Skip to content

Generate independent JS bundles with no code sharing between bundles (service workers, multi-page apps, multiple library formats) #12203

Open
@jschaf

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

Multiple Bundles

Build slightly different apps

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

  1. 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.

  2. 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

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions