webpack3插件CommonChunkPlugin分离ElementUI和Echarts

Vue单页面应用,按照webpack3默认打包生成的vendor.js过于巨大,有1.5M左右(内网环境不考虑CDN引入的做法).想法是将ElementUI和Echarts这2个第三方库各自单独打包成2个js文件。

webpack.prod.conf.js 默认配置如下:
newwebpack.optimize.CommonsChunkPlugin({

  name: 'vendor',

  minChunks(module) {
        return module.resource 
            && /\\.js$/.test(module.resource) &&
            module.resource.indexOf(path.join(\_\_dirname, '../node\_modules')) ===0

        }

}),
newwebpack.optimize.CommonsChunkPlugin({

    name: 'manifest',

    minChunks: Infinity

})
newwebpack.optimize.CommonsChunkPlugin({

    name: 'app',

    async: 'vendor-async',

    children: true,

    minChunks: 3

})

这样的默认配置产生vendor.js过于巨大,改造如下:

newwebpack.optimize.CommonsChunkPlugin({

            name: 'echarts',

            chunks: ['vendor', 'manifest', 'app'],

            minChunks: function(module, count) {

                return module.resource && /echarts/.test(module.resource)

            }

})
newwebpack.optimize.CommonsChunkPlugin({

        name: 'elementui',

        chunks: ['vendor', 'manifest', 'app'],

        minChunks: function(module, count) {

            return module.resource && /element-ui/.test(module.resource)

        }

})

以上两段抽离elementui和echarts的配置加入后,vendor确实变小了,产生了新的elementui.js 和 echarts.js表面上看达到了预期的效果。
发布到服务器,访问系统,控制台报错 webpackjsonp is not defined类似的错误,追查代码发现:在manifest.js中有定义了webpackJsonp的方法,而index.html中不是第一个引入manifest.js文件导致报错。
继续改造:

newHtmlWebpackPlugin({

    filename: config.build.index,

    template: 'index.html',

    inject: true,

    minify: {

        removeComments: true,

        collapseWhitespace: true,

        removeAttributeQuotes: true

    },

    chunks: ['manifest', 'elementui', 'echarts', 'vendor', 'app'], // 加入此行配置

    chunksSortMode: 'dependency'

})

加入上述代码配置,手动调整chunks的引入顺序。发现然并卵!!!

跪求:

1.如何利用CommonsChunkPlugin插件将ElmentUI,Echarts等第三方库和vendor剥离开单独文件存放?
2.或者还有没有其他办法可以将第三方库的文件变小或者拆分成多个小文件?
阅读 5k
1 个回答

经过后续不断尝试,终于解决了问题,现总结下解决方法和步骤:
根据之前的尝试,elementui和echarts第三方库都已经独立打包成各自的js文件,问题是:
1.在打包后的index.html中js文件的引入顺序错误导致报错webpackJsonp方法Undefined,需要 一开始就引入manifest.js文件

new HtmlWebpackPlugin({
            filename: config.build.index,
            template: 'index.html',
            inject: true,
            minify: {
                removeComments: true,
                collapseWhitespace: true,
                removeAttributeQuotes: true
            },
            chunks: ['manifest', 'vendor', 'elementVendor', 'echartsVendor', 'app'], // 更改此行配置,按照依赖关系从左至右书写
            chunksSortMode: 'manual' //更改此行配置,上面的配置无效的原因就是配置了非此值
        })

这样配置后,在打包后的index.html中script引入的js顺序就会按照配置的顺序引入。

2.拆分elementui和echarts的chunk需要修改代码

new webpack.optimize.CommonsChunkPlugin({
    name: 'elementVendor',
    chunks: ['vendor'],
    minChunks(module) {
        return module.resource && /element-ui/.test(module.resource)
    }
})
        
new webpack.optimize.CommonsChunkPlugin({
    name: 'echartsVendor',
    chunks: ['vendor'],
    minChunks(module) {
        return module.resource && /echarts/.test(module.resource)
    }
})

elementui和echarts都来自于node_modules,vendor的chunk过滤了只打包node_modules,所以拆包elementui和echarts的时候,需要设置chunk的来源 chunks: ['vendor']

3.修改manifest

new webpack.optimize.CommonsChunkPlugin({
    name: 'manifest',
    chunks: ['vendor', 'echartsVendor', 'elementVendor', 'app'],
    minChunks: Infinity
})

manifest打包的是一些运行环境,所以需要将之前定义的chunk都设置为manifest的来源

4.注意1中 chunks: ['manifest', 'vendor', 'elementVendor', 'echartsVendor', 'app'] 这段配置引入的先后顺序,因为app.js会用到第三方库,所以app是依赖于第三方库,最后引入。

结语:好了,目前系统已能正常运行,如果有什么好的建议和办法,欢迎留言,希望帮助到大家。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏