How to perform Code splitting with CommonsChunkPlugin

129 views Asked by At

This is my current bundle information which i got from bundle analyzer plugin,

Current bundle information

I want to move the jquery to a separate chunk and extract css into a separate single css bundle, is there any other optimization which i can do to reduce my bundle size?

My current webpack is this webpack.base.js

   /**
 * COMMON WEBPACK CONFIGURATION
 */

    const path = require('path');
    const webpack = require('webpack');
   const AddAssetHtmlPlugin = require('add-asset-html-webpack-plugin');
   // const BundleAnalyzerPlugin = require('webpack-bundle- 
   analyzer').BundleAnalyzerPlugin;
   const ExtractTextPlugin = require('extract-text-webpack-plugin');
   const autoprefixer = require('autoprefixer');
   // Remove this line once the following warning goes away (it was meant 
   webpack loader authors not users):
   // 'DeprecationWarning: loaderUtils.parseQuery() received a non-string 
   value which can be problematic,

   be replaced with getOptions()
   // in the next major version of loader-utils.'
   process.noDeprecation = true;
const environment = require('../../environments/environment');
let publicDeployPath = '/';
const loaderOptions = {};
if (!environment.isLocal) {
  publicDeployPath = environment.blobContainerPath;
  loaderOptions.root = environment.blobContainerPath;
  loaderOptions.minimize = true;
}

     module.exports = (options) => ({
    entry: options.entry,
    output: Object.assign({ // Compile into js/build.js
    path: path.resolve(process.cwd(), 'build'),
    publicPath: publicDeployPath,
    }, options.output), // Merge with env dependent settings
    module: {
    rules: [
      {
        test: /\.js$/, // Transform all .js files required somewhere with 
       Babel
        use: {
          loader: 'babel-loader',
          options: options.babelQuery,
        },
      },
      {
        test: /\.jsx$/, // Transform all .js files required somewhere with 
           Babel
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          options: options.babelQuery,
        },
      },
      {
        // Preprocess our own .css files
        // This is the place to add your own loaders (e.g. sass/less etc.)

        test: /\.css$/,
        // exclude: /node_modules/,
        loader: ExtractTextPlugin.extract({
          fallback: 'style-loader',
          use: [{
            loader: 'css-loader',
            options: loaderOptions,
          }, {
            loader: 'postcss-loader',
            options: {
              plugins: () => [autoprefixer()],
            },
          },
          ] }, true),
      },
      // {
      //   // Preprocess 3rd party .css files located in node_modules
      //   test: /\.css$/,
      //   include: /node_modules/,
      //   loader: ExtractTextPlugin.extract({
      //     fallback: 'style-loader',
      //     use: [{
      //       loader: 'css-loader',
      //       options: loaderOptions,
      //     },
      //     ] }, true),
      // },
      {
        test: /\.mp3$/,
        loader: 'url-loader?limit=10000&mimetype=audio/mpeg',
        options: {
          publicPath: publicDeployPath,
        },
      },
      {
        test: /\.(eot|svg|otf|ttf|woff|woff2)$/,
        loader: 'file-loader',
        options: {
          publicPath: publicDeployPath,
        },
      },
      {
        test: /\.(jpg|png|gif)$/,
        use: [
          'file-loader',
          {
            loader: 'image-webpack-loader',
            options: {
              publicPath: publicDeployPath,
              progressive: true,
              optimizationLevel: 7,
              interlaced: false,
              pngquant: {
                quality: '65-90',
                speed: 4,
              },
            },
          },
        ],
      },
      {
        test: /\.html$/,
        use: 'html-loader',
      },
      {
        test: /\.json$/,
        use: 'json-loader',
      },
      {
        test: /\.(mp4|webm)$/,
        use: {
          loader: 'url-loader',
          options: {
            limit: 10000,
          },
        },
      },
    ],
   },
   plugins: options.plugins.concat([
    new webpack.ProvidePlugin({
      // make fetch available
      fetch: 'exports-loader?self.fetch!whatwg-fetch',
    }),
    // new BundleAnalyzerPlugin(),
    new webpack.ProvidePlugin({
      $: 'jquery',
      jQuery: 'jquery',
      'window.jQuery': 'jquery',
      'root.jQuery': 'jquery',
    }),
    // Always expose NODE_ENV to webpack, in order to use 
       `process.env.NODE_ENV`
     // inside your code for any environment checks; UglifyJS will 
     automatically
    // drop any unreachable code.
    new webpack.DefinePlugin({
      'process.env': {
        NODE_ENV: JSON.stringify(process.env.NODE_ENV),
      },
    }),
    new AddAssetHtmlPlugin({ filepath: path.resolve(process.cwd(), 
     'app/vendor/VidyoConnector.js'), hash: true }),
    new webpack.NamedModulesPlugin(),
  ]),
  resolve: {
    modules: ['app', 'node_modules'],
    extensions: [
      '.js',
      '.jsx',
      '.react.js',
    ],
    mainFields: [
      'browser',
      'jsnext:main',
      'main',
    ],
  },
  devtool: options.devtool,
  target: 'web', // Make web variables accessible to webpack, e.g. window
  performance: options.performance || {},
  node: {
    fs: 'empty',
      },
      });

webpack.production.js

    // Important modules this config uses
const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const pathsToClean = [
  'build',
];
const cleanOptions = {
  root: path.resolve(__dirname, '..'),
  verbose: true,
  dry: false,
  allowExternal: true,
};
module.exports = require('./webpack.base.babel')({
  // In production, we skip all hot-reloading stuff
  entry: [
    path.join(process.cwd(), 'app/app.js'),
  ],
  // Utilize long-term caching by adding content hashes (not compilation hashes) to compiled assets
  output: {
    filename: '[name].[chunkhash].js',
    chunkFilename: '[name].[chunkhash].chunk.js',
  },

  plugins: [
    new webpack.optimize.ModuleConcatenationPlugin(),
    new webpack.optimize.CommonsChunkPlugin({
      name: 'reactjs',
      filename: 'reactjs.[chunkhash].js',
      minChunks: (module) => (
        // If module has a path, and inside of the path exists the name "somelib",
        // and it is used in 3 separate chunks/entries, then break it out into
        // a separate chunk with chunk keyname "my-single-lib-chunk", and filename "my-single-lib-chunk.js"
        module.resource && (/react/).test(module.resource)
      ),
    }),
    new CleanWebpackPlugin(pathsToClean, cleanOptions),
    new ExtractTextPlugin({ filename: 'style.[hash].css', disable: false, allChunks: true }),
    new webpack.optimize.CommonsChunkPlugin({
      name: 'vendor',
      filename: 'vendor.[chunkhash].js',
      minChunks: (module) => (
        // If module has a path, and inside of the path exists the name "somelib",
        // and it is used in 3 separate chunks/entries, then break it out into
        // a separate chunk with chunk keyname "my-single-lib-chunk", and filename "my-single-lib-chunk.js"
        module.context && module.context.includes('node_modules')
      ),
    }),
    new webpack.DefinePlugin({
      'process.env.NODE_ENV': JSON.stringify('production'),
    }),
    // Minify and optimize the index.html
    new HtmlWebpackPlugin({
      template: 'app/index.html',
      minify: {
        removeComments: true,
        collapseWhitespace: true,
        removeRedundantAttributes: true,
        useShortDoctype: true,
        removeEmptyAttributes: true,
        removeStyleLinkTypeAttributes: true,
        keepClosingSlash: true,
        minifyJS: true,
        minifyCSS: true,
        minifyURLs: true,
      },
      inject: true,
    }),
    new HtmlWebpackPlugin({  // Also generate a invalid page html
      filename: 'ppVideoInvalid.html',
      template: 'app/ppVideoInvalid.html',
    }),
    new HtmlWebpackPlugin({  // Generate a test client html
      filename: 'testClient.html',
      template: 'app/TestInterface/testClient.html',
    }),
  ],

  performance: {
    assetFilter: (assetFilename) => !(/(\.map$)|(^(main\.|favicon\.))/.test(assetFilename)),
  },
});
0

There are 0 answers