最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Webpack exclude entries for CommonsChunkPlugin - Stack Overflow

programmeradmin1浏览0评论

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!

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!

Share Improve this question asked Jan 22, 2016 at 7:47 erdyssonerdysson 1,49013 silver badges18 bronze badges
Add a comment  | 

2 Answers 2

Reset to default 8

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

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.

发布评论

评论列表(0)

  1. 暂无评论