Skip to content

Commit 568513c

Browse files
authored
fix: allow inlining fully dynamic import (#9137)
1 parent fec5579 commit 568513c

File tree

9 files changed

+70
-11
lines changed

9 files changed

+70
-11
lines changed

packages/vitest/src/node/environments/fetchModule.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { isExternalUrl, unwrapId } from '@vitest/utils/helpers'
1212
import { join } from 'pathe'
1313
import { fetchModule } from 'vite'
1414
import { hash } from '../hash'
15+
import { normalizeResolvedIdToUrl } from './normalizeUrl'
1516

1617
const saveCachePromises = new Map<string, Promise<FetchResult>>()
1718
const readFilePromises = new Map<string, Promise<string | null>>()
@@ -54,6 +55,14 @@ class ModuleFetcher {
5455
return { externalize: url, type: 'network' }
5556
}
5657

58+
// handle unresolved id of dynamic import skipped by Vite import analysis
59+
if (url[0] !== '/') {
60+
const resolved = await environment.pluginContainer.resolveId(url, importer)
61+
if (resolved) {
62+
url = normalizeResolvedIdToUrl(environment, resolved.id)
63+
}
64+
}
65+
5766
const moduleGraphModule = await environment.moduleGraph.ensureEntryFromUrl(unwrapId(url))
5867
const cached = !!moduleGraphModule.transformResult
5968

packages/vitest/src/runtime/moduleRunner/moduleEvaluator.ts

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -322,21 +322,11 @@ export class VitestModuleEvaluator implements ModuleEvaluator {
322322
? vm.runInContext(wrappedCode, this.vm.context, options)
323323
: vm.runInThisContext(wrappedCode, options)
324324

325-
const dynamicRequest = async (dep: string, options: ImportCallOptions) => {
326-
dep = String(dep)
327-
// TODO: support more edge cases?
328-
// vite doesn't support dynamic modules by design, but we have to
329-
if (dep[0] === '#') {
330-
return context[ssrDynamicImportKey](wrapId(dep), options)
331-
}
332-
return context[ssrDynamicImportKey](dep, options)
333-
}
334-
335325
await initModule(
336326
context[ssrModuleExportsKey],
337327
context[ssrImportMetaKey],
338328
context[ssrImportKey],
339-
dynamicRequest,
329+
context[ssrDynamicImportKey],
340330
context[ssrExportAllKey],
341331
// vite 7 support, remove when vite 7+ is supported
342332
(context as any).__vite_ssr_exportName__

pnpm-lock.yaml

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from 'virtual:test'
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"name": "@vitejs/test-dep-virtual",
3+
"type": "module",
4+
"private": true,
5+
"exports": "./index.js"
6+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { expect, it } from "vitest";
2+
3+
it("basic", async () => {
4+
const getId = () => "@vitejs/test-dep-virtual";
5+
const mod = await import(getId());
6+
expect(mod.test).toBe("ok");
7+
});
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { defineConfig } from "vitest/config";
2+
3+
export default defineConfig({
4+
ssr: {
5+
noExternal: ["@vitejs/test-dep-virtual"],
6+
},
7+
plugins: [
8+
{
9+
name: 'test-virtual',
10+
resolveId(source) {
11+
if (source === 'virtual:test') {
12+
return '\0' + source;
13+
}
14+
},
15+
load(id) {
16+
if (id === '\0virtual:test') {
17+
return `export const test = "ok";`;
18+
}
19+
}
20+
}
21+
],
22+
});

test/config/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
},
88
"devDependencies": {
99
"@test/test-dep-config": "link:./deps/test-dep-config",
10+
"@vitejs/test-dep-virtual": "file:./deps/test-dep-virtual",
1011
"@vitest/browser-playwright": "workspace:*",
1112
"@vitest/browser-preview": "workspace:*",
1213
"@vitest/browser-webdriverio": "workspace:*",

test/config/test/external.test.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { expect, it } from 'vitest'
2+
import { runVitest } from '../../test-utils'
3+
4+
it('can inline fully dynamic import', async () => {
5+
const { errorTree } = await runVitest({
6+
root: 'fixtures/external/dynamic',
7+
})
8+
expect(errorTree()).toMatchInlineSnapshot(`
9+
{
10+
"basic.test.ts": {
11+
"basic": "passed",
12+
},
13+
}
14+
`)
15+
})

0 commit comments

Comments
 (0)