Webpack 2 Deep Dive
This course has been updated! We now recommend you take the Webpack 4 Fundamentals course.
Table of Contents
Getting Started with Webpack
Workshop OutlineKent C. Dodds opens his workshop on Webpack 2.0 by setting some expectations for what he will be covering. Kent outlines the requirements for running the workshop exercises and walks through the setup. Every exercise has its own branch in the Github repository. Links to solutions are located on each slide.
Webpack 101Kent begins by making a case for Webpack. He explains how it replaces task runners like Grunt or Gulp. Webpack also allows developers to explicitly declare dependencies making the bundling of modules into static assets much easier.
Loaders and PluginsLoaders and Plugins are two of the most important concepts to understand inside Webpack. Loaders handle file-specific processing like looking for all CSS files and running them through a SASS processor. Plugins are add-ons that carry out specific tasks like code splitting or enabling offline capabilities through the use of ServiceWorkers.
Todo App WalkthroughKent spends some time walking through the Todo application he will be using throughout the workshop. This application will be migrated so it uses the features of Webpack 2.0. The code for this initial walkthrough is located on the 00-original-project branch.
Initializing WebpackKent demonstrates how to initialize Webpack for use in the Todo application. He creates the configuration file and talks about how to enable the use of ES6 syntax. Kent then specifies bundle.js as the output file which will contain all the initial application code.
Specifying an Entry PointWebpack needs an explicit entry point to be specified in the configuration file. This allows Webpack to locate all the application dependencies and include them in the packaged version of the application.
Webpack ValidatorKent spends a few minutes answering some audience questions about Webpack and ES6. He then introduces the Webpack Validator module which looks at the Webpack configuration settings and provides better feedback messages when there is a configuration error.
Webpack Dev ServerSince the application is being built with NPM, the “--watch” flag can be specified to rerun the build command whenever a file is modified. This is helpful, however, Kent will be using the Webpack Dev Server to handle this instead. The Webpack Dev Server contains other helpful features like Hot Module Replacement which will be covered later in the workshop.
Path ConfigurationThe path configuration variable is used to specify the absolute path to where the bundled output files should be generated. A publicPath variable must also be specified so the Webpack Dev Server knows the location of the files on the server. After adding these configuration variables, Kent spends a few minutes answering audience questions and reviewing the build process.
Minifying & Source MapsMinifying the bundle generated from Webpack can be done by adding the “-p” flag. This creates a production build. After configuring the production build, Kent demonstrates how to add source maps to make the production code easier to debug. The preferred way to create source maps is to generate them in a separate .map file so they are only loaded when the browser developer tools are open.
Exercise: Adding WebpackWhile Kent has already covered most of the topics in this exercise, he spends a few minutes looking at the solution and talking though some Webpack utilities he included. The solution to this exercise is on the FEM/01.0-add-webpack branch.
Working with Webpack
Debugging WebpackThe “--inspect“ flag can be used on the command line for enabling some debugging capabilities in Webpack. At the time of this recording, this flag was only available in node-nightly. Code examples for debugging are located on the FEM/01.1-debug-webpack branch.
Exercise: Using the Style & CSS LoadersKent walks through an exercise covering the use of the Style and CSS loaders. He demonstrates how to require the application’s CSS files in app.js rather than index.html. The solution for this exercise is located on the FEM/01.5-css branch.
Hot Module ReplacementHot module replacement allows updated application code to be injected into he application without requiring the browser to be refreshed. It’s a useful tool for developers when working on a specific area of the application. Kent demonstrate the configuration and some of the APIs available. Code for this example is located on the FEM/01.6-hmr branch.
Testing with Webpack
Exercise: Initializing KarmaKent gives a quick overview of Karma which is the testing framework he’ll be using in the Todo application. Kent then walks through the exercise which initializes and configures Karma for use in the application. The solution to this exercise is located on the FEM/02.0-init-karma branch.
Exercise: Using Karma with WebpackIn order for Karma to run correctly, it needs to use the karma-webpack preprocessor. After a brief explanation of why the preprocess or is needed, Kent introduces the next exercise which involves using this preprocessor. This exercise starts from the FEM/02.1-add-assertions branch.
Using Karma with Webpack SolutionKent walks through the solution to the Using Karma with Webpack exercise. The code for this solution is on the FEM/02.2-add-webpack branch.
Coverage BasicsCode coverage is the technique of verifying that code in the application has been “covered” by a test. Kent explains how code coverage is implemented and the background behind the tooling. He also talks about the challenges tools like Babel introduce when using instrumenting code coverage techniques.
Exercise: Code CoverageKent walks through an exercise which adds code coverage to the Todo application. He talks about the need for configuring the environment variables and supplying the coverage reporters. The solution for this exercise is on the FEM/02.3-add-coverage branch.
Exercise: Coverage ThresholdsCoverage thresholds allow developers to indicate amount of statements, branches, functions, and lines that should be covered in an application. In this exercise, Kent modifies the Karma config file to include these thresholds in the coverage reports. The solution to this exercise is on the FEM/02.4-cover-everything branch.
Exercise: ES6ifyKent briefly walks through the ES6ify exercise which includes exporting a default View object from the view.js module and using import statements instead of require statement. Import statements allow developers to specify the exact object(s) they wish to import from a module rather than requiring the entire module. The code for this exercise is on the FEM/03.0-es6ify branch.
Tree ShakingTree shaking is the process of excluding exports from modules that are not used in the application. This “dead code” is then uglified and removed. Tree shaking only works with ES6 modules and can be executed statically when the application is bundled.
Exercise: Adding Tree ShakingIn this exercise, you will observe the tree shaking process. The “log” and “leftPad” modules will be removed from the application where they aren’t being used. Kent first takes a look at the application bundle in it’s current form. They then talks through how tree shaking will analyze the code and removed the unused modules. The solution to this exercise can be found on the FEM/04.0-tree-shaking branch.
Code SplittingLarge applications often contain modules that are not required initially. Code splitting is the process of separating out lower priority modules to make the application bootstrapping faster. These modules can then be lazy-loaded once they are needed. Kent introduces the concept of code splitting and talks about why it can be beneficial.
Exercise: Using System.import()In this exercise, you will use the ES6 System.import API to implement code splitting. This new API will lazy-load code only when it’s needed in the application rather than during application startup. Kent gives a few hints and then lets the audience work on the exercise. Note: this exercise begins on the FEM/05.0-code-splitting branch
Using System.import() SolutionKent walks through the solution to the Using System.import() exercise. The solution to this exercise is on the FEM/05.1-code-splitting branch.
Commons ChunkingCommons chunking is useful when only part of a codebase is updated regularly. Non-updated modules can be cached so users do not have to reload the entire codebase when updates are made. They only reload the updated modules.
Exercise: Adding Commons Chunking Part 1This three-part exercise will add commons chunking to the Todo application. In the first part, Kent adds the CommonsChunk Webpack plugin to the application and begins configuring the chunking for the vendor CSS code. He also explains how to make the bundle.js filename dynamic.
Exercise: Adding Commons Chunking Part 2Kent continues walking through the commons chunking exercise. He troubleshoots some issues that arise with the test scripts by conditionally chunking based on the environment. He then spends some time answering a few audience questions.
Exercise: Adding Commons Chunking Part 3Kent concludes the commons chunking exercise by adding unique ID’s for each asset. Once these ID’s are added, the index.html file needs to be dynamically updated with these new names whenever the application is built. Kent adds the HTMLWebpack Plugin and configures Webpack to inject the generated bundle.js file into the <head> section of index.html. The final solution to this exercise is on the FEM/06.0-commons-chunk branch.
Exercise: Longterm CachingCurrently all the asset ID’s are regenerated on each build. Only the assets that are updated should be regenerated. This exercise demonstrates how to use the WebpackInlineManifest plugin to solve this issue. This plugin adds a files manifest to the <head> section of the index.html and will only regenerate ID’s for files that were changed. The solution to this exercise is on the FEM/06.1-longterm-caching branch.
Offline with Service WorkersThe Webpack Offline plugin adds offline capabilities through the use of Service Workers. Once the plugin is configured, assets will be cached offline and accessible if there isn’t a network connection. Kent also talks about how to disable this functionality in the development environment since offline caches are not necessary. Code for this example is on the FEM/07.0-offline branch.
Deploying to Surge.shKent adds a deploy script that will upload the application to the static-file host Surge.sh. The deploy script will first build the application and then authenticate the current user with Surge.sh. Once the application is uploaded, Kent demonstrates the file caching and Service Worker functionality. The code for this solution is on the FEM/07.1-deploy-surge branch.
ResourcesKent wraps up the workshop by sharing a few links to some resources. These resources can be found in the workshop slide deck.