Extract duplicate javascript code using WebPack CommonsChunkPlugin Extract duplicate javascript code using WebPack CommonsChunkPlugin reactjs reactjs

Extract duplicate javascript code using WebPack CommonsChunkPlugin


Your problem is that your are importing third party libs in each .js/.jsx file without importing it previously in a common file (normally called vendor.js).
If you have this file that import all you dependencies and you include it as entry and to CommonsChunkPlugin, webpack won't include again your libs in your final bundles (home.js and about.js). The technique is called code splitting in webpack docs.

vendor.js (or a name that fit for your case)

import 'react';import 'react-dom';import 'lodash';import 'semantic-ui-react';//... all your npm packages

webpack.config.js

var webpack = require('webpack');var path = require('path');module.exports = {    context: __dirname,    entry: {        vendor: './assets/js/vendor.js,        home: './assets/js/home.jsx',        about: './assets/js/about.jsx',    },    output: {        path: path.resolve('./assets/bundles/'),        filename: '[name].js',    },    plugins: [        new webpack.optimize.CommonsChunkPlugin({            name: 'vendor',            minChunks: Infinity        }),    ],    //Rest of Your config ...};

index.html

<body>    <!-- AFTER YOUR HTML CODE -->    <script type="text/javascript" src="/assets/bundles/vendor.js"></script>    <script type="text/javascript" src="/assets/bundles/home.js"></script>    <script type="text/javascript" src="/assets/bundles/about.js"></script></body>


Check webpack code splitting docs:


I managed to solve the problem by adding a common chunk to plugins. So final webpack config is :

var path = require("path");var webpack = require('webpack');var BundleTracker = require('webpack-bundle-tracker');module.exports = {    context: __dirname,    entry: {        react: ["react", "react-dom"],        home: './assets/js/home.jsx',        about: './assets/js/about.jsx',    },    output: {        path: path.resolve('./assets/bundles/'),        filename: "[name].js",    },    plugins: [        new BundleTracker({filename: './webpack-stats.json'}),        new webpack.optimize.CommonsChunkPlugin({            name: 'react',            filename: '[name].js',            minChunks: Infinity,        }),        new webpack.optimize.CommonsChunkPlugin({            name: 'common',            chunks: ['home', 'about'],            filename: '[name].js',        }),    ],    module: {        rules: [            {                test: /\.jsx?$/,                 exclude: /node_modules/,                loader: 'babel-loader',                options: {                     plugins: [                      ["lodash", { "id": ["semantic-ui-react"] }]                    ],                    presets: ["es2015", "react"]                }            },        ],    },    resolve: {        modules: ['node_modules', 'bower_components'],        extensions: ['*', '.js', '.jsx']    },};

And now bundle analyzer output is like this:

analyzer output

As it's shown in the picture, common semantic-ui-react and lodash libraries are now just in common bundle and not duplicated anymore.