Learn Webpack

from zero to hero

About this talk

  • What is Webpack?
  • How does it work?
  • Config file structure
  • Development environment
  • Deploy to production
  • Questions & Answers

Play with it!

Yet another module bundler

Webpack highlights

  • Split the dependency tree into chunks loaded on demand
  • Suited for big projects (SPAs)
  • Usage of loaders
  • Extensibility via plugins
  • Hot Module Replacement

How does it work?

Extends node.js require()

Module bundling

var module = require("./modules.js"); // CommonJS
define(["amd-module", "../file"], function(amdModule, file) {
    require(["big-module/big/file"], function(big) {
        var stuff = require("../my/stuff");
    });
}); // AMD
import {Module} from './modules'; // ES2015

Loaders can be used to preprocess files

require("coffee!./cup.coffee"); // directly
require('./cup'); // or, by configuration

Not only JS!

You can load almost anything

html, scss, images...

Structure of webpack.config

Basic configuration

module.exports = {
  context: __dirname + "/src",
  entry: "./index.js",
  output: {
      path: __dirname + "/dist",
      filename: "bundle.js"
  }
};

webpack.config.js

Basic configuration

{
  "name": "webpack-html5spain",
  "version": "0.0.1",
  "description": "An example repository for webpack newbies",
  "main": "src/index.js",
  "scripts": {
    "start": "webpack"
  },
  "devDependencies": {
    "webpack": "^1.12.2"
  }
}

package.json

Entry points

{
  context: __dirname + "/src",
  entry: {
    home: "./home",
    user: ["./user", "./account"]
  },
  output: {
      path: __dirname + "/dist",
      filename: "[name].bundle.[hash].js"
  }
}

webpack.config.js

Configuring loaders

module: {
    loaders: [{
      test: /\.js$/,
      include: [
        __dirname + "/src"
      ],
      loader: "babel-loader"
    }]
},

webpack.config.js

Loading styles

module: {
loaders: [{
  test: /\.css$/,
  include: [
    __dirname + "/src"
  ],
  loader: "style-loader!css-loader"
    }]
}

webpack.config.js

Using plugins

var ExtractTextPlugin = require('extract-text-webpack-plugin');

module.exports = {
  ...

  plugins: [
    new ExtractTextPlugin("[name].css"),
    new webpack.optimize.UglifyJsPlugin({
      compress: {
        warnings: false
      }
    }),
    new webpack.DefinePlugin({
      'process.env': {
          'NODE_ENV': JSON.stringify(process.env.NODE_ENV),
       }
    })
  ]
};

webpack.config.js

Code splitting

module.exports = {
    context: __dirname + "/src",
    entry: {
        A: "./a",
        B: "./b",
        C: "./c",
    },
    ...
    plugins: [
        new CommonsChunkPlugin("commons", "commons.js", ["A", "B"])
    ]
};

webpack.config.js

Code splitting

var webpack = require("webpack");

module.exports = {
  entry: {
    app: "./app.js",
    vendor: ["jquery", "underscore", ...],
  },
  output: {
    filename: "bundle.js"
  },
  plugins: [
    new webpack.optimize.CommonsChunkPlugin(
        /* chunkName= */"vendor", 
        /* filename= */"vendor.bundle.js"
    )
  ]
};
<script src="vendor.bundle.js"></script>
<script src="bundle.js"></script>

webpack.config.js

index.html

Conditional configurations

var TARGET = process.env.TARGET;

var mergeConfig = merge.bind(null, {
  entry: [path.join(ROOT_PATH, 'app/index.js')]
  ...
});

if(TARGET === 'build') {
  module.exports = mergeConfig({
  ...
  , plugins: [
      new webpack.optimize.UglifyJsPlugin(),
      new webpack.DefinePlugin({
        'process.env': {
          'NODE_ENV': JSON.stringify('production'),
        }
      })
  });
}

if(TARGET === 'dev') {
  module.exports = mergeConfig({
  ...
  , plugins: [
      new webpack.HotModuleReplacementPlugin()
    ]
  });
}

webpack.config.js

Conditional configurations

"scripts": {
    "build": "TARGET=build webpack",
    "start": "TARGET=dev node dev-server/server.js"
}

package.json (conditional config, same file)

"scripts": {
    "build": "webpack --config webpack.pro.config.js",
    "start": "webpack --config webpack.dev.config.js"
}

package.json conditional config, different files)

Webpack dev server

Features

  • Fast! Load bundles in memory.
  • Watch mode with hot reloading
  • Hot replacement of any file types* 

*using the appropriate loaders

Basic configuration

module.exports = {
    ...
    devServer: {
        port: 3000,
        stats: { colors: true },
        inline: true,
        publicPath: "/dist/"
    },
    plugins: [
        new webpack.HotModuleReplacementPlugin()
    ]
};

webpack.config.js

Deploy to production

Questions?

References

Learn Webpack

By Daniel de la Cruz Calvo

Learn Webpack

A brief overview of webpack features for web designers and frontend developers.

  • 1,560