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 相关文章推荐
Fastest way to build an HTML string(拼装html字符串的最快方法)
Aug 20 Javascript
JavaScript 命名空间 使用介绍
Aug 29 Javascript
jquery iframe操作详细解析
Nov 20 Javascript
jquery实现ajax提交form表单的方法总结
Mar 03 Javascript
jQuery+PHP实现动态数字展示特效
Mar 14 Javascript
javascript删除数组重复元素的方法汇总
Jun 24 Javascript
JS实现来回出现文字的状态栏特效代码
Oct 31 Javascript
JS jQuery使用正则表达式去空字符的简单实现代码
May 20 jQuery
微信小程序getPhoneNumber获取用户手机号
Sep 29 Javascript
微信小程序实现留言板
Oct 31 Javascript
js console.log打印对象时属性缺失的解决方法
May 23 Javascript
通过图带你深入了解vue的响应式原理
Jun 21 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
帅气的琦玉老师
2020/03/02 日漫
PHP 用数组降低程序的时间复杂度
2009/12/04 PHP
php文字水印和php图片水印实现代码(二种加水印方法)
2013/12/25 PHP
php过滤html中的其他网站链接的方法(域名白名单功能)
2014/04/24 PHP
php实现多维数组排序的方法示例
2017/03/23 PHP
PHP将身份证正反面两张照片合成一张图片的代码
2017/04/08 PHP
TP5框架使用QueryList采集框架爬小说操作示例
2020/03/26 PHP
js 事件处理函数间的Event物件是否全等
2011/04/08 Javascript
window.event快达到全浏览器支持了,以后使用就方便了
2011/11/30 Javascript
js中小数转换整数的方法
2014/01/26 Javascript
Jquery实现仿腾讯娱乐频道焦点图(幻灯片)特效
2015/03/06 Javascript
JavaScript实现找质数代码分享
2015/03/24 Javascript
jquery计算鼠标和指定元素之间距离的方法
2015/06/26 Javascript
在微信、支付宝、百度钱包实现点击返回按钮关闭当前页面和窗口的方法
2016/08/05 Javascript
jQuery实现扑克正反面翻牌效果
2017/03/10 Javascript
深入理解React Native原生模块与JS模块通信的几种方式
2017/07/24 Javascript
layer插件select选中默认值的方法
2018/08/14 Javascript
Vue项目总结之webpack常规打包优化方案
2019/06/06 Javascript
微信小程序把百度地图坐标转换成腾讯地图坐标过程详解
2019/07/10 Javascript
修改Vue打包后的默认文件名操作
2020/08/12 Javascript
如何编写一个 Webpack Loader的实现
2020/10/18 Javascript
[56:00]DOTA2上海特级锦标赛主赛事日 - 4 胜者组决赛Secret VS Liquid第一局
2016/03/05 DOTA
[51:14]LGD vs VP 2018国际邀请赛淘汰赛BO3 第一场 8.21
2018/08/22 DOTA
跟老齐学Python之让人欢喜让人忧的迭代
2014/10/02 Python
你眼中的Python大牛 应该都有这份书单
2017/10/31 Python
一些Centos Python 生产环境的部署命令(推荐)
2018/05/07 Python
Python读取Pickle文件信息并计算与当前时间间隔的方法分析
2019/01/30 Python
Python多线程获取返回值代码实例
2020/02/17 Python
Python运行提示缺少模块问题解决方案
2020/04/02 Python
浅谈python 调用open()打开文件时路径出错的原因
2020/06/05 Python
李维斯牛仔裤荷兰官方网站:Levi’s NL
2020/08/23 全球购物
投标承诺书范本
2014/03/27 职场文书
大学新闻系自荐书
2014/05/31 职场文书
600字作文之感受大自然
2019/11/27 职场文书
mysql联合索引的使用规则
2021/06/23 MySQL
JavaScript事件的委托(代理)的用法示例详解
2022/02/18 Javascript