diff --git a/packages/vite/src/node/plugins/importAnalysis.ts b/packages/vite/src/node/plugins/importAnalysis.ts index 814aa9187a9ce0..ced27abf1529a1 100644 --- a/packages/vite/src/node/plugins/importAnalysis.ts +++ b/packages/vite/src/node/plugins/importAnalysis.ts @@ -278,7 +278,6 @@ export function importAnalysisPlugin(config: ResolvedConfig): Plugin { let needQueryInjectHelper = false let s: MagicString | undefined const str = () => s || (s = new MagicString(source)) - const importedUrls = new Set() let isPartiallySelfAccepting = false const importedBindings = enablePartialAccept ? new Map>() @@ -411,6 +410,7 @@ export function importAnalysisPlugin(config: ResolvedConfig): Plugin { return [url, resolved.id] } + const orderedImportedUrls = new Array(imports.length) const orderedAcceptedUrls = new Array | undefined>( imports.length, ) @@ -640,7 +640,7 @@ export function importAnalysisPlugin(config: ResolvedConfig): Plugin { const hmrUrl = unwrapId(stripBase(url, base)) const isLocalImport = !isExternalUrl(hmrUrl) && !isDataUrl(hmrUrl) if (isLocalImport) { - importedUrls.add(hmrUrl) + orderedImportedUrls[index] = hmrUrl } if (enablePartialAccept && importedBindings) { @@ -718,6 +718,9 @@ export function importAnalysisPlugin(config: ResolvedConfig): Plugin { }), ) + const importedUrls = new Set( + orderedImportedUrls.filter(Boolean) as string[], + ) const acceptedUrls = mergeAcceptedUrls(orderedAcceptedUrls) const acceptedExports = mergeAcceptedUrls(orderedAcceptedExports) diff --git a/playground/module-graph/__tests__/module-graph.spec.ts b/playground/module-graph/__tests__/module-graph.spec.ts new file mode 100644 index 00000000000000..bfabd53f289724 --- /dev/null +++ b/playground/module-graph/__tests__/module-graph.spec.ts @@ -0,0 +1,12 @@ +import { expect, test } from 'vitest' +import { isServe, page, viteServer } from '~utils' + +test.runIf(isServe)('importedUrls order is preserved', async () => { + const el = page.locator('.imported-urls-order') + expect(await el.textContent()).toBe('[success]') + const mod = await viteServer.moduleGraph.getModuleByUrl( + '/imported-urls-order.js', + ) + const importedModuleIds = [...mod.importedModules].map((m) => m.url) + expect(importedModuleIds).toEqual(['\x00virtual:slow-module', '/empty.js']) +}) diff --git a/playground/module-graph/empty.js b/playground/module-graph/empty.js new file mode 100644 index 00000000000000..e69de29bb2d1d6 diff --git a/playground/module-graph/imported-urls-order.js b/playground/module-graph/imported-urls-order.js new file mode 100644 index 00000000000000..9ccf4527e6665d --- /dev/null +++ b/playground/module-graph/imported-urls-order.js @@ -0,0 +1,7 @@ +import { msg } from 'virtual:slow-module' +import './empty.js' + +export default msg + +// This module tests that the import order is preserved in this module's `importedUrls` property +// as the imports can be processed in parallel diff --git a/playground/module-graph/index.html b/playground/module-graph/index.html new file mode 100644 index 00000000000000..663a7d7ed0066a --- /dev/null +++ b/playground/module-graph/index.html @@ -0,0 +1,10 @@ +
+ + diff --git a/playground/module-graph/package.json b/playground/module-graph/package.json new file mode 100644 index 00000000000000..35e0799c262738 --- /dev/null +++ b/playground/module-graph/package.json @@ -0,0 +1,12 @@ +{ + "name": "@vitejs/test-hmr", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "vite build", + "debug": "node --inspect-brk ../../packages/vite/bin/vite", + "preview": "vite preview" + } +} diff --git a/playground/module-graph/vite.config.ts b/playground/module-graph/vite.config.ts new file mode 100644 index 00000000000000..53e07ff3bfd483 --- /dev/null +++ b/playground/module-graph/vite.config.ts @@ -0,0 +1,23 @@ +import { defineConfig } from 'vite' +import type { Plugin } from 'vite' + +export default defineConfig({ + plugins: [slowModulePlugin()], +}) + +function slowModulePlugin(): Plugin { + return { + name: 'slow-module', + resolveId(id) { + if (id === 'virtual:slow-module') { + return '\0virtual:slow-module' + } + }, + async load(id) { + if (id === '\0virtual:slow-module') { + await new Promise((resolve) => setTimeout(resolve, 500)) + return `export const msg = '[success]'` + } + }, + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f68bc2bd12eb42..83017836b874ba 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -740,6 +740,8 @@ importers: playground/minify/dir/module: {} + playground/module-graph: {} + playground/multiple-entrypoints: devDependencies: fast-glob: