Describe the bug
Vite bundles both the Vue library and its own helpers into the top index chunk, and because all components import Vue and use those helpers, then all JavaScript chunks import index.
The impact is that a change to one component causes a hash change to all components which cause a large browser cache invalidation between code releases.
Reproduction
https://github.com/jf-paradis/vite-circular-dependencies
Steps to reproduce
Since the top index indirectly imports all components, any change in a single component changes that component hash, then cascades up to index, then cascades back down to all components.
The impact can be seen here as follow:
-
Checkout the code at https://github.com/jf-paradis/vite-circular-dependencies
-
Run npm install
-
Build the app, save the list of hash changes (lines omitted for clarity):
% npm run build
dist/assets/vue.5532db34.svg 0.48 KiB
dist/index.html 0.44 KiB
dist/assets/HelloWorld.2a228e41.js 0.26 KiB / gzip: 0.21 KiB
dist/assets/Panel.37d1d496.js 0.19 KiB / gzip: 0.17 KiB
dist/assets/ByByeWorld.22d2d993.js 0.26 KiB / gzip: 0.22 KiB
dist/assets/index.3f6467e9.css 1.21 KiB / gzip: 0.63 KiB
dist/assets/index.7837aefd.js 52.55 KiB / gzip: 21.24 KiB
- Change one of the components, for example change "Hello" to "Hello!" in
HelloWorld.vue, and rebuild:
% npm run build
dist/assets/vue.5532db34.svg 0.48 KiB
dist/index.html 0.44 KiB
dist/assets/HelloWorld.85a3b193.js 0.26 KiB / gzip: 0.21 KiB
dist/assets/Panel.9626c151.js 0.19 KiB / gzip: 0.17 KiB
dist/assets/ByByeWorld.d27c7ad5.js 0.26 KiB / gzip: 0.22 KiB
dist/assets/index.3f6467e9.css 1.21 KiB / gzip: 0.63 KiB
dist/assets/index.6acde798.js 52.55 KiB / gzip: 21.25 KiB
- Notice that the hash of
ByeByeWorld.js has changed, even if that component doesn't import HelloWorld.vue. In fact, all JavaScript files have new hashes.
This can be explained becuase all chunks import index:
% grep -rEo "/index\.\w+\.js" dist
dist/index.html:/index.6acde798.js
dist/assets/Panel.9626c151.js:/index.6acde798.js
dist/assets/ByByeWorld.d27c7ad5.js:/index.6acde798.js
dist/assets/HelloWorld.85a3b193.js:/index.6acde798.js
Workaround
-
Uncomment the manualChunks function in vite.config.ts.
-
Build the app
% npm run build
dist/assets/vue.5532db34.svg 0.48 KiB
dist/index.html 0.59 KiB
dist/assets/index.caa16f9f.js 1.13 KiB / gzip: 0.58 KiB
dist/assets/vite.288ff0a5.js 1.26 KiB / gzip: 0.67 KiB
dist/assets/HelloWorld.78a2bc30.js 0.26 KiB / gzip: 0.22 KiB
dist/assets/Panel.2ce48d7b.js 0.19 KiB / gzip: 0.17 KiB
dist/assets/ByByeWorld.1350f4f8.js 0.27 KiB / gzip: 0.22 KiB
dist/assets/index.3f6467e9.css 1.21 KiB / gzip: 0.63 KiB
dist/assets/vendor.3885daba.js 50.40 KiB / gzip: 20.29 KiB
- Change one of the components again, for example revert "Hello!" to "Hello" in
HelloWorld.vue, and rebuild:
dist/assets/vue.5532db34.svg 0.48 KiB
dist/index.html 0.59 KiB
dist/assets/index.15a1828f.js 1.13 KiB / gzip: 0.58 KiB
dist/assets/HelloWorld.5cb36190.js 0.26 KiB / gzip: 0.22 KiB
dist/assets/vite.288ff0a5.js 1.26 KiB / gzip: 0.67 KiB
dist/assets/Panel.2ce48d7b.js 0.19 KiB / gzip: 0.17 KiB
dist/assets/ByByeWorld.1350f4f8.js 0.27 KiB / gzip: 0.22 KiB
dist/assets/index.3f6467e9.css 1.21 KiB / gzip: 0.63 KiB
dist/assets/vendor.3885daba.js 50.40 KiB / gzip: 20.29 KiB
Notice that the hash of ByeByeWorld.js has NOT changed. In fact, only HelloWorld.js and index.js have changed.
- This can be explained because none of the chunks are importing index:
% grep -rEo "/index\.\w+\.js" dist
dist/index.html:/index.15a1828f.js
System Info
Binaries:
Node: 16.16.0 - ~/.nvm/versions/node/v16.16.0/bin/node
Yarn: 1.22.19 - /opt/homebrew/bin/yarn
npm: 8.11.0 - ~/.nvm/versions/node/v16.16.0/bin/npm
npmPackages:
@vitejs/plugin-vue: ^3.1.0 => 3.1.2
vite: ^3.1.0 => 3.1.8
Used Package Manager
npm
Logs
No response
Validations
Describe the bug
Vite bundles both the Vue library and its own helpers into the top index chunk, and because all components import Vue and use those helpers, then all JavaScript chunks import index.
The impact is that a change to one component causes a hash change to all components which cause a large browser cache invalidation between code releases.
Reproduction
https://github.com/jf-paradis/vite-circular-dependencies
Steps to reproduce
Since the top index indirectly imports all components, any change in a single component changes that component hash, then cascades up to index, then cascades back down to all components.
The impact can be seen here as follow:
Checkout the code at
https://github.com/jf-paradis/vite-circular-dependenciesRun
npm installBuild the app, save the list of hash changes (lines omitted for clarity):
HelloWorld.vue, and rebuild:ByeByeWorld.jshas changed, even if that component doesn't importHelloWorld.vue. In fact, all JavaScript files have new hashes.This can be explained becuase all chunks import index:
% grep -rEo "/index\.\w+\.js" dist dist/index.html:/index.6acde798.js dist/assets/Panel.9626c151.js:/index.6acde798.js dist/assets/ByByeWorld.d27c7ad5.js:/index.6acde798.js dist/assets/HelloWorld.85a3b193.js:/index.6acde798.jsWorkaround
Uncomment the
manualChunksfunction invite.config.ts.Build the app
HelloWorld.vue, and rebuild:Notice that the hash of
ByeByeWorld.jshas NOT changed. In fact, onlyHelloWorld.jsandindex.jshave changed.% grep -rEo "/index\.\w+\.js" dist dist/index.html:/index.15a1828f.jsSystem Info
Binaries: Node: 16.16.0 - ~/.nvm/versions/node/v16.16.0/bin/node Yarn: 1.22.19 - /opt/homebrew/bin/yarn npm: 8.11.0 - ~/.nvm/versions/node/v16.16.0/bin/npm npmPackages: @vitejs/plugin-vue: ^3.1.0 => 3.1.2 vite: ^3.1.0 => 3.1.8Used Package Manager
npm
Logs
No response
Validations