Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 37 additions & 5 deletions packages/vite/src/node/plugins/importAnalysisBuild.ts
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,42 @@ export function buildImportAnalysisPlugin(config: ResolvedConfig): Plugin[] {
}

if (imports.length) {
// Nested preload wrappers emit inner markers before outer markers.
// Pair markers with the latest open dynamic import while scanning forward.
const markerStartPosByImportIndex = new Map<number, number>()
const openImports: number[] = []
let importIndex = 0
let markerStartPos = findPreloadMarker(code)
const firstMarkerStartPos = markerStartPos
while (markerStartPos !== -1) {
while (
importIndex < imports.length &&
imports[importIndex].e <= markerStartPos
) {
openImports.push(importIndex)
importIndex++
}
const ownerImportIndex = openImports.pop()
if (ownerImportIndex !== undefined) {
markerStartPosByImportIndex.set(
ownerImportIndex,
markerStartPos,
)
}
markerStartPos = findPreloadMarker(
code,
markerStartPos + preloadMarker.length,
)
}
// fix issue #3051
if (
firstMarkerStartPos !== -1 &&
imports.length === 1 &&
!markerStartPosByImportIndex.has(0)
) {
markerStartPosByImportIndex.set(0, firstMarkerStartPos)
}

for (let index = 0; index < imports.length; index++) {
// To handle escape sequences in specifier strings, the .n field will be provided where possible.
const {
Expand Down Expand Up @@ -438,11 +474,7 @@ export function buildImportAnalysisPlugin(config: ResolvedConfig): Plugin[] {
addDeps(normalizedFile)
}

let markerStartPos = findPreloadMarker(code, end)
// fix issue #3051
if (markerStartPos === -1 && imports.length === 1) {
markerStartPos = findPreloadMarker(code)
}
markerStartPos = markerStartPosByImportIndex.get(index) ?? -1

if (markerStartPos > 0) {
// the dep list includes the main chunk, so only need to reload when there are actual other deps.
Expand Down
31 changes: 31 additions & 0 deletions playground/dynamic-import/__tests__/dynamic-import.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,37 @@ test('should load dynamic import with css in package', async () => {
await expect.poll(() => getColor('.pkg-css')).toBe('blue')
})

test.runIf(isBuild)(
'should preload css for nested dynamic imports',
async () => {
const js = findAssetFile(/index-[-\w]{8}\.js$/) ?? ''
const innerPreload = js.match(
/import\([^)]*issue-22700-b-[-\w]+\.js[^)]*\)[\s\S]*?(,\[\]\)|__vite__mapDeps)/,
)?.[1]
expect(innerPreload).toBe(',[])')

await page.click('.issue-22700')
await expect
.poll(() => page.textContent('.issue-22700-result'))
.toMatch('nested dynamic import with css')
await expect
.poll(() =>
page.evaluate(() =>
Array.from(
document.querySelectorAll<HTMLLinkElement>(
'link[rel="stylesheet"]',
),
(link) => link.href,
).some((href) => /issue-22700-a-[-\w]+\.css$/.test(href)),
),
)
.toBe(true)
await expect
.poll(() => getColor('.issue-22700-result'))
.toBe('rgb(12, 34, 56)')
},
)

test('should work with load ../ and itself directory', async () => {
await expect
.poll(() => page.textContent('.dynamic-import-self'))
Expand Down
3 changes: 3 additions & 0 deletions playground/dynamic-import/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
<button class="issue-2658-2">Issue 2658 - 2</button>
<button class="css">css</button>
<button class="pkg-css">pkg-css</button>
<button class="issue-22700">Issue 22700</button>

<p>dynamic-import-with-vars</p>
<div class="dynamic-import-with-vars">todo</div>
Expand Down Expand Up @@ -39,6 +40,8 @@

<div class="view"></div>

<div class="issue-22700-result"></div>

<div class="dynamic-import-self"></div>

<div class="dynamic-import-static"></div>
Expand Down
9 changes: 9 additions & 0 deletions playground/dynamic-import/nested/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,15 @@ document.querySelector('.pkg-css').addEventListener('click', async () => {
text('.view', 'dynamic import css in package')
})

document.querySelector('.issue-22700').addEventListener('click', async () => {
const { markerClass } = await import('./issue-22700-a.js').then((mod) => {
return import('./issue-22700-b.js').then(() => mod)
})
const result = document.querySelector('.issue-22700-result')
result.classList.add(markerClass)
text('.issue-22700-result', 'nested dynamic import with css')
})

function text(el, text) {
document.querySelector(el).textContent = text
}
Expand Down
3 changes: 3 additions & 0 deletions playground/dynamic-import/nested/issue-22700-a.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.issue-22700-loaded {
color: rgb(12, 34, 56);
}
3 changes: 3 additions & 0 deletions playground/dynamic-import/nested/issue-22700-a.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import './issue-22700-a.css'

export const markerClass = 'issue-22700-loaded'
1 change: 1 addition & 0 deletions playground/dynamic-import/nested/issue-22700-b.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const msg = 'nested dynamic import with css'
Loading