Open castholm opened 2 years ago
Locally, I have used patch-package to apply a patch that would be the equivalent of making the following changes to assetImportMetaUrl.ts:
@@ -44,7 +44,14 @@ export function assetImportMetaUrlPlugin(config: ResolvedConfig): Plugin {
// potential dynamic template string
if (rawUrl[0] === '`' && /\$\{/.test(rawUrl)) {
- const ast = this.parse(rawUrl)
+ let fixedUrl
+ if (!/^`(\.?\.?\/|\${)/.test(rawUrl)) {
+ // Normalize relative URLs to begin with './' to prevent issues later down the plugin pipeline.
+ fixedUrl = '`./' + rawUrl.slice(1)
+ } else {
+ fixedUrl = rawUrl
+ }
+ const ast = this.parse(fixedUrl)
const templateLiteral = (ast as any).body[0].expression
if (templateLiteral.expressions.length) {
const pattern = JSON.stringify(buildGlobPattern(templateLiteral))
@@ -55,7 +62,7 @@ export function assetImportMetaUrlPlugin(config: ResolvedConfig): Plugin {
s.overwrite(
index,
index + exp.length,
- `new URL((import.meta.glob(${pattern}, { eager: true, import: 'default', as: 'url' }))[${rawUrl}], self.location)`,
+ `new URL((import.meta.glob(${pattern}, { eager: true, import: 'default', as: 'url' }))[${fixedUrl}], self.location)`,
{ contentOnly: true }
)
continue
If you believe this would be okay as a fix, let me know and I'll open a PR.
It seems resolve by #7837, the PR will call the resolve plugin
to resolve url. So the url can resolve as bare package imports or absolute fs paths.
Does #7837 handle template strings? I will have to build and test it myself later to confirm, but it doesn't seem like that PR changes how template strings are handled.
Describe the bug
When running
vite dev
and visiting the site, all of the following methods of resolving assets work:However, when running
vite build
, the third case (new URL(`pets/${species}.txt`, import.meta.url)
) causes the build to fail with the messageIt seems a bit inconsistent that static relative URLs without a leading
./
work but not dynamic ones. Ideally, all four should work.I understand that the JavaScript spec require relative module imports to begin with a leading
./
, but this is just a URL to a generic asset.path/to/asset
and./path/to/asset
should be equivalent.Reproduction
https://stackblitz.com/edit/vitejs-vite-9ymymw
System Info
Used Package Manager
npm
Logs
Click to expand!
```shell ❯ npm run build -- --debug $ tsc && vite build --debug vite:config no config file found. +0ms vite:esbuild init tsconfck (root: /home/projects/vitejs-vite-9ymymw) +0ms vite:esbuild init tsconfck (root: /home/projects/vitejs-vite-9ymymw) +1ms vite:esbuild init tsconfck (root: /home/projects/vitejs-vite-9ymymw) +0ms vite:esbuild init tsconfck (root: /home/projects/vitejs-vite-9ymymw) +0ms vite:esbuild init tsconfck end +1ms vite:esbuild init tsconfck end +0ms vite:esbuild init tsconfck end +0ms vite:esbuild init tsconfck end +0ms vite:config using resolved config: { vite:config root: '/home/projects/vitejs-vite-9ymymw', vite:config base: '/', vite:config mode: 'production', vite:config configFile: undefined, vite:config logLevel: undefined, vite:config clearScreen: undefined, vite:config optimizeDeps: { vite:config disabled: 'build', vite:config force: undefined, vite:config esbuildOptions: { preserveSymlinks: undefined } vite:config }, vite:config build: { vite:config target: [ 'es2020', 'edge88', 'firefox78', 'chrome87', 'safari13' ], vite:config polyfillModulePreload: true, vite:config outDir: 'dist', vite:config assetsDir: 'assets', vite:config assetsInlineLimit: 4096, vite:config cssCodeSplit: true, vite:config cssTarget: [ 'es2020', 'edge88', 'firefox78', 'chrome87', 'safari13' ], vite:config sourcemap: false, vite:config rollupOptions: {}, vite:config minify: 'esbuild', vite:config terserOptions: {}, vite:config write: true, vite:config emptyOutDir: null, vite:config manifest: false, vite:config lib: false, vite:config ssr: false, vite:config ssrManifest: 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 }, vite:config configFileDependencies: [], 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 optimizeDeps: { force: undefined }, vite:config build: {} vite:config }, vite:config resolve: { alias: [ [Object], [Object] ] }, vite:config publicDir: '/home/projects/vitejs-vite-9ymymw/public', vite:config cacheDir: '/home/projects/vitejs-vite-9ymymw/node_modules/.vite', vite:config command: 'build', vite:config ssr: { vite:config format: 'esm', vite:config target: 'node', vite:config optimizeDeps: { disabled: true, esbuildOptions: [Object] } vite:config }, vite:config isWorker: false, vite:config mainConfig: null, vite:config isProduction: true, vite:config plugins: [ vite:config 'vite:build-metadata', 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 '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:force-systemjs-wrap-complete', vite:config 'vite:watch-package-data', vite:config 'commonjs', vite:config 'vite:data-uri', vite:config 'vite:asset-import-meta-url', 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 server: { vite:config preTransformRequests: true, vite:config middlewareMode: false, vite:config fs: { strict: true, allow: [Array], deny: [Array] } 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 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(0) { set: [Function (anonymous)] }, vite:config createResolver: [Function: createResolver], vite:config worker: { vite:config format: 'iife', vite:config plugins: [ vite:config 'vite:build-metadata', 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 '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:force-systemjs-wrap-complete', vite:config 'vite:watch-package-data', vite:config 'commonjs', vite:config 'vite:data-uri', vite:config 'vite:asset-import-meta-url', 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 rollupOptions: {}, vite:config getSortedPlugins: [Function: getSortedPlugins], vite:config getSortedPluginHooks: [Function: getSortedPluginHooks] vite:config }, vite:config appType: 'spa', vite:config experimental: { importGlobRestoreExtension: false, hmrPartialAccept: false }, vite:config getSortedPlugins: [Function: getSortedPlugins], vite:config getSortedPluginHooks: [Function: getSortedPluginHooks] vite:config } +6ms vite v3.1.0 building for production... ✓ 2 modules transformed. [vite:import-glob] Invalid glob: "pets/**.txt" (resolved: "pets/**.txt"). It must start with '/' or './' file: /home/projects/vitejs-vite-9ymymw/src/main.ts error during build: Error: Invalid glob: "pets/**.txt" (resolved: "pets/**.txt"). It must start with '/' or './' at toAbsoluteGlob (file:///home/projects/vitejs-vite-9ymymw/node_modules/vite/dist/node/chunks/dep-665b0112.js:36015:11) at async Promise.all (index 0) at async eval (file:///home/projects/vitejs-vite-9ymymw/node_modules/vite/dist/node/chunks/dep-665b0112.js:35848:31) at async Promise.all (index 0) at async parseImportGlob (file:///home/projects/vitejs-vite-9ymymw/node_modules/vite/dist/node/chunks/dep-665b0112.js:35862:13) at async transformGlobImport (file:///home/projects/vitejs-vite-9ymymw/node_modules/vite/dist/node/chunks/dep-665b0112.js:35874:21) at async Object.transform (file:///home/projects/vitejs-vite-9ymymw/node_modules/vite/dist/node/chunks/dep-665b0112.js:35680:28) at async transform (file:///home/projects/vitejs-vite-9ymymw/node_modules/rollup/dist/es/shared/rollup.js:21958:16) at async ModuleLoader.addModuleSource (file:///home/projects/vitejs-vite-9ymymw/node_modules/rollup/dist/es/shared/rollup.js:22183:30) ```Validations