Generate independent JS bundles with no code sharing between bundles (service workers, multi-page apps, multiple library formats) #12203
Description
Description
As a developer using Vite, I want to be able to generate independent bundles for a service worker and the main app. I want the service worker bundle to be completely independent of the main bundle to avoid unnecessary imports. Code splitting is less beneficial when the bundles run in different scopes or pages.
Example
Let's say I have the following file tree:
- main.js (entry point: depends on main_dep.js and shared_library.js)
- main_dep.js
- service_worker.js (entry point: depends on service_worker_dep.js and shared_library.js)
- service_worker_dep.js
- shared_library.js
In this case, Vite generates three chunks because a single invocation of Rollup ensures code is never duplicated:
- main.hash.js: contains main.js and main_dep.js; imports shared_library.hash.js
- service_worker.hash.js: contains service_worker.js and service_worker_dep.js; imports shared_library.hash.js
- shared_library.hash.js
I want Vite to emit two independent bundles, duplicating shared_library.js in each chunk.
- main.hash.js: contains main.js, main_dep.js, and shared_library.hash.js
- service_worker.hash.js: contains service_worker.js, service_worker_dep.js, shared_library.hash.js
Related use cases
Independent (no code sharing) modules for library mode
- Folder as entry in library mode for multiple independent js modules #8098: the author said independent modules, but likely meant separate entry points
- Build multiple UMD files from multiple entries #7484: author ended up using separate Vite configs
- feat(lib): allow multiple entries #7047: comment mentions the ability to target multiple output formats like UMD, CJS, and modules.
Multiple Bundles
- How to do multiple bundles with vite?: Author notes that Webpack and Rollup support multiple bundles and will prefer those tools to Vite.
- https://github.com/innocenzi/laravel-vite/discussions/116: Resolved as implemented. The link is dead, but probably resolved by calling Vite multiple times.
- Stop Vite from splitting out all shared components into separate modules? ElMassimo/vite_ruby#138: The author had the same goal as this request. Workaround was to call Vite multiple times.
Build slightly different apps
- Support multiple (array) input/output options in rollupOptions #2039 (I've also wanted this)
Suggested solution
In the vite config object, support an array of Rollup options as requested in #2039.
In build mode, invoke Rollup once per array element.
In serve mode, I don't think Vite uses Rollup.
Pros
- Keep a single vite.config.ts, a single build and serve command.
- Increases flexibility of Vite to cover several requested use-cases.
Cons
- May differ from the philosophical goals of Vite.
- May add significant complexity to build command--I'm not familiar enough with Vite internals to know.
Alternative
-
Add a separate script tag in index.html. A disadvantage is that it's unclear whether a separate module should be independent of the main entry point.
-
Keep the status quo. A reasonable workaround is to use multiple Vite configs or accept code splitting when using multiple entry points. The main downside is that dealing with two Vite configs is significantly more awkward than a single config. Since a web worker is tightly coupled to the app it supports, it seems heavy-handed to require another Vite config.
Additional context
#2039 (Support multiple (array) input/output options in rollupOptions): Closed by Evan You
You can't because vite build runs a single Rollup build. If you want multiple builds, have multiple vite config files and run vite build -c different.config.js
Rollup tutorial: never duplicates code
Link to Rollup tutorial that declares that Rollup will never duplicate code.
StackOverflow: Prevent service-worker.js from being bundled with vite / rollup
Vite config to place service-worker.js at the top level of the directory. Shared code is split to a separate chunk to be imported by the main index.html entry point and service worker entry point.
How to add multiple inputs and outputs for Svelte rollup config
Blog post on how to emit multiple bundles in Rollup using an array of Rollup configurations instead of a single object. Another blog post on bundling into multiple formats hints that the bundles are likely independent.
Validations
- Follow our Code of Conduct
- Read the Contributing Guidelines.
- Read the docs.
- Check that there isn't already an issue that request the same feature to avoid creating a duplicate.