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

ESM config doesn't work on Windows #1487

Closed
jods4 opened this issue Jan 11, 2021 · 3 comments
Closed

ESM config doesn't work on Windows #1487

jods4 opened this issue Jan 11, 2021 · 3 comments

Comments

@jods4
Copy link
Contributor

jods4 commented Jan 11, 2021

Describe the bug

Try to write an ESM config with vite.config.mjs or simply vite.config.js in a package with type: "module".
Vite tries to import it but fails with

failed to load config from C:\****\vite.config.mjs
error when starting dev server:
Error [ERR_UNSUPPORTED_ESM_URL_SCHEME]: Only file and data URLs are supported by the default ESM loader. On Windows, absolute paths must be valid file:// URLs. Received protocol 'c:'
    at new NodeError (node:internal/errors:278:15)
    at Loader.defaultResolve [as _resolve] (node:internal/modules/esm/resolve:825:11)
    at Loader.resolve (node:internal/modules/esm/loader:86:40)
    at Loader.getModuleJob (node:internal/modules/esm/loader:230:28)
    at Loader.import (node:internal/modules/esm/loader:165:28)
    at importModuleDynamically (node:internal/modules/cjs/loader:1051:27)
    at exports.importModuleDynamicallyCallback (node:internal/process/esm_loader:30:14)
    at eval (eval at loadConfigFromFile (C:\****\node_modules\vite\dist\node\chunks\dep-661a710c.js:46795:33), <anonymous>:1:21)
    at loadConfigFromFile (C:\****\node_modules\vite\dist\node\chunks\dep-661a710c.js:46795:33)      
    at resolveConfig (C:\****\node_modules\vite\dist\node\chunks\dep-661a710c.js:46584:34)

The root cause is here:

userConfig = (await eval(`import(resolvedPath + '?t=${Date.now()}')`))

You can't import("C:\..."), you need to add the file:/// protocol.
Node suggests that you use pathToFileUrl for that as escaping can sometimes be tricky.

Suggested fix:

({ default: userConfig } = await import(`${url.pathToFileURL(resolvedPath)}?t=${Date.now()}`)

✔️ Works on my machine.

Notice that I removed the eval. I am no Rollup expert but I believe rollup can't handle dynamic imports that aren't constant. There's a plugin that handles interpolation but it also gives up if the interpolation doesn't begin with . or .. and ends up with a file extension. So I don't think the ugly eval is required here, I might be wrong.

Bonus suggested improvement: that code doesn't look for a possible .cjs config, which would be commonjs inside a esm-by-default package.

I don't have time for that additional bug: when using Typescript vite.config.ts the result seems to always be interpreted as a CJS module, even inside a package that is ESM by default. This blew up on me when one of my modules had a top-level await, which is only allowed in ESM mode in Node 14.3+. Just FYI, I don't have time to go into this bug.

System Info

  • vite version: 2.0.0-beta.21
  • Operating System: win 10
  • Node version: 15
  • Package manager (npm/yarn/pnpm) and version: npm 7
@yyx990803
Copy link
Member

The eval is still necessary during development because TS will compile all import into sync requires when targeting commonjs.

@jods4
Copy link
Contributor Author

jods4 commented Jan 11, 2021

You went for a totally different file path encoding, which is all fine by me, but it leaves me wondering how it works if you reference stuff on a different drive altogether.

The /path/to/config.js syntax is relative to the root of the current drive, and your code blindly strips any drive in the absolute path.
That might be a super rare use-case, but wouldn't that fail if I use an absolute path to another drive in my inline config?

EDIT: I'm not doing that and I don't really care if it doesn't work, just noticing.

@yyx990803
Copy link
Member

Vite's resolve plugin and most official Rollup plugins normalize windows paths this way, so the whole thing likely won't work with any cross drive imports anyway.

@github-actions github-actions bot locked and limited conversation to collaborators Jul 16, 2021
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