webpack打包优化(VUE Project)

祝你们新年快乐,万事如意,新年发大财😊😊javascript

临近春节,公司不少同事都提早回家过年,剩余人员根据禅道去修改bug,当bug修正完毕之后,咱们须要从新打包给运维,上测试服给测试同事提测,可是因为项目本体比较庞大,因此打包时间太过漫长(二十五分钟以上😭),因此有了打包优化的想法(其实想法早就有了,可是由于平时工做计划比较充实,因此一直没有去完成这个工做),此次正好有时间,因此去从新考虑了这个问题!html

话很少说,直接开始正文吧vue

先给你们看一下项目的目录结构:java

就是正常的项目结构,简单说一下吧:node

  • build文件夹包含的是一些打包配置的一下东西
  • config文件夹是项目的基础配置
  • dist是打包以后的文件
  • node_modules是项目的依赖包
  • src文件夹里面是项目的源码
  • static文件夹里面放的是一些项目使用的静态资源
  • index.html是项目的首页
  • package.json文件是项目的配置json
  • yarn.lock是使用yarn锁定项目用的依赖

优化思路

项目打包时间长,缘由无外乎就是项目总体比较庞大、依赖复杂、组件以前拆分不够合理。jquery

对于这三个问题呢,咱们能够针对下面这几个方面去作一下处理:webpack

  • 对项目进行路由屏蔽,只打包本身须要打包的部分(我司就是好几个项目合并在了一块儿,至于缘由则是 需求相似,因此放在一块儿比较省事 -_-||| 开发过程当中是省了很多事,可是如今同样要还的!!!!)
  • 依赖关系复杂,这里说的是项目中的依赖模块比较多,像咱们如今这个项目,光算依赖包的话就有40+,另一个重要缘由就是组件之间存在相同引用的依赖。解决思路是把项目中重用的依赖抽离出来进行单独打包。
  • 组件在写的过程当中,须要考虑好这个组件的使用方向,以及实现功能,不能混为一谈。

实际操做

有了总体的思路,那么开搞就能够啦 去webpack文档去看了一下有一个DllPlugin,这个插件就是帮助咱们解决问题的关键,下面是我webpack.dll.config的代码:ios

var path = require("path");
var webpack = require("webpack");

function resolve (dir) {
  return path.join(__dirname, '..', dir)
}

module.exports = {
  // 你想要打包的模块的数组
  entry: {
    vendor: ['vue', 'lodash', 'vuex', 'axios', 'vue-router', 'iview', 'element-ui',
      'echarts','xlsx','jquery','vue-fullcalendar','vue-cookie','handsontable']
  },
  output: {
    path: path.join(__dirname, '../dist/vendor-dll-js'), // 打包后文件输出的位置
    filename: '[name].dll.js',
    library: '[name]_library'
    // vendor.dll.js中暴露出的全局变量名。
    // 主要是给DllPlugin中的name使用,
    // 故这里须要和webpack.DllPlugin中的`name: '[name]_library',`保持一致。
  },
  resolve: {
    extensions: ['.js', '.vue', '.json'],
    alias: {
      'vue$': 'vue/dist/vue.esm.js',
      '@': resolve('src'),
    }
  },
  plugins: [
    new webpack.DllPlugin({
      path: path.join(__dirname, '.', '[name]-manifest.json'),
      name: '[name]_library',
      context: __dirname
    }),
    // 压缩打包的文件,与该文章主线无关
    new webpack.optimize.UglifyJsPlugin({
      compress: {
        warnings: false
      }
    })
  ]
};
复制代码

咱们须要将项目中具备重用性的包抽离出来,放在vendor数组里面,而后在下面output里面定义一下打包输出的文件路径,而后在resolve里面配置解析参数,最后定义使用的DllPlugin插件,UglifyJsPlugin是压缩js的插件git

Dllplugin里的path,会输出一个vendor-manifest.json,这是用来作关联id的,打包的时候不会打包进去,因此不用放到static里 而后运行一下 webpack -p --progress --config build/webpack.dll.conf.jsgithub

成功之后,static下会有dll.vendor.js,根目录下会有vendor.manifest.json 各自打开看一下,就会看到依赖库的源码和匹配id

ok,到这里,抽离依赖库的事情就完成了,那么接下来问题就是怎么引用呢,怎么在dev和build跑呢?

这里补了一点dll和commonsChunk概念上的区别,commonsChunk之因此慢和大,是由于每次run的时候,都会去作一次打包,而实际上咱们不会一直去更新咱们引用的依赖库,因此dll的作法就等因而,事先先打包好依赖库,而后只对每次都修改的js作打包。

继续上面的步骤,咱们须要根据生成的json文件去修改webpack.base.config文件:

const manifest = require('../vendor-manifest.json')
......
plugins: [
    new webpack.DllReferencePlugin({
      manifest
    })
  ]
复制代码

而后打开index.html,在底部加上<script src="./static/dll.vendor.js"></script>

执行一下npm run build,一块儿正常的话,表示你的操做是正确的。

升级处理

至此优化的问题基本已经解决了,可是在处理过程当中须要进行复制粘贴,还要对index.html文件进行操做,若是是对于项目不熟悉的人来进行开发项目的话,就会出现一些小的问题,因此我决定继续往下研究一下:

思路仍是上面的思路,咱们下面须要进行的操做呢就是对与以前的处理进行优化,经过配置文件,和命令去实现咱们想要的效果

首先咱们将上面 webpack.dll.config 文件里面的entry配置项拿出来,在config文件夹下新建一个dll.js

module.exports = {
  entry: {
    // 这里的依赖顺序必须是:对象从上往下依赖,数组从右到左依赖(若是互不依赖的能够忽略顺序)
    ui: ['iview', 'element-ui'],
    tool: ['lodash', 'jquery', 'axios', 'vue-fullcalendar'],
    vue: ['vue', 'vuex', 'vue-router', 'vue-cookie'],
    xlsx: ['xlsx'],
    echarts: ['echarts'],
    other: ['handsontable'],
  },
  outFile: '../static/dll'
};
复制代码

这里面其实就是咱们一开始写的entry的配置项,根据这个js去打包的文件有一个顺序,就是我总结的这个:

这里的依赖顺序必须是:对象从上往下依赖,数组从右到左依赖(若是互不依赖的能够忽略顺序)

若是不按照这个顺序去写的话,会出现依赖错误的问题!!!

而后在output里面再进行一下配置:

output: {
    path: path.join(__dirname, dllConfig.outFile), // 打包后文件输出的位置
    filename: '[name].dll.[chunkhash].js',
    library: '[name]_library'
    // 主要是给DllPlugin中的name使用,
    // 故这里须要和webpack.DllPlugin中的`name: '[name]_library',`保持一致。
  },
复制代码

这样在执行webpack -p --progress --config build/webpack.dll.conf.js指令的时候会生成以下:

是否是看到文件后面的hash就一脸懵逼,这怎么办,咱们没有办法去进行复制粘贴了!!(咱们的目的不就是不进行复制粘贴吗 正经脸-_-)

要实现命令操做以后不进行复制粘贴操做就须要使用webpack的 HtmlWebpackPlugin插件

在plugins里面配置一下HtmlWebpackPlugin

new HtmlWebpackPlugin({
  filename: path.join(__dirname, '../', config.dev.index),
  template: 'index.ejs',
  inject: false
}),
复制代码

而后在根目录添加一个index.ejs模版(ejsGitHub地址), index.ejs中代码以下:

<body>
    <div id="app"></div>
    <!-- dll files will be auto injected -->
    <% for (var chunk in htmlWebpackPlugin.files.chunks) { %><script type="text/javascript" src="/<%= htmlWebpackPlugin.files.chunks[chunk].entry %>"></script>
    <% } %>
    <!-- built files will be auto injected -->
</body>
复制代码

最后须要在config文件夹下的index.js进行一下修改: 在dev中添加:index: 'index.html',

项目在执行dev指令或者build指令以前须要先执行:webpack -p --progress --config build/webpack.dll.conf.js 在dll指令结束后 执行其余操做就能够完美的玩耍了😊

总结

至此代码打包优化的整个过程就基本结束了,测试一下,15分钟左右就能够完成打包,比以前打包快了将近10分钟,能够说是很是成功的一次尝试!!

最后祝各位勤劳、睿智、闷骚正念,外表冷漠心里狂热,颜值负分,人设冰点的程序猿们,节日快乐!

相关文章
相关标签/搜索