Webpack Deep Dive

Kent C. Dodds

Utah

1 wife, 3 kids

PayPal, Inc.

@kentcdodds

Please Stand...

What this workshop is

  • Migrate existing JavaScript application to Webpack 2
  • Integrate unit testing with Mocha and Karma
  • Utilize features like tree-shaking, code splitting, hashing for long term caching, chunking, Service Worker, and more
  • Deploy the app to surge.sh

What this workshop is not

  • EVERY feature of Webpack and its ecosystem (not writing plugins/loaders)
  • ALL applicable to EVERY application

Requirements

to run the workshop

  1. git
  2. node (version 6)
  3. npm (version 3)

Let's
Get
STARTED!

Setup

git clone https://github.com/kentcdodds/es6-todomvc.git

cd es6-todomvc

npm run setup:fem

npm start

open http://localhost:8080

open http://localhost:8080

Webpack 101

Why does this thing exist?

Webpack vs Grunt/Gulp?

no task runner needed

Dependencies

Loaders

Per-file processing

And hundreds more...

Plugins

Do everything else...

CommonsChunkPlugin

ExtractTextWebpackPlugin

DedupePlugin

PrefetchPlugin

And many more...

Is your setup script done yet?

Let's explore the app

Initializing Webpack

Required config properties

Config Props: entry/output.filename

entry

output

Exercise

  • Add scripts
  • Add webpack.config.js
  • Update index.html

git checkout -f FEM/01.0-add-webpack

Debugging Webpack

node-nightly --inspect 😀

* Now available by default in the latest versions of Node!

You don't need node-nightly anymore

Exercise

  • npm install -g node-nightly
  • Add scripts
  • Update webpack.config.js
  • Try it out!

git checkout -f FEM/01.1-debug-webpack

Bundle everything

From scripts to CommonJS

Exercise

  • require everything in app.js
  • Remove IIFEs
  • Add pathinfo to webpack.config.js
  • Update index.html

git checkout -f FEM/01.2-require-everything

Explicit Dependencies

Architecture FTW

Exercise

  • Update helpers.js to export functions
  • Update app.js to require helpers and export onLoad
  • Update bootstrap.js to require helpers and app.js
  • Don't worry about everything else :)

git checkout -f FEM/01.3-explicit-deps

Transpile

The Babel Loader

Exercise

  • Add babel-loader to webpack.config
  • Create .babelrc
  • Remove 'use strict' from all files

git checkout -f FEM/01.4-transpile

Load CSS

They're just modules...

CSS Loader

body:before {
  content: '😀';
  font-size: 60px;
}

Style Loader

<style>body:before{content:'😀';font-size:60px;}</style>

*at runtime

Exercise

  • Add style-loader and css-loader to webpack.config.js
  • require css files in app.js
  • Remove css files from index.html
  • Move bundle script to <head>

git checkout -f FEM/01.5-css

Hot Module Replacement

Live reload, but much better

bootstrap.js

webpackHotUpdate

Exercise

  • Update bootstrap.js to handle module.hot
  • Add --hot to dev script

git checkout -f FEM/01.6-hmr

Testing with Webpack

Using Karma and Mocha

Init - Exercise

  • Run node_modules/.bin/karma init
  • Update karma.conf.js
  • Update scripts
  • Add controller.test.js

git checkout -f FEM/02.0-init-karma

Assert - Exercise

  • Add chai to frameworks in karma.conf.js
  • Update controller.test.js to use expect

git checkout -f FEM/02.1-add-assertions

Webpack - Exercise

  • export default Controller
  • import Controller from './Controller'
  • Update karma.conf to use karma-webpack

git checkout -f FEM/02.2-add-webpack

Coverage - Exercise

  • Update .babelrc
  • Add karma-coverage config to karma.conf

git checkout -f FEM/02.3-add-coverage

Cover everything - Exercise

  • Update karma.conf:
    • srcGlob
    • add bootstrap.js to excluded files
    • add check to coverageReporter

git checkout -f FEM/02.4-cover-everything

ES6ify ✨ 

Static Modules & more!

Exercise

  • export default View from view.js
  • import View from './view' in app.js
  • etc...

git checkout -f FEM/03.0-es6ify

Tree Shaking 🌲

Save bytes

Tree shaking creates dead code.

-Tobias Koppers

Tree shaking excludes exports from modules where it can be detected the export is not used. Uglify then deletes the dead code.

-me 😉

Exercise

  • Update .babelrc
  • Remove `log` from app.js
  • Observe the tree shaking glory 🌳 🌴 
  • Remove `log` and `padLeft` from helpers.js

git checkout -f FEM/05.0-code-splitting

Code Splitting

Load it when you need it

Exercise

  • Update graph/index.js:
    • Remove `renderGraph` import
    • Add function to use System.import

git checkout -f FEM/05.1-code-splitting

Commons Chunking

App 3

App 4

App 2

App 1

Exercise

  • Update entry to object
  • Update filename
  • Move index.html to src directory
  • Remove bundle.js script in index.html
  • Remove publicPath
  • Add CommonsChunk Plugin
  • Add HtmlWebpackPlugin
  • Update start script

git checkout -f FEM/06.0-commons-chunk

Exercise

  • Add webpack manifest to index.html template
  • Add manifest to CommonsChunkPlugin

git checkout -f FEM/06.1-longterm-caching

Exercise

  • Replace css loader with ExtractTextPlugin.extract
  • Add ExtractTextPlugin to plugins

git checkout -f FEM/06.2-extract-css

Offline

Progressive Web Apps

Exercise

  • Add Offline plugin to webpack.config.js
  • import offline runtime in app.js
  • Add Define plugin to webpack.config.js

git checkout -f FEM/07.0-offline

Deploy

Surge.sh: CDN that's crazy fast

Exercise

  • Run node_modules/.bin/surge token
  • Add scripts/deploy
  • Update .gitignore
  • Update package.json

git checkout -f FEM/07.1-deploy-surge

export SURGE_LOGIN=<your-email>
export SURGE_TOKEN=<your-token>
node_modules/.bin/surge --project dist --domain https://todomvc-<your-name>.surge.sh
SET SURGE_LOGIN=<your-email>
SET SURGE_TOKEN=<your-token>
node_modules/.bin/surge --project dist --domain https://todomvc-<your-name>.surge.sh

*nix

windows

Resources

Thank you!