拆分生成文件

目前为止我们只有一个js文件,如果依赖文件更新,则需要整个应用更新。

设置vendor输出

react单独添加一个entry属性vendor

  1. ...
  2. const common = {
  3. entry: {
  4. app: PATHS.app,
  5. vendor: ['react']
  6. // app: PATHS.app
  7. },
  8. output: {
  9. path: PATHS.build,
  10. filename: '[name].js'
  11. },
  12. plugins: [
  13. new HtmlWebpackPlugin({
  14. title: 'Webpack demo'
  15. })
  16. ]
  17. };
  18. ...
  1. [webpack-validator] Config is valid.
  2. Hash: 6b55239dc87e2ae8efd6
  3. Version: webpack 1.13.0
  4. Time: 4168ms
  5. Asset Size Chunks Chunk Names
  6. app.js 25.4 kB 0 [emitted] app
  7. vendor.js 21.6 kB 1 [emitted] vendor
  8. app.js.map 307 kB 0 [emitted] app
  9. vendor.js.map 277 kB 1 [emitted] vendor
  10. index.html 190 bytes [emitted]
  11. [0] ./app/index.js 123 bytes {0} [built]
  12. [0] multi vendor 28 bytes {1} [built]
  13. [36] ./app/component.js 136 bytes {0} [built]
  14. + 35 hidden modules
  15. Child html-webpack-plugin for "index.html":
  16. + 3 hidden modules

app.js并没有小,因为app和vendor之间相同部分并没有合并 如图示例图1

通过CommonsChunkPlugin插件设置

它是一个功能强大的插件,这里只是介绍基础的用法。更多设置

这里需要额外生成一个manifest文件,它能保证webpack在编译时候不去重新编译vendor部分内容。因为如果没有manifest,代码变化会引起hash值变化,vendor里的hash变化就会导致重新编译。

  1. // libs/parts.js
  2. ...
  3. exports.extractBundle = function(options) {
  4. const entry = {};
  5. entry[options.name] = options.entries;
  6. return {
  7. // 定义需要分离的entry,会合并到webpack.config.js中
  8. entry: entry,
  9. plugins: [
  10. new webpack.optimize.CommonsChunkPlugin({
  11. names: [options.name, 'manifest']
  12. })
  13. ]
  14. };
  15. }

还有manifest插件

  1. // webpack.config.js
  2. ...
  3. const common = {
  4. entry: {
  5. app: PATHS.app
  6. // vendor: ['react']
  7. },
  8. ...
  9. };
  10. ...
  11. // Detect how npm is run and branch based on that
  12. switch(process.env.npm_lifecycle_event) {
  13. case 'build':
  14. config = merge(
  15. common,
  16. ...
  17. parts.extractBundle({
  18. name: 'vendor',
  19. entries: ['react']
  20. }),
  21. parts.minify(),
  22. parts.setupCSS(PATHS.style)
  23. );
  24. break;
  25. default:
  26. ...
  27. }
  28. module.exports = validate(config);

执行结果

  1. [webpack-validator] Config is valid.
  2. Hash: 516a574ca6ee19e87209
  3. Version: webpack 1.13.0
  4. Time: 2568ms
  5. Asset Size Chunks Chunk Names
  6. app.js 3.94 kB 0, 2 [emitted] app
  7. vendor.js 21.4 kB 1, 2 [emitted] vendor
  8. manifest.js 780 bytes 2 [emitted] manifest
  9. app.js.map 30.7 kB 0, 2 [emitted] app
  10. vendor.js.map 274 kB 1, 2 [emitted] vendor
  11. manifest.js.map 8.72 kB 2 [emitted] manifest
  12. index.html 225 bytes [emitted]
  13. [0] ./app/index.js 123 bytes {0} [built]
  14. [0] multi vendor 28 bytes {1} [built]
  15. [36] ./app/component.js 136 bytes {0} [built]
  16. + 35 hidden modules
  17. Child html-webpack-plugin for "index.html":
  18. + 3 hidden modules

可以看到app.js明显小了,因为相同部分被合并到了一起, 如图:示例图1 通过require.ensure可以实现动态加载依赖

自动加载依赖到vendor

如果在package.json里已经严格区分了dependenciesdevDependencies,那就可以通过vendor自动加载相关dependencies的依赖。

  1. ...
  2. const pkg = require('./package.json');
  3. ...
  4. const common = {
  5. entry: {
  6. app: PATHS.app,
  7. vendor: Object.keys(pkg.dependencies)
  8. },
  9. ...
  10. }
  11. ...

当然可以配置filter排除不需要的依赖


<<上一节:设置环境变量 >>下一节:为文件名添加hash