Exercise: Adding Commons Chunking Part 1

In notebook:
FrontEndMasters Webpack Deep Dive
Created at:
2017-01-04
Updated:
2017-01-04
Tags:
JavaScript Webpack libraries
Branch 06.0-commons-chunk

First, we need to find the code that doesn't change often. In his app, it's the todomvc-app-css/index.css file. 
Then, in Webpack we need to change the entry point:
  // ****   webpack.config.babel.js   ****

...
module.exports = env => {
  const {ifProd, ifNotProd} = getIfUtils(env)
  const config = webpackValidator({
    context: resolve('src'),
    // 1. change the entry point
    entry: {
      app: './bootstrap.js',
      // 1. ++++ add the vendor entry
      // these contain all the vendor files 
      // we want to chunk
      vendor: ['todomvc-app-css/index.css'],
    },
...
​$ npm run build dev​ 

We get an error: Conflict: Multiple assets emit to the same filename 'bundle.js'

Aside: adding a progress bar to the build

  // ****   webpack.config.babel.js   ****
...
    plugins: [
      new ProgressBarPlugin()
      ],
...
Back to the error ( Conflict: Multiple assets emit to the same filename 'bundle.js'

We have to make the bundle file name unique. We can use a hash or a name for the output:
  // ****   webpack.config.babel.js   ****

    entry: {
      app: './bootstrap.js',
      vendor: ['todomvc-app-css/index.css'],
    },
    output: {
      // 1. ++-- add .[name]
      filename: 'bundle.[name].js',
      path: resolve('dist'),
      pathinfo: ifNotProd(),
    },
Now the output files are named bundle.app.js and bundle.vendor.js, so we would need to update index.html to use these. 
We need one more step, since later we will not be using these names but be using hash to name the files. 

Adding the commons chunk plugin

Require webpack in webpack.config.babel.js: 
  // ****   webpack.config.babel.js   ****

/* eslint no-console:"off" */
const {resolve} = require('path')
// 1. ++++
const webpack = require('webpack')
const ProgressBarPlugin = require('progress-bar-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const webpackValidator = require('webpack-validator')
const {getIfUtils, removeEmpty} = require('webpack-config-utils')


...
  plugins: [
    new ProgressBarPlugin(),
    // 2. ++++ add more 'optimize' plugins from webpack
    // we're telling webpack to create the 
    // common chunks from the vendor files
    new webpack.optimize.CommonsChunkPlugin({
      name: 'vendor',
    })
  ]
At this point bundle.app.js requires the vendor files, but does not include it.

So, still need to add both script tags to index.html:
  <script src="dist/bundle.vendor.js"></script>
<script src="dist/bundle.app.js"></script>

Q&A: Does the order of the plugins matter?

It does sometimes matter. He's pretty sure, though never personally run into a problem with it.