vitest-dev / vitest

Next generation testing framework powered by Vite.
https://vitest.dev
MIT License
12.68k stars 1.13k forks source link

Can't `mock` or `alias` module in browser mode when dependency is aliased (`npm:my-dependency@2.0.0`) #6483

Open JCQuintas opened 1 week ago

JCQuintas commented 1 week ago

Describe the bug

Hello, we are trying to understand what would take to migrate into vitest on our repositories at MUI, both for browser and jsdom testing.

And we encountered an issue in regard to aliased dependencies.

We currently have the following in our package

    "date-fns": "2.30.0",
    "date-fns-v3": "npm:date-fns@3.6.0",

This is due to the different signatures between these two versions. In the final code, this is a peer dependency, so inside our code we only always use import from 'date-fns'.

But when testing, we want to test the actual library, which requires some aliasing.

I've tried with both config.alias and vi.mock and they both work on jsdom, but not on browser.

// config.ts
import { defineConfig } from 'vite'

export default defineConfig({
  resolve: {
    alias: [
      {
        find: 'date-fns',
        replacement: 'date-fns-v3',
        customResolver(source, importer, options) {
          if (importer?.includes('DateFnsV3')) return source
          return null
        },
      }
    ]
  },
  test: {
    setupFiles: ['./vitest.setup.ts'],
  },
})

/// TypeError: Failed to fetch dynamically imported module: http://localhost:5173/Users/dev/vitest-browser-alias-mock/components/DateFnsV3.test.tsx?import&browserv=1726153861578
// test file
vi.mock('date-fns/addHours', ()=>({addHours}))
vi.mock('date-fns/parse', ()=>({parse}))

/// SyntaxError: The requested module '/node_modules/.vite/deps/date-fns_parse.js?v=16a839a0' does not provide an export named 'parse'

Reproduction

https://github.com/JCQuintas/vitest-browser-alias-mock

Important Files

Ensure you uncomment one of the comments in these files to test

vitest.config.ts
components/DateFnsV3.test.tsx

Running

pnpm test

System Info

System:
    OS: macOS 14.6.1
    CPU: (11) arm64 Apple M3 Pro
    Memory: 8.68 GB / 36.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 20.12.2 - ~/.nvm/versions/node/v20.12.2/bin/node
    npm: 10.5.0 - ~/.nvm/versions/node/v20.12.2/bin/npm
    pnpm: 9.10.0 - ~/.nvm/versions/node/v20.12.2/bin/pnpm
  Browsers:
    Brave Browser: 127.1.68.137
    Chrome: 128.0.6613.137
    Safari: 17.6
  npmPackages:
    @vitejs/plugin-react: ^4.3.1 => 4.3.1 
    @vitest/browser: ^2.1.0 => 2.1.0 
    @vitest/ui: latest => 2.1.0 
    vite: latest => 5.4.4 
    vitest: latest => 2.1.0

Used Package Manager

pnpm

Validations

hi-ogawa commented 1 day ago
// test file
vi.mock('date-fns/addHours', ()=>({addHours}))
vi.mock('date-fns/parse', ()=>({parse}))

/// SyntaxError: The requested module '/node_modules/.vite/deps/date-fns_parse.js?v=16a839a0' does not provide an export named 'parse'

This mocking error looks like a bug and not really related to npm:... alias dependency. Based on your reproduction, I made something simpler just installing "date-fns": "2.30.0" and the error is same https://github.com/hi-ogawa/reproductions/tree/main/vitest-6483-browser-mock-date-fns

What looks odd to me is I see these two requests on devtools and probably the 2nd one again exporting addHours is wrong:

// http://localhost:5173/node_modules/.vite/deps/date-fns_addHours.js?t=1726706677742&v=fa62991a
const module = globalThis["__vitest_mocker__"].getFactoryModule("/node_modules/.vite/deps/date-fns_addHours.js");
export const addHours = module["addHours"];
// http://localhost:5173/node_modules/.vite/deps/date-fns_parse.js?t=1726706677742&v=fa62991a
const module = globalThis["__vitest_mocker__"].getFactoryModule("/node_modules/.vite/deps/date-fns_parse.js");
export const addHours = module["addHours"];