vitest icon indicating copy to clipboard operation
vitest copied to clipboard

File not found after update Vitest but work on old versions

Open paulocoutinhox opened this issue 5 months ago • 6 comments

Describe the bug

Hi,

I have a test where i need load a .wasm file and it is outside my web project.

It was built in /Users/paulo/Developer/workspaces/cpp/xplpc/build/wasm/wasm32/bin/xplpc.wasm and the web project to test is /Users/paulo/Developer/workspaces/cpp/xplpc/wasm/sample.

The project is here: https://github.com/xplpc/xplpc

My test is:

[...]

import Module from "@xplpc/build/wasm/wasm32/bin/xplpc";

describe("Client", () => {
    beforeAll(async () => {
        // initialize module
        const module: IXWasmModule = await Module();
        XPLPC.shared().initialize(module, new XConfig(new JsonSerializer()));
    });

[...]

On vitest 0.29.3 my test works well because @xplpc is a mapping to project root (tsconfig.json and vite.config.ts) /Users/paulo/Developer/workspaces/cpp/xplpc and the xplpc.wasm file and xplpc.js is found.

But after update to vitest version 3.2.4 i start receive error:

=============
stderr | tests/unit/client.spec.ts > Client
failed to asynchronously prepare wasm: Error: ENOENT: no such file or directory, open 'http://localhost:3000/@fs/Users/paulo/Developer/workspaces/cpp/xplpc/build/wasm/wasm32/bin/xplpc.wasm'
Aborted(Error: ENOENT: no such file or directory, open 'http://localhost:3000/@fs/Users/paulo/Developer/workspaces/cpp/xplpc/build/wasm/wasm32/bin/xplpc.wasm')

 ❯ tests/unit/client.spec.ts (12 tests | 12 skipped) 12ms
   ↓ Client > check if is initialized
   ↓ Client > battery level
   ↓ Client > battery level from string
   ↓ Client > battery level from string with await
   ↓ Client > get logged value
   ↓ Client > get logged value with await
   ↓ Client > get reverse value
   ↓ Client > get reverse value with await
   ↓ Client > transfer data view
   ↓ Client > transfer data view with await
   ↓ Client > receive data view
   ↓ Client > receive data view with await
 ✓ tests/unit/pages.spec.ts (1 test) 11ms

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Failed Suites 1 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯

 FAIL  tests/unit/client.spec.ts > Client
RuntimeError: Aborted(Error: ENOENT: no such file or directory, open 'http://localhost:3000/@fs/Users/paulo/Developer/workspaces/cpp/xplpc/build/wasm/wasm32/bin/xplpc.wasm')
 ❯ abort ../../build/wasm/wasm32/bin/xplpc.js:8:10177

 ❯ instantiateArrayBuffer ../../build/wasm/wasm32/bin/xplpc.js:8:12222
 ❯ createWasm ../../build/wasm/wasm32/bin/xplpc.js:8:13811
 ❯ ../../build/wasm/wasm32/bin/xplpc.js:8:81025
 ❯ tests/unit/client.spec.ts:32:38
⎯⎯⎯⎯⎯⎯⎯⎯⎯ Unhandled Errors ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
Vitest caught 1 unhandled error during the test run.
This might cause false positive tests. Resolve unhandled errors to make sure your tests are not affected.

⎯⎯⎯⎯⎯⎯⎯⎯ Unhandled Rejection ⎯⎯⎯⎯⎯⎯⎯⎯
RuntimeError: Aborted(Error: ENOENT: no such file or directory, open 'http://localhost:3000/@fs/Users/paulo/Developer/workspaces/cpp/xplpc/build/wasm/wasm32/bin/xplpc.wasm')
 ❯ abort ../../build/wasm/wasm32/bin/xplpc.js:8:10177

 ❯ instantiateArrayBuffer ../../build/wasm/wasm32/bin/xplpc.js:8:12222
 ❯ processTicksAndRejections node:internal/process/task_queues:105:5
 ❯ createWasm ../../build/wasm/wasm32/bin/xplpc.js:8:13811
 ❯ ../../build/wasm/wasm32/bin/xplpc.js:8:81025
 ❯ tests/unit/client.spec.ts:32:38

This error originated in "tests/unit/client.spec.ts" test file. It doesn't mean the error was thrown inside the file itself, but while it was running.

It try load the file from http://localhost:3000/@fs.

Full error log: https://github.com/xplpc/xplpc/actions/runs/15764432959/job/44437922762#step:12:93

Reproduction

Steps:

git clone https://github.com/xplpc/xplpc.git
cd xplpc
git checkout jun-updates
./emsdk activate 
python3 xplpc.py wasm-build
python3 xplpc.py wasm-test

If don't want build the wasm file, get the latest build below and put on build/wasm/wasm32/bin:

wasm-files.zip

System Info

System:
    OS: macOS 15.3.1
    CPU: (10) arm64 Apple M1 Pro
    Memory: 88.97 MB / 16.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 23.9.0 - /opt/homebrew/bin/node
    npm: 10.9.2 - /opt/homebrew/bin/npm
    bun: 1.2.8 - ~/Library/Application Support/reflex/bun/bin/bun
  Browsers:
    Chrome: 137.0.7151.120
    Safari: 18.3
  npmPackages:
    @vitejs/plugin-vue: ^5.2.3 => 5.2.3 
    vite: ^6.3.5 => 6.3.5 
    vitest: ^3.2.4 => 3.2.4

Used Package Manager

npm

Validations

paulocoutinhox avatar Jun 19 '25 18:06 paulocoutinhox

It's likely new URL("some.wasm") inside emscripten output js is broken on jsdom. Not sure if this is still relevant, but from the old issue https://github.com/vitest-dev/vitest/issues/5704#issuecomment-2321473768, someone suggested using USE_ES6_IMPORT_META flag. Can you try that as emscripten build? perhaps https://github.com/xplpc/xplpc/blob/ff42456d46af3d286aee23522f47087e0539df87/CMakeLists.txt#L179

Also, I'd expect you don't need vite-plugin-wasm to test emscripten build on Vitest (or even Vite). You may also try disabling it by plugins: [!process.env.VITEST && wasm()].

Also, you may try browser mode instead of jsdom so that wasm loading and everything happens on browser https://vitest.dev/guide/browser/


Ah, I wasn't aware but it looks like this happens on jsdom https://stackblitz.com/edit/vitest-dev-vitest-fcfvzd2r?file=test%2Fbasic.test.ts

import { test } from 'vitest';

test('repro', () => {
  console.log(import.meta.url);
  // => file:///home/projects/vitest-dev-vitest-fcfvzd2r/test/basic.test.ts

  console.log(new URL('./foo', import.meta.url).href);
  // => http://localhost:3000/test/foo

  console.log(new URL('/bar', import.meta.url).href);
  // => http://localhost:3000/@fs/bar
});

hi-ogawa avatar Jun 19 '25 23:06 hi-ogawa

Hi,

I removed wasm() plugin, but the problem is the same.

This problem started recently. It is working with old versions: https://github.com/xplpc/xplpc/actions/runs/15741492299/job/44367683882#step:12:59

The web application that use wasm library is working. The problem is only with wasm.

paulocoutinhox avatar Jun 20 '25 00:06 paulocoutinhox

The issue seems same as https://github.com/vitest-dev/vitest/issues/5704#issuecomment-2124303312 You may try the workaround in the comment.

@sheremet-va Assuming self.location rewrite is an intended behavior, do you know where we have tests for this? (namely which tests were regressed and then fixed by https://github.com/vitest-dev/vitest/pull/4258?)

hi-ogawa avatar Jun 20 '25 01:06 hi-ogawa

Hi,

I tried it inside vite.config.ts:

/// <reference types="vitest" />
import { defineConfig } from 'vite'

import vue from '@vitejs/plugin-vue'
import { resolve } from 'path'
import { fileURLToPath, URL } from "url"
import EnvironmentPlugin from "vite-plugin-environment"
import eslintPLugin from "vite-plugin-eslint"
import topLevelAwait from "vite-plugin-top-level-await"
import wasm from "vite-plugin-wasm"

const BASE_URL = (process.env.BASE_URL ? process.env.BASE_URL.replace(/\/$|$/, '/') : '/');

// https://vite.dev/config/
export default defineConfig({
    base: BASE_URL,
    build: {
        target: ['esnext']
    },
    resolve: {
        alias: {
            "@": fileURLToPath(new URL("./src", import.meta.url)),
            '@xplpc': resolve(__dirname, '../../'),
            '@bootstrap': resolve(__dirname, 'node_modules/bootstrap'),
        },
    },
    plugins: [
        vue(),
        eslintPLugin({
            exclude: ["../../build/**", "**/node_modules/**"]
        }),
        EnvironmentPlugin(
            {
                CURRENT_DATE_TIME:
                    new Date().toJSON().slice(0, 19).replace("T", " ") + " UTC",
            },
            {
                defineOn: "import.meta.env",
            }
        ),
        [!process.env.VITEST && wasm()],
        {
            name: "keep-import-meta-url",
            enforce: "pre",
            transform(code, id, _options) {
                // prevent NormalizeURLPlugin from replacing import.meta.url with self.location
                // https://github.com/vitest-dev/vitest/blob/d8304bb4fbe16285d014f63aa71ef9969865c691/packages/vitest/src/node/plugins/normalizeURL.ts#L11
                // since it breaks `new URL(..., import.meta.url)` used by emscripten EXPORT_ES6 output
                // https://github.com/emscripten-core/emscripten/blob/228af1a7de1672b582e1448d4573c20c5d2a5b5a/src/shell.js#L242
                if (id.endsWith("xplpc.js")) {
                    //console.log("------------------" + id);
                    return code.replace(/\bimport\.meta\.url\b/g, `String(import.meta.url)`);
                }
            },
        },
        topLevelAwait()
    ],
    server: {
        host: true,
        port: 3000,
        fs: {
            strict: false,
            allow: [".."],
        },
    },
    test: {
        globals: true,
        environment: 'jsdom',
        setupFiles: './src/setupTests.ts',
        coverage: {
            reporter: ['text', 'html'],
            exclude: [
                'node_modules/',
                'src/setupTests.ts',
            ],
        },
    }
})

And it solve my problem for now.

But there is any official solution?

Also, i need wasm() plugin or it is supported officially and i can remove it?

Thanks.

paulocoutinhox avatar Jun 20 '25 04:06 paulocoutinhox

We cannot answer about the need of vite-plugin-wasm. It's a community plugin, so you can check with the author there.

Regarding whether this change is an expected behavior or not, we'll discuss it later.

hi-ogawa avatar Jun 20 '25 04:06 hi-ogawa

My question about vite-plugin-wasm is only to understand if WASM files are supported natively or not.

paulocoutinhox avatar Jun 20 '25 05:06 paulocoutinhox

After make more tests, i see that your workaround fix for tests but break the app copy the .wasm to assets when run build.

paulocoutinhox avatar Jun 21 '25 19:06 paulocoutinhox

After make more tests, i see that your workaround fix for tests but break the app copy the .wasm to assets when run build.

Sorry, forgot to mention that. You would need to use !!process.env.VITEST && { name: "keep-import-meta-url", ... } to enable only on Vitest / Jsdom.

hi-ogawa avatar Jun 21 '25 23:06 hi-ogawa