core-js v3 pure imports and webpack module cache interoperability
0 reputation · 02 May 2022, 08:58 UTC
0 reputation · 02 May 2022, 08:58 UTC
Goal is to understand how core-js v3 entry points interact with webpack’s module cache and whether stale polyfill code can persist across rebuilds when the underlying implementation changes.
core-js v3 exposes two supported entry styles: the default 'core-js' patched-globals entry and 'core-js/pure' per-feature imports. The default entry can be treated by bundlers as a single module, while pure imports enable tree-shaking and finer granularity. Behavior differs between core-js v2 and v3, and bundler-specific caching such as webpack’s persistent module cache can mask or amplify stale results.
An unresolved design decision in the core-js repository concerns automatic version-hash injection into bundled output to bust caches when a polyfill implementation changes. Current documentation describes the two entry points but does not specify cache invalidation expectations at the bundler boundary.
Does using 'core-js/pure' reduce the risk of stale polyfill results compared with the default 'core-js' entry under webpack’s persistent cache? Is there documented guidance for cache invalidation when individual polyfill files change? What is the current status of the version-hash proposal for bundled output?
34775 reputation · 02 May 2022, 12:18 UTC
Does core-js/pure reduce stale polyfill risk? Yes. Granular imports give webpack separate cache entries per feature, so a change to one polyfill invalidates only that entry.
Is there documented guidance for cache invalidation when individual polyfill files change? No. The core-js README and CHANGELOG describe entry points but do not specify bundler‑level cache expectations.
What is the status of the version‑hash proposal? It remains an open issue in the core-js repository; no implementation has been merged as of the last known state.
Webpack 5’s persistent cache stores each module by the hash of its resolved file. With the default import 'core-js' the entry point is a single file that re‑exports all polyfills; its content hash changes only when the entry file itself is edited, not when an internal polyfill is patched. Consequently the cached module may be reused even though the underlying implementation changed, presenting a risk of stale code.
With core-js/pure each import such as import 'core-js/pure/array/flat-map' resolves to a distinct polyfill file. The cache key is the hash of that file, so a change to the file updates the hash and webpack invalidates only that module. Other polyfills stay cached, limiting the stale‑code surface to the changed feature.
sideEffects: false in its package.json, enabling tree‑shaking of pure imports.cache: { type: 'filesystem' }.import 'core-js/pure/array/flat-map';.npx webpack --mode=production and note the emitted modules.node_modules/core-js-pure/array/flat-map.js) to simulate a change.import 'core-js'; as the entry and observe whether the whole core-js module is reused from cache despite the internal change.Are you using a custom cache.key function or cache.buildDependencies that includes lockfiles (package-lock.json or yarn.lock)? If yes, a lockfile change on a core-js upgrade may already invalidate the cache, reducing the practical difference between entry styles. If no, the pure‑import granularity remains the primary defense against stale polyfills.
Use comments to ask for clarification. Post a solution as an answer.
34,775 reputation · 02 May 2022, 10:53 UTC
Since v3.36 (2024), core-js ships core-js/stable and core-js/web entry points. These are convenience barrels that re-export the same full polyfill set as the default core-js entry — they remain single modules in webpack's cache graph, so they inherit the same stale-cache risk.
Writing import 'core-js/pure' (without a feature path) pulls the entire registry into one module, collapsing the per-feature cache keys back into a single entry. Only import 'core-js/pure/features/<name>' (or the older core-js/pure/array/flat-map style) preserves per-polyfill invalidation.
Until a version-hash lands, the reliable pattern is webpack-side: set cache.buildDependencies.config: ['package-lock.json'] (or yarn.lock/pnpm-lock.yaml) and use [contenthash] in output filenames. With pnpm or Yarn PnP, verify that lockfile changes actually rewrite on-disk file contents — hardlinked stores can keep content hashes stable across version bumps.