Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't alias module in browser mode when dependency is aliased #6646

Closed
6 tasks done
JCQuintas opened this issue Oct 5, 2024 · 10 comments
Closed
6 tasks done

Can't alias module in browser mode when dependency is aliased #6646

JCQuintas opened this issue Oct 5, 2024 · 10 comments

Comments

@JCQuintas
Copy link

JCQuintas commented Oct 5, 2024

Describe the bug

Same as #6483 which resolved this issue for mock

But for vitest.config.ts resolve.alias

We currently have the following in our package

    "date-fns": "2.30.0",
    "date-fns-v3": "npm:[email protected]",

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.

// 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

Reproduction

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

Important Files

Ensure you uncomment the alias in vitest.config.ts

Running

pnpm test

System Info

  System:
    OS: macOS 15.0.1
    CPU: (11) arm64 Apple M3 Pro
    Memory: 96.31 MB / 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.11.0 - ~/.nvm/versions/node/v20.12.2/bin/pnpm
  Browsers:
    Brave Browser: 127.1.68.137
    Chrome: 129.0.6668.90
    Safari: 18.0.1
  npmPackages:
    @vitejs/plugin-react: ^4.3.1 => 4.3.2 
    @vitest/browser: latest => 2.1.2 
    @vitest/ui: latest => 2.1.2 
    vite: latest => 5.4.8 
    vitest: latest => 2.1.2

Used Package Manager

pnpm

Validations

@sheremet-va
Copy link
Member

sheremet-va commented Oct 7, 2024

I don't understand what you are trying to achieve, to be honest. Do you want to always resolve to date-fn locally? Even in DateFnsV3? Or do you want date-fns/parse to be resolved to date-fns-v3 instead of date-fns-v3/parse?

@sheremet-va
Copy link
Member

I would recommend creating an index.html file and running your code with Vite - you get the same issue there, which makes it easier to debug since this is not an issue with Vitest:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script type="module" src="./components/DateFnsV3.tsx"></script>
  <script type="module" src="./components/DateFns.tsx"></script>
</body>
</html>
{
  "scripts": {
    "dev": "vite dev"
  }
}

@JCQuintas
Copy link
Author

JCQuintas commented Oct 7, 2024

I want files that contain DateFnsV3 in its name to have date-fns library replaced by date-fns-v3. This aliasing works correctly in JSDOM.

I see this as the similar issue from my original topic. There one of the issues was fixed, which is was using vi.mock

@sheremet-va
Copy link
Member

sheremet-va commented Oct 7, 2024

This aliasing works correctly in JSDOM.

This is debatable, Vitest in Node.js doesn't actually follow the same resolving mechanism and tries to resolve the same thing twice if it doesn't work. The error happening in the browser is the correct behaviour. As I said, try using this config with a normal Vite project and you will see the same error.

@sheremet-va
Copy link
Member

sheremet-va commented Oct 7, 2024

I want files that contain DateFnsV3 in its name to have date-fns library replaced by date-fns-v3.

This also doesn't explain what I asked. Do you want date-fns/parse to be resolved as date-fns-v3/parse or date-fns-v3? date-fns-v3/parse doesn't have a parse export

@JCQuintas
Copy link
Author

This also doesn't explain what I asked. Do you want date-fns/parse to be resolved as date-fns-v3/parse or date-fns-v3?

I want date-fns/parse to become date-fns-v3/parse, but not only that. date-fns is modular, it has date-fns/format, date-fns/addHours, etc. All those instances should be changed as well.

@JCQuintas
Copy link
Author

This is debatable, Vitest in Node.js doesn't actually follow the same resolving mechanism and tries to resolve the same thing twice if it doesn't work. The error happening in the browser is the correct behaviour. As I said, try using this config with a normal Vite project and you will see the same error.

It is not debatable that it works. 🙃

And I understand that running it in the browser gives me errors.

If I rename vitest.config to vite.config the errors become:

5:48:02 PM [vite] Pre-transform error: Failed to load url date-fns-v3/addHours (resolved id: date-fns-v3/addHours) in /Users/jcquintas/dev/vitest-browser-alias-mock/components/DateFnsV3.tsx. Does the file exist?
5:48:02 PM [vite] Pre-transform error: Failed to load url date-fns-v3/parse (resolved id: date-fns-v3/parse) in /Users/jcquintas/dev/vitest-browser-alias-mock/components/DateFnsV3.tsx. Does the file exist?

which means the config is working, but the files are not present 🤔

@sheremet-va
Copy link
Member

It is not debatable that it works. 🙃

It is debatable whether it works correctly.

which means the config is working, but the files are not present 🤔

It means you misconfigured the customResolver API. Usually returning unresolved ids in the alias plugin doesn't work in Vite, you need to resolve it to the correct file. I personally don't know how to work with that API, I would recommend asking in Vite discord server.

In conclusion, the config works correctly. The error is expected, the fact that it works in Node.js fake jsdom environment is a bug in Vitest, it should print the same error.

@JCQuintas
Copy link
Author

It is debatable whether it works correctly.

🤣 true

Usually returning unresolved ids in the alias plugin doesn't work in Vite, you need to resolve it to the correct file.

This input helped. I managed to get this to work with the monstrosity below. It is not pretty though. But it works, if anyone needs something similar in the future.

      {
        find: 'date-fns',
        replacement: 'date-fns-v3',
        customResolver(source, importer) {
          if (importer?.includes('DateFnsV3')) {
            return path.resolve(__dirname, 'node_modules', `${source}.mjs`)
          }
          return path.resolve(__dirname, 'node_modules', 'date-fns', 'index.js')
        },
      }

@JCQuintas
Copy link
Author

This is a more reasonable solution

      {
        find: 'date-fns',
        replacement: 'date-fns-v3',
       async customResolver(source, importer, options) {
          if (importer?.includes('DateFnsV3')) {
            return import.meta.resolve(source).replace('file:', '')
          }
          return import.meta.resolve('date-fns').replace('file:', '')
        },
      }

@sheremet-va sheremet-va closed this as not planned Won't fix, can't repro, duplicate, stale Oct 8, 2024
@github-actions github-actions bot locked and limited conversation to collaborators Oct 23, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

2 participants