不同文件引入相同文件是否会出重复打包?

比如说我有2个公共文件commonA,commonB。
在文件A中引入了commonA,文件B中将两个文件都引入了但是只用了commonB,
这样是否会出现重复打包导致包变大的情况?

阅读 5k
3 个回答

不会的,webpack 会分析包依赖的。

当使用文件A 中调用 require(commonB) 时,只是说明文件 A 需要使用 commonB 的某些功能,并不是把 commonB 的内容直接复制粘贴到了文件 A 里面。

通过 webpack2 的 treeshaking 还可以把 commonB 中没有用到的内容去掉。如果 A 使用了 commonB 的 1 3 7 函数,而文件 B 使用了 5 9 函数,那么通过 treeshaking 打包的最终结果只有 1 3 5 7 9 函数,其余没有用到的都不会打包进去。

webpack.optimize.CommonsChunkPlugin抽取公共chunks分很多种情况,下面随便说几种最常见的:

情况一:

   entry: {
      page1: './src/A.js',
      page2: './src/B.js'
   },

A.js和B.js都引用了commonA,commonB。
那么commonA,commonB会被合并成一个公共js抽取出来.

情况二:

   entry: {
      page1: './src/A.js',
      page2: './src/B.js',
      page3: './src/C.js'
   },

A.js和B.js都引用了commonA,commonB,但是C.js没引用commonA,commonB
此时虽然commonA,commonB是A.js和B.js的公共文件,但是C.js没引用,打包你会发现根本不会从A.js和B.js中抽取commonA,commonB。。。

此时需要修改webpack.optimize.CommonsChunkPlugin加上minChunks:

new webpack.optimize.CommonsChunkPlugin({ name: 'common', minChunks: 2 })

这样表示只要被引用2次及以上的chunks都会被当做公共模块抽取,这样C.js没引用也没关系了。

**

情况三:

**

   entry: {
      page1: './src/A.js',
      page2: './src/B.js',
      page3: './src/C.js',
      'vendor': ['jquery','vue','other']
   },

可以在entry中手动指定要抽取的公共chunks,这样即使A.js,B.js,C.js都不引用这些指定的chunks,webpack打包时也会抽取它们变成一个公共模块。

再深入一点:

new webpack.optimize.CommonsChunkPlugin({ name: 'common', minChunks: 2 })

情况一:如果name在webpack.config的entry配置项中没有指定,比如我们上面的entry中现在是没写这个common入口的,那么默认common会是所有入口的公共文件,包括被调用了2次以上的commonA,commonB,生成一个common.js

new webpack.optimize.CommonsChunkPlugin({ name: 'manifest', chunks: ['common'] })

这样再来一次,manifest也没在entry中指定, 那么就是从common.js和其他入口js中抽取公共文件,这个公共文件就是一些webpack的打包运行程序文件了- -

情况二:

new webpack.optimize.CommonsChunkPlugin({ name: ['common', 'vendor'], minChunks: 2 })

现在name是一个数组,里面有一个在entry中指定了的vendor,还有一个没指定的common
common上面已经说过了,vendor是已经指定的,会单独把那些指定的公共chunks打包成一个vendor.js,vendor.js里的内容是不需要引用也会被抽离了,这个上面也说过了- -

最后自己多探索吧- -vendor+manifest是一种打包方式,DLL又是一种把vendor+manifest中的vendor不打包的方式,还有externals直接引用vendor中的内容不打包的方式等等。。

webpack CommonsChunkPlugin 插件能帮你找到公共的代码,抽离到common.js 中。

var webpack = require('webpack');

module.exports = {

    entry: {
        'main':'./src/main.js',
        'user':['./src/login.js','./src/reg.js'],
        'index':['./src/index.js']
    },

    output:{
        path: __dirname+'/build/js', 
        filename:'[name].js'
    },

    plugins:[

        // 提供公共代码
        new webpack.optimize.CommonsChunkPlugin({
            name:'common'
        })
    ]
};
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题