Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Webpack exclude entries for CommonsChunkPlugin

I am trying to set up webpack production configuration. All looks well. However, I realized that while using the commons chunk plugin, it covers all the files in common as expected. What I want to do is, separation of common library modules and common application modules. My config file is :

module.exports = {
  entry: {
    lib: ["react", "react-dom"],
    app: "./ui-v2/app/app.js",
    app2: "./ui-v2/app/app2.js"
  },
  output: {
    path: path.join(__dirname, "target/ui/v2"),
    filename: "/app/[name].[chunkhash].min.js"
  },
  module: {
    loaders: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: "babel-loader"
      },
      {
        test: /\.(png|jpg|svg)/,
        loader: "file-loader?name=img/[name].[hash].[ext]"
        // loaders: ["url", "image-webpack"]
      },
      {
        test: /\.scss$/,
        loader: ExtractTextPlugin.extract("style-loader", "css-loader!autoprefixer-loader!sass-loader", {
          publicPath: __dirname
        })
      },
      {
        test: /\.(woff|woff2|ttf|eot)$/,
        loader: "file-loader?name=fonts/[name].[hash].[ext]"
      }
    ]
  },
  plugins: [
    clean,
    new webpack.optimize.CommonsChunkPlugin("common", "app/common.[chunkhash].js"),
    new webpack.ProvidePlugin({
      React: "react",
      ReactDOM: "react-dom",
      $: "jquery",
      _: "lodash"
    }),
    new webpack.optimize.UglifyJsPlugin({
      compress: {
      warnings: false
      sourceMap: true
    },
    mangle: {
    except: ["exports", "import", "$", "_", "require", "React", "ReactDOM"]
    }
    }),
    new ExtractTextPlugin("styles/[name].[contenthash].css"),
    new Manifest()
  ]
}

Basically I have 3 modules in the app; app.js, app2.js and a common component user.js.

What I want to achieve is to bundle all library related files like react, react-dom, lodash, etc in a lib bundle, and common application components like user.js in a common bundle. In order to do this, I thought there might be an option to exclude the files that I don't want them to go to "common" file. If I use this output, what is the point for long term caching files for library bundles because whenever I get a common component in my project, they will go into the common bundle and the content hash will be different, but nothing changes in this library files like react, jquery, lodash, etc.

Anyway, what I have at the end of build process is everything still goes into the common bundle and lib has nothing and the file sizes are :

app.<hash>.min.js -> 3.05KB
app2.<hash>.min.js -> 3.05KB
lib.<hash>.min.js -> 165 Bytes (has almost nothing!)
common.<hash>.js -> 678 KB

Is there any way to achieve what I want or what would be the best approach to a production build in similar cases? Thank you!

like image 469
erdysson Avatar asked Jan 22 '16 07:01

erdysson


2 Answers

Its because the first parameter for CommonsChunkPlugin is "common" where it should be "lib". The plugin picks up the entry with a name matching with the value of its first parameter.

A simple example config picked from webpack's wiki -

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")
  ]
};

Note that the "vendor" entry is again specified in CommonsChunkPlugin

like image 164
hazardous Avatar answered Oct 21 '22 23:10

hazardous


You should check out Webpack's DLL Plugin.

https://github.com/webpack/webpack/blob/cb3d8e2097503c7245c5dda5b7a6e9d63421a72b/examples/dll/README.md

With this plugin you bundle up common 3rd party vendor dependencies such as React and friends in a DLL, which is essentially just a JSON Manifest that goes along with your requires wrapped in webpack context and cached to disk.

In your project code, you would have your shared components which depend on React and friends, and you would have your application code which depend on your shared components as well as react and friends.

Your project would incorporate the DLL Reference plugin as you can see here:

https://github.com/webpack/webpack/blob/cb3d8e2097503c7245c5dda5b7a6e9d63421a72b/examples/dll-user/README.md

This will see to it that your shared components and your application code pull React and other 3rd party modules from the same DLL bundle. This can help improve build times and the performance of the dev server and hot module reloading.

like image 45
Jonathan Soeder Avatar answered Oct 21 '22 21:10

Jonathan Soeder