美文网首页
浅谈webpack优化

浅谈webpack优化

作者: GrowthCoder | 来源:发表于2018-08-09 10:45 被阅读0次

    移动端项目,需要严格控制包的大小,不然影响用户体验,所以需要对webpack进行优化
    本文档主要介绍自己初次体验webpack优化的一些知识点。

    敲黑板

    包分析工具

    vue-cli内置包分析工具

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

    可以通过在package.json添加命令开启包分析工具,默认8888端口

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

    vue-cli 默认配置 打包思路

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

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

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

    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继续抽离出一个文件

    代码如下,两种写法

    // 方法一 对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的配置

    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属性的值为对象时,作为多个入口的文件们,每个都是一个chunk

    minChunks:number

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

    minChunks:infinity

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

    minChunks:默认值

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

    代码分割

    • 分离业务代码和第三方库 (vendor)
    • 按需加载 (利用路由中 import() 语法 component: () => import('@/components/Hello'))
    • 首页首次加载的时候如果不需要就不加载,等加载到响应路由再去加载相关资源
    • 减少首屏加载时间
    • 根据模块的相对路径生成一个四位数的hash作为模块id
      • webpack里每个模块都有一个module id
      • HashedModuleIdsPlugin 模块根据相对路径生成一个四位数hash作为模块id,引入新的模块,不影响module id,只要模块路径不改变
      • new webpack.HashedModuleIdsPlugin()

    参考文章

    webpack
    commonsChunkPlugin
    demo

    希望此文对大家有帮助,欢迎吐槽

    相关文章

      网友评论

          本文标题:浅谈webpack优化

          本文链接:https://www.haomeiwen.com/subject/eljqbftx.html