Webpack的dll功能使用


Posted in Javascript onJune 28, 2018

最近使用Webpack遇到了一个坑。

我们构建前端项目的时候,往往希望第三方库(vendors)和自己写的代码可以分开打包,因为第三方库往往不需要经常打包更新。对此Webpack的文档建议用CommonsChunkPlugin来单独打包第三方库。

entry: {
 vendor: ["jquery", "other-lib"],
 app: "./entry"
}
new CommonsChunkPlugin({
 name: "vendor",

 // filename: "vendor.js"
 // (Give the chunk a different name)

 minChunks: Infinity,
 // (with more entries, this ensures that no other module
 // goes into the vendor chunk)
})

通常为了对抗缓存,我们会给售出文件的文件名中加入hash的后缀——但是——我们编辑了app部分的代码后,重新打包,发现vendor的hash也变化了!

Webpack的dll功能使用

这么一来,意味着每次发布版本的时候,vendor代码都要刷新,即使我并没有修改其中的代码。这样并不符合我们分开打包的初衷。

带着问题我浏览了Github上的讨论,发现了一个神器:dll。

Dll是Webpack最近新加的功能,我在网上并没有找到什么中文的介绍,所以在这里我就简单介绍一下。

Dll这个概念应该是借鉴了Windows系统的dll。一个dll包,就是一个纯纯的依赖库,它本身不能运行,是用来给你的app引用的。

打包dll的时候,Webpack会将所有包含的库做一个索引,写在一个manifest文件中,而引用dll的代码(dll user)在打包的时候,只需要读取这个manifest文件,就可以了。

这么一来有几个好处:

  1. Dll打包以后是独立存在的,只要其包含的库没有增减、升级,hash也不会变化,因此线上的dll代码不需要随着版本发布频繁更新。
  2. App部分代码修改后,只需要编译app部分的代码,dll部分,只要包含的库没有增减、升级,就不需要重新打包。这样也大大提高了每次编译的速度。
  3. 假设你有多个项目,使用了相同的一些依赖库,它们就可以共用一个dll。

如何使用呢?

首先要先建立一个dll的配置文件,entry只包含第三方库:

const webpack = require('webpack');

const vendors = [
 'antd',
 'isomorphic-fetch',
 'react',
 'react-dom',
 'react-redux',
 'react-router',
 'redux',
 'redux-promise-middleware',
 'redux-thunk',
 'superagent',
];

module.exports = {
 output: {
  path: 'build',
  filename: '[name].[chunkhash].js',
  library: '[name]_[chunkhash]',
 },
 entry: {
  vendor: vendors,
 },
 plugins: [
  new webpack.DllPlugin({
   path: 'manifest.json',
   name: '[name]_[chunkhash]',
   context: __dirname,
  }),
 ],
};

webpack.DllPlugin的选项中,path是manifest文件的输出路径;name是dll暴露的对象名,要跟output.library保持一致;context是解析包路径的上下文,这个要跟接下来配置的dll user一致。

运行Webpack,会输出两个文件一个是打包好的vendor.js,一个就是manifest.json,长这样:

{
 "name": "vendor_ac51ba426d4f259b8b18",
 "content": {
  "./node_modules/antd/dist/antd.js": 1,
  "./node_modules/react/react.js": 2,
  "./node_modules/react/lib/React.js": 3,
  "./node_modules/react/node_modules/object-assign/index.js": 4,
  "./node_modules/react/lib/ReactChildren.js": 5,
  "./node_modules/react/lib/PooledClass.js": 6,
  "./node_modules/react/lib/reactProdInvariant.js": 7,
  "./node_modules/fbjs/lib/invariant.js": 8,
  "./node_modules/react/lib/ReactElement.js": 9,
  
  ............

Webpack将每个库都进行了编号索引,之后的dll user可以读取这个文件,直接用id来引用。

Dll user的配置:

const webpack = require('webpack');

module.exports = {
 output: {
  path: 'build',
  filename: '[name].[chunkhash].js',
 },
 entry: {
  app: './src/index.js',
 },
 plugins: [
  new webpack.DllReferencePlugin({
   context: __dirname,
   manifest: require('./manifest.json'),
  }),
 ],
};

DllReferencePlugin的选项中,context需要跟之前保持一致,这个用来指导Webpack匹配manifest中库的路径;manifest用来引入刚才输出的manifest文件。

运行Webpack之后,结果如下:

Webpack的dll功能使用

对比一下不做分离的情况下打包的结果:

Webpack的dll功能使用

速度快了,文件也小了。

平时开发的时候,修改代码后重新编译的速度会大大减少,节省时间。

如果有多个项目,使用相同的一套库,你可以在打包的时候引用相同的manifest文件,这样就可以在项目之间共享了。

参考:

https://webpack.github.io/docs/list-of-plugins.html#dllplugin

https://github.com/webpack/webpack/tree/master/examples/dll

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
教你如何解密js/vbs/vbscript加密的编码异处理小结
Jun 25 Javascript
最简单的jQuery程序 入门者学习
Jul 09 Javascript
JavaScript可否多线程? 深入理解JavaScript定时机制
May 23 Javascript
javascript中call和apply方法浅谈
Sep 27 Javascript
如何实现修改密码时密码框显示保存到cookie的密码
Dec 10 Javascript
JavaScript解八皇后问题的方法总结
Jun 12 Javascript
详解关于vue2.0工程发布上线操作步骤
Sep 27 Javascript
layui表格内容溢出的解决方法
Sep 06 Javascript
中级前端工程师必须要掌握的27个JavaScript 技巧(干货总结)
Sep 23 Javascript
vue中在vuex的actions中请求数据实例
Nov 08 Javascript
浅谈Vue.use到底是什么鬼
Jan 21 Javascript
Vue自定义表单内容检查rules实例
Oct 30 Javascript
详解基于DllPlugin和DllReferencePlugin的webpack构建优化
Jun 28 #Javascript
vue使用Element组件时v-for循环里的表单项验证方法
Jun 28 #Javascript
详解ES6中的三种异步解决方案
Jun 28 #Javascript
Auto.js自动收取自己和好友蚂蚁森林能量脚本
Jun 28 #Javascript
使用vue-router完成简单导航功能【推荐】
Jun 28 #Javascript
vue如何引入sass全局变量
Jun 28 #Javascript
小程序实现带年月选取效果的日历
Jun 27 #Javascript
You might like
php 大数据量及海量数据处理算法总结
2011/05/07 PHP
php变量作用域的深入解析
2013/06/03 PHP
Symfony2创建页面实例详解
2016/03/18 PHP
CentOS 上搭建 PHP7 开发测试环境
2017/02/26 PHP
JavaScript下通过的XMLHttpRequest发送请求的代码
2011/06/28 Javascript
Javascript Throttle & Debounce应用介绍
2013/03/19 Javascript
js innerHTML 改变div内容的方法
2013/08/03 Javascript
Area 区域实现post提交数据的js写法
2014/04/22 Javascript
js对象内部访问this修饰的成员函数示例
2014/04/27 Javascript
jQuery使用load()方法载入另外一个网页文件内的指定标签内容到div标签的方法
2015/03/25 Javascript
JavaScript中数据结构与算法(三):链表
2015/06/19 Javascript
把Node.js程序加入服务实现随机启动
2015/06/25 Javascript
直接拿来用的15个jQuery代码片段
2015/09/23 Javascript
jQuery获取select选中的option的value值实现方法
2016/08/29 Javascript
Angular在一个页面中使用两个ng-app的方法(二)
2017/02/20 Javascript
解决layui 复选框等内置控件不显示的问题
2018/08/14 Javascript
详解vuejs中执行npm run dev出现页面cannot GET/问题
2020/04/26 Javascript
vue实现购物车加减
2020/05/30 Javascript
Openlayers显示瓦片网格信息的方法
2020/09/28 Javascript
uniapp电商小程序实现订单30分钟倒计时
2020/11/01 Javascript
为什么JavaScript中0.1 + 0.2 != 0.3
2020/12/03 Javascript
[01:14:34]DOTA2上海特级锦标赛C组资格赛#2 LGD VS Newbee第一局
2016/02/28 DOTA
[01:08:24]DOTA2-DPC中国联赛 正赛 RNG vs Phoenix BO3 第一场 2月5日
2021/03/11 DOTA
介绍Python的@property装饰器的用法
2015/04/28 Python
python爬取哈尔滨天气信息
2018/07/14 Python
Django 视图层(view)的使用
2018/11/09 Python
教你如何编写、保存与运行Python程序的方法
2019/07/12 Python
Django框架基础模板标签与filter使用方法详解
2019/07/23 Python
基于python的selenium两种文件上传操作实现详解
2019/09/19 Python
python怎么调用自己的函数
2020/07/01 Python
python 递归相关知识总结
2021/03/03 Python
工作中个人的自我评价
2013/12/31 职场文书
实验教师岗位职责
2014/02/13 职场文书
少先队学雷锋活动月总结
2014/03/09 职场文书
初中毕业感言300字
2015/07/31 职场文书
想要创业,那么你做好准备了吗?
2019/07/01 职场文书