浅谈webpack优化

移动端项目,须要严格控制包的大小,否则影响用户体验,因此须要对webpack进行优化
本文档主要介绍本身初次体验webpack优化的一些知识点。css

敲黑板

包分析工具

便于分析哪些包有问题,哪些包体积过大等现象
vue-cli内置包分析工具vue

// webpack.prod.conf.js
if (config.build.bundleAnalyzerReport) {
  const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
  webpackConfig.plugins.push(new BundleAnalyzerPlugin())
}

能够经过在package.json添加命令开启包分析工具,默认8888端口node

"analyze": "NODE_ENV=production npm_config_report=true npm run build"

vue-cli 默认配置 打包思路

vue-cli默认配置将node_modules里的依赖都打进vendor中,有一些弊端webpack

  • 引入的模块越多,vendor文件越大
  • 提取公共文件目的是,一次打包,以后文件尽量被浏览器缓存下来,不能每次打包都去改变hash值
  • 这个vendor文件将node_modules中全部依赖都进行抽离,以后维护若是添加新的模块或者删除一些没有用的模块,那么vendor的hash值会发生变化,不利于浏览器缓存

项目中,我主要经过CommonsChunkPlugin插件对webpack进行优化,将原本1M的包,最后只有300+kbweb

CommonsChunkPlugin

  • 会将项目中引入的node_modules中的模块抽离出来
new webpack.optimize.CommonsChunkPlugin({
  name: 'vendor',
  minChunks: function (module) {
    // this assumes your vendor imports exist in the node_modules directory
    return module.context && module.context.includes('node_modules');
  }
});
  • 提取公共模块,若是没有添加或者删除公共模块,则hash值不变,首次加载被浏览器缓存
  • 尽可能将项目中不变的依赖包 抽离出一个文件,保证后续引入别的依赖包,此文件hash值不变化
  • 下图中将vue vuex vue-router vant继续抽离出一个文件

代码以下,两种写法vue-router

// 方法一 对module.context进行过滤
new webpack.optimize.CommonsChunkPlugin({
    names: "common",
     minChunks: function(module, count) {
       if (module.resource && /^.*\.(css|scss)$/.test(module.resource)) {
         return false;
       }
       return module.context && 
         (module.context.includes("vue") ||
         module.context.includes("vant") ||
         module.context.includes("vuex") ||
         module.context.includes("vue-router"));
     }
   }),
// 方法二
// webpack.base.conf 文件  将公共模块,写入入口
entry: {
   app: './src/main.js',
   common: ['vue', 'vuex', 'vue-router', 'vant']
},
// webpack.prod.conf 
new webpack.optimize.CommonsChunkPlugin({
   name: 'common',
   minChunks: Infinity // 除了入口的模块,其余模块都不打包进入common
}),

修改router,目的修改打包以后的js文件,便于跟踪

经过下面对每一个路由进行修改,添加webpackChunkName,打包出来每一个模块的js名称会根据本身设定的来
除此以外,还须要同步修改webpack.prod.conf.jsoutput的配置vuex

output: {
   path: config.build.assetsRoot,
   filename: utils.assetsPath('js/[name].[chunkhash].js'),
   chunkFilename: utils.assetsPath('js/[name].[chunkhash].js')
 },
component: () => import(/* webpackChunkName: "home" */ '@/containers/home.vue'),

image.png

对minChunks理解

当entry属性的值为对象时,做为多个入口的文件们,每一个都是一个chunkvue-cli

minChunks:number

某个模块最少被多少个入口文件依赖,当大于等于设定的值,就会被打入公共包,小于这个值,该模块就会被和每一个入口打包在一块儿npm

minChunks:infinity

不会把任何依赖的模块提取出来打入公共包json

minChunks:默认值

若是没有设置,则为默认值,只有被全部入口文件所依赖,则提取出来打公共包

代码分割

  • 分离业务代码和第三方库 (vendor)
  • 按需加载 (利用路由中 import() 语法 component: () => import('@/components/Hello'))

    • 首页首次加载的时候若是不须要就不加载,等加载到响应路由再去加载相关资源
    • 减小首屏加载时间
  • 根据模块的相对路径生成一个四位数的hash做为模块id

    • webpack里每一个模块都有一个module id
    • HashedModuleIdsPlugin 模块根据相对路径生成一个四位数hash做为模块id,引入新的模块,不影响module id,只要模块路径不改变
    • new webpack.HashedModuleIdsPlugin()

参考文章

webpack
commonsChunkPlugin
demo

但愿此文对你们有帮助,欢迎吐槽

相关文章
相关标签/搜索