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 相关文章推荐
XmlUtils JS操作XML工具类
Oct 01 Javascript
利用jquery的获取JS文件中的字符串内容
Feb 14 Javascript
可在线编辑网页文字效果代码(单击)
Mar 02 Javascript
PHP开发者必须掌握的6个关键字
Apr 14 Javascript
学习javascript的闭包,原型,和匿名函数之旅
Oct 18 Javascript
通过Jquery.cookie.js实现展示浏览网页的历史记录超管用
Oct 23 Javascript
jQuery中使用animate自定义动画的方法
May 29 Javascript
微信小程序开发之map地图实现教程
Jun 08 Javascript
web前端开发中常见的多列布局解决方案整理(一定要看)
Oct 15 Javascript
使用Vue.js中的过滤器实现幂方求值的方法
Aug 27 Javascript
vue实现从外部修改组件内部的变量的值
Jul 30 Javascript
vue监听浏览器原生返回按钮,进行路由转跳操作
Sep 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
PHP把JPEG图片转换成Progressive JPEG的方法
2014/06/30 PHP
PHP中Session可能会引起并发问题
2015/06/26 PHP
php resizeimage 部分jpg文件 生成缩略图失败的原因分析及解决办法
2016/03/23 PHP
bgsound 背景音乐 的一些常用方法及特殊用法小结
2010/05/11 Javascript
javascript jq 弹出层实例
2013/08/25 Javascript
使用jquery自定义鼠标样式满足个性需求
2013/11/05 Javascript
JavaScript设置首页和收藏页面的小例子
2013/11/11 Javascript
jQuery获取字符串中出现最多的数
2016/02/22 Javascript
设计模式中的组合模式在JavaScript程序构建中的使用
2016/05/18 Javascript
JavaScript数组方法大全(推荐)
2016/07/05 Javascript
js从数组中删除指定值(不是指定位置)的元素实现代码
2016/09/13 Javascript
layer实现弹窗提交信息
2016/12/12 Javascript
如何清除IE10+ input X 文本框的叉叉和密码输入框的眼睛图标
2016/12/21 Javascript
微信小程序 生命周期和页面的生命周期详细介绍
2017/01/19 Javascript
Vue.js实战之Vuex的入门教程
2017/04/01 Javascript
微信小程序引用公共js里的方法的实例详解
2017/08/17 Javascript
浅谈Vue 初始化性能优化
2017/08/31 Javascript
angular写一个列表的选择全选交互组件的示例
2018/01/22 Javascript
AngularJS使用Filter自定义过滤器控制ng-repeat去除重复功能示例
2018/04/21 Javascript
layui的数据表格+springmvc实现搜索功能的例子
2019/09/28 Javascript
详解ES6新增字符串扩张方法includes()、startsWith()、endsWith()
2020/05/12 Javascript
js实现简易点击切换显示或隐藏
2020/11/29 Javascript
python中requests模块的使用方法
2015/04/08 Python
python通过邮件服务器端口发送邮件的方法
2015/04/30 Python
python调用其他文件函数或类的示例
2019/07/16 Python
Python读取excel文件中带公式的值的实现
2020/04/17 Python
中国包裹转运寄送国际服务:Famiboat
2019/07/24 全球购物
简述使用ftp进行文件传输时的两种登录方式?它们的区别是什么?常用的ftp文件传输命令是什么?
2016/11/20 面试题
司机职责范本
2014/03/08 职场文书
无财产无子女离婚协议书范文
2014/09/14 职场文书
2014年调度员工作总结
2014/11/19 职场文书
捐助倡议书
2015/01/19 职场文书
2015秋季新学期开学寄语
2015/05/28 职场文书
安全守法证明
2015/06/23 职场文书
教学副校长工作总结
2015/08/13 职场文书
Java中PriorityQueue实现最小堆和最大堆的用法
2021/06/27 Java/Android