fix: preload css for nested dynamic imports (fix #22700)#22721
Conversation
|
Thanks for digging into this. It does make the CSS load again, but the pairing it produces attaches each import's deps to the wrong marker. For __vitePreload(
() =>
import('a').then(() =>
__vitePreload(() => import('b') /* a's deps */),
) /* b's deps */,
)a's CSS is no longer dropped, which fixes the visible bug, but it now sits on the inner |
72cd357 to
ff84d70
Compare
|
Thanks, that makes sense. I updated the branch to pair preload markers from the inside out by processing dynamic imports in reverse order. I also tightened the build test so it checks the generated output shape: the outer Validated locally:
|
|
Nice, the backwards + skip-claimed version pairs them correctly now. Each nested import gets its own deps, so #22700 is fixed and the swap is gone. I ran it against the original repro and a few nesting shapes, CSS lands on the right call. Two tiny things, both minor:
Also tweaked the test a bit. The build regex pins the exact minified shape (the arrows and the 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(',[])') |
shulaoda
left a comment
There was a problem hiding this comment.
LGTM. cc @sapphi-red, both this and #22759 fix it and this one's a smaller diff. Left a couple of small notes above.
sapphi-red
left a comment
There was a problem hiding this comment.
Marking so that it's clear that I'm reviewing this and #22759
Description
Fixes #22700.
Nested dynamic imports could reuse a preload marker that had already been paired with an earlier import. When that happened, the outer import could lose its dependency list and the CSS for the imported chunk would not be loaded in production builds.
This change skips already-consumed preload markers before rewriting the marker for the current dynamic import.
The regression test exercises the build-only behavior in the dynamic-import playground by checking that the nested import creates a stylesheet link and applies the imported CSS.
Tests
pnpm run buildpnpm --filter vite run buildpnpm run test-build dynamic-import -t "should preload css for nested dynamic imports"pnpm run test-build dynamic-importpnpm exec eslint packages/vite/src/node/plugins/importAnalysisBuild.ts playground/dynamic-import/__tests__/dynamic-import.spec.ts playground/dynamic-import/nested/index.js playground/dynamic-import/nested/issue-22700-a.js playground/dynamic-import/nested/issue-22700-b.jspnpm exec oxfmt --check packages/vite/src/node/plugins/importAnalysisBuild.ts playground/dynamic-import/__tests__/dynamic-import.spec.ts playground/dynamic-import/index.html playground/dynamic-import/nested/index.js playground/dynamic-import/nested/issue-22700-a.js playground/dynamic-import/nested/issue-22700-b.js playground/dynamic-import/nested/issue-22700-a.cssgit diff --check