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 相关文章推荐
自适应图片大小的弹出窗口
Jul 27 Javascript
JS 无法通过W3C验证的处理方法
Mar 09 Javascript
jquery表单验证需要做些什么
Nov 17 Javascript
JS短信验证码倒计时功能的实现(没有验证码,只有倒计时)
Oct 27 Javascript
详解Sea.js中Module.exports和exports的区别
Feb 12 Javascript
layui导航栏实现代码
May 19 Javascript
浅谈Webpack 持久化缓存实践
Mar 22 Javascript
ES10 特性的完整指南小结
Mar 04 Javascript
JS div匀速移动动画与变速移动动画代码实例
Mar 26 Javascript
JS字符串与二进制的相互转化实例代码详解
Jun 28 Javascript
node实现mock-plugin中间件的方法
Dec 25 Javascript
Vue中import from的来源及省略后缀与加载文件夹问题
Feb 09 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
THINKPHP+JS实现缩放图片式截图的实现
2010/03/07 PHP
理解php Hash函数,增强密码安全
2011/02/25 PHP
PHP框架Laravel的小技巧两则
2015/02/10 PHP
Thinkphp关闭缓存的方法
2015/06/26 PHP
php array_key_exists() 与 isset() 的区别
2016/10/24 PHP
PHP迭代与递归实现无限级分类
2017/08/28 PHP
js parsefloat parseint 转换函数
2010/01/21 Javascript
解析window.open的使用方法总结
2013/06/19 Javascript
获取3个数组不重复的值的具体实现
2013/12/30 Javascript
javascript处理表单示例(javascript提交表单)
2014/04/28 Javascript
scrollWidth,clientWidth,offsetWidth的区别
2015/01/13 Javascript
Windows下用PyCharm和Visual Studio开始Python编程
2015/10/26 Javascript
JavaScript文档碎片操作实例分析
2015/12/12 Javascript
微信小程序 解决请求服务器手机预览请求不到数据的方法
2017/01/04 Javascript
H5图片压缩与上传实例
2017/04/21 Javascript
详解vue-router和vue-cli以及组件之间的传值
2017/07/04 Javascript
vue实现全选和反选功能
2017/08/31 Javascript
IntersectionObserver实现图片懒加载的示例
2017/09/29 Javascript
图片加载完成再执行事件的实例
2017/11/16 Javascript
对vue事件的延迟执行实例讲解
2018/08/28 Javascript
jQuery.validate.js表单验证插件的使用代码详解
2018/10/22 jQuery
微信小程序学习笔记之表单提交与PHP后台数据交互处理图文详解
2019/03/28 Javascript
基于vue的video播放器的实现示例
2021/02/19 Vue.js
[07:26]2015国际邀请赛第二日TOP10集锦
2015/08/06 DOTA
python实现从web抓取文档的方法
2014/09/26 Python
使用rpclib进行Python网络编程时的注释问题
2015/05/06 Python
Python常用字符串替换函数strip、replace及sub用法示例
2018/05/21 Python
python的scipy.stats模块中正态分布常用函数总结
2021/02/19 Python
HTML5 Video/Audio播放本地文件示例介绍
2013/11/18 HTML / CSS
加拿大著名的奢侈品购物网站:SSENSE(支持中文)
2020/06/25 全球购物
网络安全类面试题
2015/08/01 面试题
应届毕业生自荐信例文
2014/02/26 职场文书
庆六一开幕词
2015/01/29 职场文书
自主招生专家推荐信
2015/03/26 职场文书
迁徙的鸟观后感
2015/06/09 职场文书
从原生JavaScript到React深入理解
2022/07/23 Javascript