Dynamic import fails in route with brackets or parenthesis
Describe the bug
This bug was initially reported to Sveltekit (https://github.com/sveltejs/kit/issues/8516), but it likely is a bug with Vite, related to https://github.com/vitejs/vite/issues/9833, but affecting direct imports rather than glob imports.
Dynamically importing a module in a route with [parameters] or (group), for example:
// src/routes/[foo]/+page.js
export async load = ({ params }) => (await import(`./index.${params.foo}.js`).data;
// src/routes/(foo)/bar/+page.js
export async load = ({ url }) => (await import(`./index.${url.params.get('foo'}.js`).data;
Fails with the following error:
Error: Unknown variable dynamic import: ../[foo]/index.foo.js
at vite/dynamic-import-helper:7:96
at new Promise (<anonymous>)
at __vite_ssr_exports__.default (vite/dynamic-import-helper:6:12)
at load (/src/routes/[foo]/+page.js:2:59)
at Module.load_data (/node_modules/@sveltejs/kit/src/runtime/server/page/load_data.js:110:43)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async eval (/node_modules/@sveltejs/kit/src/runtime/server/page/index.js:195:13)
Reproduction
https://stackblitz.com/edit/sveltejs-kit-template-default-peg2jd?file=src/routes/[foo]/+page.js
Steps to reproduce
Navigate to the header links /(foo)/baz or /[foo] from the reproduction stackblitz.
System Info
System:
OS: Windows 10 10.0.19045
CPU: (20) x64 12th Gen Intel(R) Core(TM) i7-12700H
Memory: 13.96 GB / 31.68 GB
Binaries:
Node: 16.17.0 - C:\Program Files\nodejs\node.EXE
npm: 8.15.0 - C:\Program Files\nodejs\npm.CMD
Browsers:
Edge: Spartan (44.19041.1266.0), Chromium (109.0.1518.61)
Internet Explorer: 11.0.19041.1566
npmPackages:
vite: ^4.0.0 => 4.0.4
Used Package Manager
npm
Logs
No response
Validations
- [X] Follow our Code of Conduct
- [X] Read the Contributing Guidelines.
- [X] Read the docs.
- [X] Check that there isn't already an issue that reports the same bug to avoid creating a duplicate.
- [X] Make sure this is a Vite issue and not a framework-specific issue. For example, if it's a Vue SFC related bug, it should likely be reported to vuejs/core instead.
- [X] Check that this is a concrete bug. For Q&A open a GitHub Discussion or join our Discord Chat Server.
- [X] The provided reproduction is a minimal reproducible example of the bug.
Here's a simpler repro, that doesn't involve SvelteKit:
https://github.com/Rich-Harris/vite-dynamic-import-repro
Added a repro for https://github.com/sveltejs/kit/issues/8490 for good measure — these are treated differently (note the ' vs `):
console.log(Object.keys(import.meta.glob(`./\\(parens\\)/data-*.js`)).length);
console.log(Object.keys(import.meta.glob('./\\(parens\\)/data-*.js')).length);
As a temporary solution for SvelteKit users facing this issue, rather than (which currently breaks):
export async load = ({ params }) => {
const module = await import(`./index.${params.foo}.js`);
return module.data;
}
do instead:
export async load = ({ params }) => {
const modules = import.meta.glob('./index.*.js');
const module = await modules[`./index.${params.foo}.js`]();
return module.data;
}
The expected vite code should be the same for those two snippets.
As found in https://github.com/vitejs/vite/pull/11839#issuecomment-1411656243, this would need to be fixed upstream in @rollup/plugin-dynamic-import-vars
I made a PR that fixes the upstream issue: https://github.com/rollup/plugins/pull/1636 But even with that, it seems there's a bug in Vite side too.
IIUC this newRawPattern should not use toAbsoluteGlob, otherwise ( will be escaped.
https://github.com/vitejs/vite/blob/0654d1b52448db4d7a9b69aee6aad9e015481452/packages/vite/src/node/plugins/dynamicImportVars.ts#L131-L134