Skip to content

Instantly share code, notes, and snippets.

@timneutkens
Last active April 25, 2024 16:15
Show Gist options
  • Save timneutkens/63f95e096a7a060627ca53056720022e to your computer and use it in GitHub Desktop.
Save timneutkens/63f95e096a7a060627ca53056720022e to your computer and use it in GitHub Desktop.

Barrel Files

There are different types of barrel files. These are three conditions that define how they can be processed by a bundler:

  1. Barrel file and all imported modules are flagged as side-effect free via "sideEffects": false (etc.) in package.json.
  2. Barrel file contains named re-exports (export { default as something } from "./inner", export { something } from "./inner") instead of star re-exports (export * from "./inner").
  3. Barrel file contains additional local declarations or exports and they are imported from other modules.

Limitations

When condition 1 is false (not flagged as side-effect free), the ESM spec requires all inner modules to be evaluated. So the bundler has to read and process them to find potential side effects.

When condition 2 is false (using star re-exports), the bundler need to read and process all inner modules to find the export that was actually requested by the importing module.

webpack

Webpack will always read and process all inner modules independed of these conditions.

Webpack has a side effects optimization that allow it to skip over the barrel file and import the inner module directly if condition 1 is true.

When condition 3 is true (local declarations in barrel file imported), webpack won't be able to skip the barrel file.

In production builds the following optimization apply in additional to that:

Webpack also has a Scope Hoisting optimization, so in cases when barrel file can't be directly skipped, it can be merged with the inner modules, reducing the number of modules in the final bundle.

Webpack will remove unused exports, so a minimizer can use Dead-Code Elimination to get rid of code of the inner modules in some cases.

Turbopack

Turbopack will only read and process the inner modules when either condition 1 or condition 2 is false (see limitations).

Turbopack has a side effects optimization that allow it to skip over the barrel file and import the inner module directly if condition 1 is true.

When condition 3 is true (local declarations in barrel file imported), Turbopack is able to separate local exports from the re-exports and can still skip the barrel file.

Turbopack doesn't have production builds yet.

Summary

1: side-effect-free 2: named re-exports 3: local declarations skip processing skip bundling
no ? ? Webpack ❌
Turbopack ❌
Webpack ❌
Turbopack ❌
yes no no Webpack ❌
Turbopack ❌
Webpack ✅
Turbopack: ✅
yes no yes Webpack ❌
Turbopack ❌
Webpack ❌
Turbopack: ✅
yes yes no Webpack ❌
Turbopack ✅
Webpack ✅
Turbopack: ✅
yes yes yes Webpack ❌
Turbopack ✅
Webpack ❌
Turbopack: ✅
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment