Closed maxpatiiuk closed 1 month ago
I'm not sure this is exactly a bug. In the resolveId
hook, the given id isn't guaranteed to be normalized (the term used by Vite for forward slash only paths), what Vite guarantees within its plugins and encourages others plugins to do so, is that resolved ids (returned from resolveId
hook) are normalized.
Non-normalized path can also happen if user writes imports like import "foo\\bar"
or import "C:\\foo\\bar"
, which they will be passed to resolveId
as is.
Your plugin should be updated in this case to handle backslashes.
Describe the bug
In most places Vite is using POSIX path separators even on Windows (i.e in
config.root
, file identifiers and etc).However, there is one place where this is inconsistent and platform path separators are used:
If
build.lib.entry
includes a virtual file, theresolveId()
hook in plugins will be called:The
resolveId()
is called with an absolute path (process.cwd() + '/virtual-file.js') that uses the platform's path separator (\
on Windows), rather than POSIX path separatorThis is inconsistent behavior and lead to a bug in my plugin on Windows.
Reproduction
https://github.com/maxpatiiuk/vite-inconsistent-resolve-id
Steps to reproduce
Use Windows machine
Clone the reproduction repository
Install dependencies
Run build
See build output show a message like
resolveId called with C:\Users\root\...
rather thanresolveId called with C:/Users/root/...
System Info
Used Package Manager
npm
Logs
Click to expand!
```shell vite:config bundled config file loaded in 173.20ms +0ms vite:config using resolved config: { vite:config build: { vite:config target: [ 'es2020', 'edge88', 'firefox78', 'chrome87', 'safari14' ], vite:config cssTarget: [ 'es2020', 'edge88', 'firefox78', 'chrome87', 'safari14' ], vite:config outDir: 'dist', vite:config assetsDir: 'assets', vite:config assetsInlineLimit: 4096, vite:config cssCodeSplit: false, vite:config sourcemap: false, vite:config rollupOptions: {}, vite:config minify: 'esbuild', vite:config terserOptions: {}, vite:config write: true, vite:config emptyOutDir: null, vite:config copyPublicDir: true, vite:config manifest: false, vite:config lib: { formats: [Array], entry: 'virtual-file.js' }, vite:config ssr: false, vite:config ssrManifest: false, vite:config ssrEmitAssets: false, vite:config reportCompressedSize: true, vite:config chunkSizeWarningLimit: 500, vite:config watch: null, vite:config commonjsOptions: { include: [Array], extensions: [Array] }, vite:config dynamicImportVarsOptions: { warnOnError: true, exclude: [Array] }, vite:config modulePreload: { polyfill: true }, vite:config cssMinify: true vite:config }, vite:config plugins: [ vite:config 'vite:build-metadata', vite:config 'vite:watch-package-data', vite:config 'vite:pre-alias', vite:config 'alias', vite:config 'vite:modulepreload-polyfill', vite:config 'vite:resolve', vite:config 'vite:html-inline-proxy', vite:config 'vite:css', vite:config 'vite:esbuild', vite:config 'vite:json', vite:config 'vite:wasm-helper', vite:config 'vite:worker', vite:config 'vite:asset', vite:config 'resolve-id', vite:config 'vite:wasm-fallback', vite:config 'vite:define', vite:config 'vite:css-post', vite:config 'vite:build-html', vite:config 'vite:worker-import-meta-url', vite:config 'vite:asset-import-meta-url', vite:config 'vite:force-systemjs-wrap-complete', vite:config 'commonjs', vite:config 'vite:data-uri', vite:config 'vite:dynamic-import-vars', vite:config 'vite:import-glob', vite:config 'vite:build-import-analysis', vite:config 'vite:esbuild-transpile', vite:config 'vite:terser', vite:config 'vite:reporter', vite:config 'vite:load-fallback' vite:config ], vite:config configFile: 'C:/Users/mak13180/Documents/arcgis-web-components/packages/test-packages/vite-inconsistent-resolve-id/vite.config.ts', vite:config configFileDependencies: [ vite:config 'C:/Users/mak13180/Documents/arcgis-web-components/packages/test-packages/vite-inconsistent-resolve-id/vite.config.ts' vite:config ], vite:config inlineConfig: { vite:config root: undefined, vite:config base: undefined, vite:config mode: undefined, vite:config configFile: undefined, vite:config logLevel: undefined, vite:config clearScreen: undefined, vite:config build: {} vite:config }, vite:config root: 'C:/Users/mak13180/Documents/arcgis-web-components/packages/test-packages/vite-inconsistent-resolve-id', vite:config base: '/', vite:config rawBase: '/', vite:config resolve: { vite:config mainFields: [ 'browser', 'module', 'jsnext:main', 'jsnext' ], vite:config conditions: [], vite:config extensions: [ vite:config '.mjs', '.js', vite:config '.mts', '.ts', vite:config '.jsx', '.tsx', vite:config '.json' vite:config ], vite:config dedupe: [], vite:config preserveSymlinks: false, vite:config alias: [ [Object], [Object] ] vite:config }, vite:config publicDir: 'C:/Users/mak13180/Documents/arcgis-web-components/packages/test-packages/vite-inconsistent-resolve-id/public', vite:config cacheDir: 'C:/Users/mak13180/Documents/arcgis-web-components/packages/test-packages/vite-inconsistent-resolve-id/node_modules/.vite', vite:config command: 'build', vite:config mode: 'production', vite:config ssr: { vite:config target: 'node', vite:config optimizeDeps: { noDiscovery: true, esbuildOptions: [Object] } vite:config }, vite:config isWorker: false, vite:config mainConfig: null, vite:config bundleChain: [], vite:config isProduction: true, vite:config css: { lightningcss: undefined }, vite:config esbuild: { jsxDev: false }, vite:config server: { vite:config preTransformRequests: true, vite:config sourcemapIgnoreList: [Function: isInNodeModules$1], vite:config middlewareMode: false, vite:config fs: { vite:config strict: true, vite:config allow: [Array], vite:config deny: [Array], vite:config cachedChecks: undefined vite:config } vite:config }, vite:config preview: { vite:config port: undefined, vite:config strictPort: undefined, vite:config host: undefined, vite:config https: undefined, vite:config open: undefined, vite:config proxy: undefined, vite:config cors: undefined, vite:config headers: undefined vite:config }, vite:config envDir: 'C:/Users/mak13180/Documents/arcgis-web-components/packages/test-packages/vite-inconsistent-resolve-id', vite:config env: { BASE_URL: '/', MODE: 'production', DEV: false, PROD: true }, vite:config assetsInclude: [Function: assetsInclude], vite:config logger: { vite:config hasWarned: false, vite:config info: [Function: info], vite:config warn: [Function: warn], vite:config warnOnce: [Function: warnOnce], vite:config error: [Function: error], vite:config clearScreen: [Function: clearScreen], vite:config hasErrorLogged: [Function: hasErrorLogged] vite:config }, vite:config packageCache: Map(1) { vite:config 'fnpd_C:/Users/mak13180/Documents/arcgis-web-components/packages/test-packages/vite-inconsistent-resolve-id' => { vite:config dir: 'C:/Users/mak13180/Documents/arcgis-web-components/packages/test-packages/vite-inconsistent-resolve-id', vite:config data: [Object], vite:config hasSideEffects: [Function: hasSideEffects], vite:config webResolvedImports: {}, vite:config nodeResolvedImports: {}, vite:config setResolvedCache: [Function: setResolvedCache], vite:config getResolvedCache: [Function: getResolvedCache] vite:config }, vite:config set: [Function (anonymous)] vite:config }, vite:config createResolver: [Function: createResolver], vite:config optimizeDeps: { vite:config holdUntilCrawlEnd: true, vite:config esbuildOptions: { preserveSymlinks: false } vite:config }, vite:config worker: { format: 'iife', plugins: '() => plugins', rollupOptions: {} }, vite:config appType: 'spa', vite:config experimental: { importGlobRestoreExtension: false, hmrPartialAccept: false }, vite:config getSortedPlugins: [Function: getSortedPlugins], vite:config getSortedPluginHooks: [Function: getSortedPluginHooks] vite:config } +57ms vite v5.3.1 building for production... resolveId called with: C:\Users\mak13180\Documents\arcgis-web-components\packages\test-packages\vite-inconsistent-resolve-id\virtual-file.js ✓ 1 modules transformed. dist/vite-project.js 0.03 kB │ gzip: 0.05 kB ✓ built in 285ms ```Validations