记一次webpack打包优化

未进行打包优化的痛点:

  随着项目的不断扩大,引入的第三方库会越来越多,我们每次build的时候会对所有的文件进行打包,耗时必定很长,不利于日常开发。

解决思路:

  第三方库我们只是引入到项目里来,一般不会经常性的去修改源码,一般都是在src目录下编写业务代码,因此可以把第三方依赖和src分开打包。

  每次build的时候我们只需要把之前build好的第三方依赖文件引入到项目中即可,避免了我们每次build的时候都会build第三方依赖。

  当第三方依赖发生改变的时候我们只需要把第三方依赖再build一次就行。

步骤一:构建项目 引入第三方依赖

## 初始化项目

vue init webpack webpack-test
cd dll-test

## 安装基础配置包

npm install

## 安装依赖模块(第三方静态资源)

npm install vuex vue-router axios lodash element-ui  vue-bus iview  --save

安装完成后再package.json中可查看到对应的资源

  main.js中引入第三方资源

import Vue from 'vue'
import App from './App'
import router from './router'
import iView from 'iview'
import VueBus from 'vue-bus'
import lodash from 'lodash'
import vuex from 'vuex'
import ElementUI from 'element-ui'
import axios from 'axios'
import vueRouter from 'vue-router'

Vue.config.productionTip = false

Vue.use(iView)
Vue.use(ElementUI)
Vue.use(VueBus)
Vue.use(lodash)
Vue.use(vuex)
Vue.use(axios)
Vue.use(vueRouter)

看下未优化前的打包时间

22930ms差不多23s,后面项目变大,可达数分钟。 

步骤二:使用DllPlugin插件把第三方依赖抽离出来

  在build文件夹下(根目录,config目录下都可以)创建webpack.dll.conf.js

  内容如下:

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

module.exports = {
  // 你想要打包的模块
  entry: {
    vendor: [
    'axios',
    'iview',
    'vue/dist/vue.esm.js',
    'lodash',
    'vue-bus',
    'element-ui',
    'vue-router',
    'vuex',
    ]
  },
  output: {
    path: path.join(__dirname, '../static/js'), // 打包后文件输出的位置
    filename: '[name].dll.js',
    library: '[name]_library' 
  },
  plugins: [
    new webpack.DllPlugin({
      //生成上文说到清单文件,此处放在当前build文件下面,你也可以放其他地方
      path: path.join(__dirname, '.', '[name]-manifest.json'), 
      name: '[name]_library'
    }),
   //压缩 只是为了包更小一点 
    new webpack.optimize.UglifyJsPlugin({
      compress: {
        warnings: false,
        drop_console:true,
        drop_debugger:true
      },
      output:{
        // 去掉注释内容
        comments: false,
      },
      sourceMap: true
    })
  ]
};

将第三方包抽离出来打包的脚本已经写好了,需要编写一条命令来执行该脚本。

package.json中scripts下加入该命令"dll": "webpack --config build/webpack.dll.conf.js"

  "scripts": {
    "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
    "start": "npm run dev",
    "lint": "eslint --ext .js,.vue src",
    "build": "node build/build.js",
    "dll": "webpack --config build/webpack.dll.conf.js"
  },

  执行下npm run dll 命令将第三方依赖进行打包

可以看到在项目中生成了vendor-manifest.json 和 vendor.dll.js这两个文件

vendor-manifest.json是dllPlugin生成的资源,内容如下:

可以看到,每一个公共库中的js文件,都会有一个对应的资源ID。

同时生成一个打包文件vendor.dll.js,一般是依赖库, 这个文件会暴露给全局一个类似require功能的函数,这个全局函数的名字是可以配置的, 比如,可以为 vendorRequire();

步骤三:引入DllReferencePlugin 插件,让在打包业务组件的时候自动引入第三方依赖打包好的资源,根据vendor-manifest.json中对应的资源id。

DllReferencePlugin 是在打包过程中使用的,在打包业务代码时,每遇到一个在manifest.json中出现的文件,就可以利用上述 vendor.dll.js 暴露的全局函数进行相应处理,而不会把这个文件打包进来。

安装add-asset-html-webpack-plugin插件(将打包好的endor.dll.js加入到生成的html中)

npm add-asset-html-webpack-plugin --save

在webpack.prod.conf.js中加入以下代码:

// 将生成的css js添加到HTML文件
const AddAssetHtmlPlugin = require('add-asset-html-webpack-plugin')

在plugins中加入如下代码:

    // 打包优化  
    new webpack.DllReferencePlugin({
      context: path.resolve(__dirname, '..'), 
      manifest: require('./vendor-manifest.json')
    }),
    //这个主要是将生成的vendor.dll.js文件加上hash值插入到页面中。
    new AddAssetHtmlPlugin([{
      filepath: path.resolve(__dirname,'../static/js/vendor.dll.js'),
      outputPath: utils.assetsPath('js'),
      publicPath: path.posix.join(config.build.assetsPublicPath, 'static/js'),
      includeSourcemap: false,
      hash: true,
    }]),

至此第三方依赖的抽离已完成,我们打包下看看优化后的速度。

npm run build

3187ms  才3s,是不是比未优化的22930ms快多了,在项目越来越大的时候效果更明显。

可以使用npm run build -report 来查看打包的直观图。

这只是一种优化的方式,还有其他可优化的部分,后续继续添加。

赶紧去解决打包时间过长的烦恼吧。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏jojo的技术小屋

如何调试移动端页面

3402
来自专栏jojo的技术小屋

原 如何调试移动端页面

2116
来自专栏jeremy的技术点滴

使用go开发api服务

2943
来自专栏coding for love

在线商城项目02-展示商品列表页面并抽取公共组件

step1:新增存放重构资源的目录 视频提供的重构有点问题,大家可以使用我上传在github上的重构资源。 在根目录下新建一个resources文件夹,用来...

732
来自专栏PHP技术

HTTP/2 服务器推送(Server Push)

HTTP/2 协议的主要目的是提高网页性能。 头信息(header)原来是直接传输文本,现在是压缩后传输。原来是同一个 TCP 连接里面,上一个回应(respo...

3236
来自专栏开源项目

打包巨慢怎么办?这些工具让你爱不释手 | 码云周刊第 58 期

测试小妹 程序测试不通过,已经打回重审啦,你重新再做下单元测试哦… OS : 每次修改一个问题,我都要重新 clean -> 编译打包 -> 上传 fir,最后...

3565
来自专栏酷玩时刻

10分钟用Jitpack发布开源库

项目开发中无论Java web 还是Android 都会用到很多开源库,他们一般通过Maven/Gradle依赖进来的。

803
来自专栏Android相关

Gradle For Android(5)--管理多Module的编译

通常一个多Module的工程会有一个根目录,而它的子目录下包含了所有的Module。为了告诉Gradle这个Project的结构,这个目录下包含了所有要构建的M...

933
来自专栏Young Dreamer

webpack的Hot Module Replacement运行机制

使用webpack打包,难免会使用Hot Module Replacement功能,该功能能够实现修改、添加或删除前端页面中的模块代码,而且是在页面不刷新的前提...

2185
来自专栏编程微刊

微信小程序从零开始开发步骤(二)创建小程序页面

2417

扫码关注云+社区