Skip to content

Commit 269aa43

Browse files
committed
fix(import-analysis): preserve importedUrls import order (#14465)
1 parent 6f6e5de commit 269aa43

File tree

8 files changed

+71
-2
lines changed

8 files changed

+71
-2
lines changed

packages/vite/src/node/plugins/importAnalysis.ts

+5-2
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,6 @@ export function importAnalysisPlugin(config: ResolvedConfig): Plugin {
278278
let needQueryInjectHelper = false
279279
let s: MagicString | undefined
280280
const str = () => s || (s = new MagicString(source))
281-
const importedUrls = new Set<string>()
282281
let isPartiallySelfAccepting = false
283282
const importedBindings = enablePartialAccept
284283
? new Map<string, Set<string>>()
@@ -411,6 +410,7 @@ export function importAnalysisPlugin(config: ResolvedConfig): Plugin {
411410
return [url, resolved.id]
412411
}
413412

413+
const orderedImportedUrls = new Array<string | undefined>(imports.length)
414414
const orderedAcceptedUrls = new Array<Set<UrlPosition> | undefined>(
415415
imports.length,
416416
)
@@ -640,7 +640,7 @@ export function importAnalysisPlugin(config: ResolvedConfig): Plugin {
640640
const hmrUrl = unwrapId(stripBase(url, base))
641641
const isLocalImport = !isExternalUrl(hmrUrl) && !isDataUrl(hmrUrl)
642642
if (isLocalImport) {
643-
importedUrls.add(hmrUrl)
643+
orderedImportedUrls[index] = hmrUrl
644644
}
645645

646646
if (enablePartialAccept && importedBindings) {
@@ -718,6 +718,9 @@ export function importAnalysisPlugin(config: ResolvedConfig): Plugin {
718718
}),
719719
)
720720

721+
const importedUrls = new Set(
722+
orderedImportedUrls.filter(Boolean) as string[],
723+
)
721724
const acceptedUrls = mergeAcceptedUrls(orderedAcceptedUrls)
722725
const acceptedExports = mergeAcceptedUrls(orderedAcceptedExports)
723726

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { expect, test } from 'vitest'
2+
import { isServe, page, viteServer } from '~utils'
3+
4+
test.runIf(isServe)('importedUrls order is preserved', async () => {
5+
const el = page.locator('.imported-urls-order')
6+
expect(await el.textContent()).toBe('[success]')
7+
const mod = await viteServer.moduleGraph.getModuleByUrl(
8+
'/imported-urls-order.js',
9+
)
10+
const importedModuleIds = [...mod.importedModules].map((m) => m.url)
11+
expect(importedModuleIds).toEqual(['\x00virtual:slow-module', '/empty.js'])
12+
})

playground/module-graph/empty.js

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { msg } from 'virtual:slow-module'
2+
import './empty.js'
3+
4+
export default msg
5+
6+
// This module tests that the import order is preserved in this module's `importedUrls` property
7+
// as the imports can be processed in parallel

playground/module-graph/index.html

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<div class="imported-urls-order"></div>
2+
3+
<script type="module">
4+
import importedUrlsOrderSuccess from './imported-urls-order'
5+
text('.imported-urls-order', importedUrlsOrderSuccess)
6+
7+
function text(el, text) {
8+
document.querySelector(el).textContent = text
9+
}
10+
</script>

playground/module-graph/package.json

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"name": "@vitejs/test-hmr",
3+
"private": true,
4+
"version": "0.0.0",
5+
"type": "module",
6+
"scripts": {
7+
"dev": "vite",
8+
"build": "vite build",
9+
"debug": "node --inspect-brk ../../packages/vite/bin/vite",
10+
"preview": "vite preview"
11+
}
12+
}
+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { defineConfig } from 'vite'
2+
import type { Plugin } from 'vite'
3+
4+
export default defineConfig({
5+
plugins: [slowModulePlugin()],
6+
})
7+
8+
function slowModulePlugin(): Plugin {
9+
return {
10+
name: 'slow-module',
11+
resolveId(id) {
12+
if (id === 'virtual:slow-module') {
13+
return '\0virtual:slow-module'
14+
}
15+
},
16+
async load(id) {
17+
if (id === '\0virtual:slow-module') {
18+
await new Promise((resolve) => setTimeout(resolve, 500))
19+
return `export const msg = '[success]'`
20+
}
21+
},
22+
}
23+
}

pnpm-lock.yaml

+2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)