Upgrade to Webpack 4
Webpack 4 offers several improvements including:
- much faster build times
- a declarative syntax for automatic chunk splitting
-
<script async>
support - better tree shaking for "pure modules" without side effects
Beta announcement: https://medium.com/webpack/webpack-4-beta-try-it-today-6b1d27d7d7e2
Release announcement: https://medium.com/webpack/webpack-4-released-today-6cdb994702d4
Priority: Urgent
Right now, since gitlab-org/gitlab-ce#41341, we have no CommonsChunk
definitions outside of our vendor'd libraries which are loaded on all pages. Any code that is not linked in main.js
or commons/index.js
which exists in more than one route is currently duplicated. This is an inefficient use of browser caching and contributes needlessly to bloated omnibus package size (by repeating some modules/libraries in multiple bundles).
To Do:
-
Update Dependencies -
Nearly all of them have not been updated to support webpack 4, except forkarma-webpack
. We'll need to either contribute a fix upstream, or update our CI config to preventyarn check
from failing our builds due to mismatchingpeerDependencies
.
Edit:karma-webpack
is now compatible -
Clean Up Config - Many webpack config options have changed or been made redundant. We need to adjust the way our development/production mode defaults are defined. This will likely result in a much more simplified webpack config file.
Reference to new config options and their defaults: https://medium.com/webpack/webpack-4-mode-and-optimization-5423a6bc597a
-
Fix Karma Tests - Karma is failing in webpack 4 due to the way we had been taking advantage of some undocumented ESM behavior in webpack 2/3. We are no longer able to use jasmine's
spyOn
with modules which have been imported withimport * as Foo from 'foo';
. Modules will also now fail if you attempt to referencethis
within a module context (which we do in a few specs).Related issue: gitlab-org/gitlab-ce#30998
-
Adjust Rails Integration - We need to update our
webpack-rails
integration to understandChunkGroup
s when generating script tags. Entry points now correspond to collections of split chunks rather than a single file. All of the must be loaded together. -
Verify That Multiple Entry Points Can Coexist -
The new behavior of the webpack runtime doesn't seem to expect multiple entry points to be run on a single page. We need to make sure these will work when we do things like conditionally add theraven
bundle as an entry point. If this does not work as expected, we will need to find another way to accomplish this.
Edit: After some testing, this appears to work just fine as long as we use a single runtime chunk for all entry points on the page (seeoptimization.runtimeChunk
). -
Ensure Nothing Has Broken - Audit the new development/production mode defaults in webpack 4, ensure sourcemaps and breakpoints still work, ensure our webpack-dev-server workflow still works, check our
uglify
output.
Follow Ups:
-
Enable Async Scripts - We need to ensure that
DOMContentLoaded
events in our route-based entry points play nice with async chunks. This could be problematic because async scripts may run any time before or after theDOMContentLoaded
event fires. We may need to define a new method to trigger these events, similar tojQuery(document).ready()
. See: -
Take Advantage of Tree Shaking - Update to several libraries which support
sideEffects: false
in theirpackage.json
including lodash.Related issue: #23110 (moved)
-
Revisit Named Chunks and Long-term Caching - Bundle size is a paramount concern for performance, and attempting to manage cache strings such that they remain the same from one release to another will become a lower priority than it was in prior releases. We'll be removing the convoluted
NamedChunksPlugin
andNameAllModulesPlugin
definitions temporarily until their usefulness can be re-assessed.