Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to handle deploys with Webpack code splitting?

Tags:

Here's an unexpected issue I've run into with Webpack code splitting in the wild: Imagine this scenario:

  1. The user loads a React app with Webpack code splitting and a few bundle chunks are loaded
  2. A deploy happens and the contents of any future chunks that the user might receive from the server are updated (note: the previous chunks get deleted on the server during a deploy)
  3. The user clicks on a link and loads a new route which triggers more bundle chunks to load. Except these new chunks are incompatible with the ones the user's browser has already loaded and the app breaks because of a runtime error

How can this scenario be prevented?

One possible solution would be to maintain multiple versioned sets of chunks but I'm wondering if there's a simpler solution being used by large-scale apps.

If preload-webpack-plugin is used, all chunks can be prefetched but they will only stay cached for a short time (5 minutes in Chrome).

like image 961
Maros Avatar asked Aug 03 '17 19:08

Maros


People also ask

Does webpack do code splitting?

Code-Splitting is a feature supported by bundlers like Webpack, Rollup and Browserify (via factor-bundle) which can create multiple bundles that can be dynamically loaded at runtime.

What is webpack chunking?

Chunk: This webpack-specific term is used internally to manage the bundling process. Bundles are composed out of chunks, of which there are several types (e.g. entry and child).

Which approaches are used by next JS for code splitting * Entry points prevent duplicate dynamic imports all of the above?

There are three general approaches to code splitting available: Entry Points: Manually split code using entry configuration. Prevent Duplication: Use Entry dependencies or SplitChunksPlugin to dedupe and split chunks. Dynamic Imports: Split code via inline function calls within modules.


1 Answers

As Max Stoiber writes on spectrum.chat:

ServiceWorkers come in really handy when doing code splitting!

We use the excellent offline-plugin by @nekr to cache all the current bundles locally, so no matter if the server updates the files or not the ServiceWorker will always serve the files from the local cache. Every hour it will check the server for updates and, if an update is available, download all the fresh bundles from the remote server and cache them locally. The next time the user restarts the app the new version of the app is used! 💯

https://github.com/NekR/offline-plugin

This solution means your app downloads all the chunks up front, which defeats the purpose of code splitting in terms of bandwidth, but at least you still retain the benefit of only parsing the chunks you need to load the app, which for me is significant on slow devices. Also, browser refreshes/caching now involves the Service Worker lifecycle (see "Waiting" at https://developers.google.com/web/fundamentals/primers/service-workers/lifecycle).

like image 74
Dmitry Minkovsky Avatar answered Sep 28 '22 11:09

Dmitry Minkovsky