fix(build): avoid __vitePreload
breaking rollup dynamic import tree-shaking
#17367
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Description
The
__vitePreload
function breaks Rollup's dynamic import tree-shaking.Consider the following entry file example:
And the
foo.ts
file:Bundle this using Rollup will result in entry file
index.js
:And file
foo-i1IIQb7W.js
:However, if bundled using Vite in non-lib mode, it generates entry file
index-BY2O_S30.js
insideindex.thml
:And the file
foo-B2TMQ0vo.js
:The reason that tree-shaking of dynamic imports fails is that the
__vitePreload
function only wraps theimport(/* module name */)
, but Rollup needs additional information to perform tree-shaking on the imported module.To address this, I used AST to analyze what should be wrapped in the
__vitePreload
function.After testing, I found two ways to consistently trigger Rollup's tree-shaking of dynamically imported modules:
import('./foo').then( ({ foo, bar }) => /* use foo and bar */)
const { foo, bar } = await import('./foo')
For the first case, I wrap the full import expression and its first
then
call expression into the__vitePreload
function.For the second case, I add a
then
call expression to indicate which exported content will be destructured and wrap it into the__vitePreload
function.After modification, Vite generates the entry JS file:
And the file
foo-B4NibxfM.js
:Now it could tree-shake the dynamically imported module just as in Rollup!
I have used this modified Vite in production environment for my corporation, and it hasn't received any bug reports yet.