webpack3.x升级到4.x后的包大小优化。打包分析在优化之前,我们需要知道项目的打包情况。npmrunbuild后,webpack会把打包信息打印到终端,像这样:可以看到有几个大文件,但是不清楚包含了哪些模块,哪些模块适合单独提取,哪些模块不适合对于提取,这个时候就需要用到包分析工具了。以下内容摘自webpack文档:BundleAnalysis-BundleAnalysis一旦开始拆分代码,分析输出以检查模块的最终位置可能很有用。官方分析工具是一个很好的起点。还有一些其他社区支持的选项:webpack-chart:用于webpack统计的交互式饼图webpack-visualizer:可视化和分析您的包以查看哪些模块正在占用空间,哪些可能是重复的。webpack-bundle-analyzer:一个插件和CLI实用程序,将包内容表示为方便的交互式可缩放树图。webpackbundleoptimizehelper:该工具将分析您的包并为您提供可操作的改进建议以减少包的大小。bundle-stats:生成包报告(包大小、资产、模块),并比较不同版本之间的结果。这里我们使用了webpack-bundle-analyzer这个交互式可缩放的树形图,这样我们可以更直观的了解打包情况。安装插件npmi-Dwebpack-bundle-analyzerimportpluginconstBundleAnalyzerPlugin=require("webpack-bundle-analyzer").BundleAnalyzerPlugin;module.exports={插件:[newBundleAnalyzerPlugin()],};然后我们再次尝试构建以下内容,看看会发生什么。npmrunbuild插件会自动在浏览器中打开链接:http://127.0.0.1:8888/,其中以交互式可缩放树状图展示了当前项目的打包,可以清晰的看到其中包含的模块每个文件,并有针对性地处理它们:代码拆分分析上面的树形图?总结了以下几个可以优化的点:提取两个入口的公共依赖,如:Element-UI、Vue全家桶、Lodash等;提取只有一个组件使用的依赖,如:Swiper的其他依赖,将optimization.splitChunks属性的默认值单独删除,然后在cacheGroups中配置如下:webpack.prod.js//..constwebpackConfig=merge(baseWebpackConfig,{//..{-chunks:"async",-minSize:30000,-maxSize:0,-minChunks:1,-maxAsyncRequests:5,-maxInitialRequests:3,-automaticNameDelimiter:"~",-automaticNameMaxLength:30,-name:true,cacheGroups:{+common:{+test:/[\\/]node_modules[\\/]/,+name:'vendors-common',+minSize:0,+minChunks:2,//被至少2个chunk引用+chunks:'initial',+priority:1//优先级,默认为0,可以为负+},+other:{+test:/[\\/]node_modules[\\/]/,+name:'vendors-other',+chunks:'initial',+priority:-10+},-defaultVendors:{-test:/[\\/]node_modules[\\/]/,-优先级:-10-},默认:{minChunks:2,priority:-20,reuseExistingChunk:true}}}}//..});//..module.exports=webpackConfig;我们再build一下,看npmrunbuild可以看到几个包含node_modules的大文件被拆分出来了:vendors-common.***.js(两个入口的共同依赖,引用了两次以上)vendors-other.***.js(其他依赖,在单个入口中使用,作为全局使用)5.***.js(swiper,在单个组件中引入的依赖,webpack会自动提取)在其他项目中使用的依赖并自动拆分出来,文件为smaller并没有在上图中体现出来。比较代码拆分前后两个入口加载文件的大小:拆分前:_app(2.5MB)qi(1.04MB)拆分后:_app(1.88MB)qi(1.04MB)_entry2没有变化,大小为条目1加载的文件减少了0.62MB,接近25%。当然,这是没有gzip压缩的情况,如果在nginx服务器上开启gzip压缩,整体体积会更小。这里是如果你想单独提取一些依赖,你可以看看这个官方例子。如果您的项目依赖较少,您可以根据自己喜欢的组合手动拆分项目依赖。在多个文件中缓存(cache)当访问一个网页时,所请求的文件会存储在浏览器的缓存中。下次访问时,如果满足HTTP缓存机制,浏览器就可以从缓存中读取文件,而无需从服务器读取,甚至不需要发出请求,可以显着提高加载速度,减少流量消耗。但是如果重建项目,用户浏览器的缓存还没有过期,又想快速更新,保留一些缓存怎么办?有关详细信息,请参阅HTTP缓存-丢弃和更新缓存的响应。对于这个webpack打包,有几点需要优化:控制输出文件的名称-contentHash提取运行时代码-runtimeChunk指定模块标识符-moduleIdwebpack.prod.js//..constwebpackConfig=merge(baseWebpackConfig,{//..output:{//..-filename:utils.assetsPath('js/[name].[chunkhash].js')+//根据文件内容hash生成,当文件内容改变时,hash也会相应变化+filename:utils.assetsPath('js/[name].[contenthash].js')},optimization:{+//runtimeblock包含模块之间的引用关系,Extractitasa单独的文件,当引用关系发生变化时,不会引起不相关文件内容的变化。其他模块(默认ID值按照解析顺序递增)+moduleIds:'hashed'//...}});//..module.exports=webpackConfig;详见webpackDocumentation-Cache(缓存)总结在代码拆分的过程中,做了一些尝试,根据已有的配置(比如Element-UI,因为不经常改动,文件较大)分离指定的依赖),但是会Destroyingtheexistingsplit,多次尝试无果,最接近的是这个,entry1会把它包含在文件中,但是entry2不会,当前项目有两个entry:使用如下配置://..constwebpackConfig=merge(baseWebpackConfig,{//..优化:{splitChunks:{cacheGroups:{common:{-测试:/[\\/]node_modules[\\/]/,+测试:/[\\/]node_modules[\\/]((?!(element-ui)).)+[\\/]/,name:'vendors-common',minSize:0,minChunks:2,//被至少2个块引用chunks:'initial',priority:1//优先级,默认为0,可以为负},other:{-测试:/[\\/]node_modules[\\/]/,+测试:/[\\/]node_modules[\\/]((?!(element-ui)).)+[\\/]/,name:'vendors-other',chunks:'initial',优先级:-10},+'element-ui':{+test:/[\\/]node_modules[\\/](element-ui)[\\/]/,+name:'vendor-element-ui',+chunks:'initial',+priority:-15+},default:{minChunks:2,priority:-20,reuseExistingChunk:true}}}}//..});//..module.exports=webpackConfig;后续有解决方案后会更新。包装尺寸的优化到此告一段落。下篇文章会讲到如何优化打包速度
