This course has been updated! We now recommend you take the Webpack 4 Fundamentals course.
Table of Contents
Getting Started with Webpack
Workshop Outline
Kent 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 101
Kent 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 Plugins
Loaders 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 Walkthrough
Kent 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 Webpack
Kent 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 Point
Webpack 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 Validator
Kent 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 Server
Since 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 Configuration
The 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 Maps
Minifying 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.Development vs Production Environments
Since the Webpack config file is a JavaScript file, it can contain conditional logic to run code based on the environment. Kent demonstrates how to pass an env variable into the module to determine if the application is running in development or production. This allows him to alter the way the source maps are generated for each environment.Exercise: Adding Webpack
While 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 Webpack
The “--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.Bundling
Rather than including each JavaScript file in the index.html, Webpack can be used to bundle script files based on CommonJS require statement. Kent adds these require statements to the app.js file and also spends a few minutes explaining the value of using the pathInfo configuration variable. Code for this example is located on the FEM/01.2-require-everything branch.Explicit Dependencies
Kent demonstrates why it’s better to export specific objects from each JavaScript module rather than have it added to the global application object. He uses the CommonJS module syntax for the exports/imports. Code for this example is located on the FEM/01.3-explicit-deps branch.Transpiling with Babel
The first loader Kent uses is the Babel loader. The babel loader will look for any file with a “.js” extension and pipe it though the babel loader. Kent also talks about how to exclude JavaScript files in the node_modules directory. Code for the example is located on the FEM/01.4-transpile branch.Loading CSS
CSS files are considered modules just like JavaScript files. They can be required using the same CommonJS syntax. The Webpack CSS Loader will create a JavaScript module with the CSS and inject it into the DOM at runtime through the Style Loader.Exercise: Using the Style & CSS Loaders
Kent 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 Replacement
Hot 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 Karma
Kent 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 Webpack
In 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 Solution
Kent 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 Basics
Code 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 Coverage
Kent 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.Coverage Exclusions and Webpack Middleware
By default, Karma will run test coverage reports on the JavaScript test files as well as the application code. This can lead to inflated coverage statistics. Kent demonstrates how to exclude certain files from the test coverage reports and also use the webpack-middleware module to hide the default Webpack CLI output.Exercise: Coverage Thresholds
Coverage 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.
Webpack Optimizations
Exercise: ES6ify
Kent 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 Shaking
Tree 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 Shaking
In 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 Splitting
Large 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 branchUsing System.import() Solution
Kent 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 Chunking
Commons 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 1
This 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 2
Kent 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 3
Kent 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 Caching
Currently 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.Exercise: Extracting CSS Part 1
In this exercise, Kent demonstrates how to use the ExtractText Webpack plugin to pull out the CSS code which is currently being injected with JavaScript. This will allow for the CSS file to be cached and eliminate the flash of blank content when the application launches.Exercise: Extracting CSS Part 2
Kent reviews why the CSS is first loaded into a JavaScript module and then extracted with the ExtractText plugin. He then answers a couple more audience questions before concluding the exercise. The solution to this exercise is on the FEM/06.2-extract-css branch.Offline with Service Workers
The 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.sh
Kent 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.Audience Questions and Aphrodite
Kent spends a few minutes answering some final audience questions about how the file-level caching works in tandem with Service Workers. He also explains why he uses the Aphrodite library for working with CSS in JavaScript.Resources
Kent wraps up the workshop by sharing a few links to some resources. These resources can be found in the workshop slide deck.