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 相关文章推荐
在线编辑器的实现原理(兼容IE和FireFox)
Mar 09 Javascript
多个js与css文件的合并方法详细说明
Dec 26 Javascript
学习Bootstrap滚动监听 附调用方法
Jul 02 Javascript
jquery设置表单元素为不可用的简单代码
Jul 04 Javascript
前端程序员必须知道的高性能Javascript知识
Aug 24 Javascript
jQuery动态添加与删除tr行实例代码
Oct 18 Javascript
JavaScript数据结构之二叉树的删除算法示例
Apr 13 Javascript
jQuery实现手机号正则验证输入及自动填充空格功能
Jan 02 jQuery
element-ui的回调函数Events的用法详解
Oct 16 Javascript
Vue CLI2升级至Vue CLI3的方法步骤
May 20 Javascript
使用VueRouter的addRoutes方法实现动态添加用户的权限路由
Jun 03 Javascript
ES2020系列之空值合并运算符 '??'
Jul 22 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
超外差式晶体管收音机的组装与统调
2021/03/01 无线电
php adodb操作mysql数据库
2009/03/19 PHP
PHP 伪静态隐藏传递参数名的四种方法
2010/02/22 PHP
php和jquery实现地图区域数据统计展示数据示例
2014/02/12 PHP
试用php中oci8扩展
2015/06/18 PHP
Yii2.0高级框架数据库增删改查的一些操作
2015/11/16 PHP
ExtJS GridPanel 根据条件改变字体颜色
2010/03/08 Javascript
5个javascript的数字格式化函数分享
2011/12/07 Javascript
Mac/Windows下如何安装Node.js
2013/11/22 Javascript
用jquery写的菜单从左往右滑动出现
2014/04/11 Javascript
浅析JavaScript事件和方法
2015/02/28 Javascript
探索angularjs+requirejs全面实现按需加载的套路
2016/02/26 Javascript
jQuery EasyUI编辑DataGrid用combobox实现多级联动
2016/08/29 Javascript
原生ajax处理json格式数据的实例代码
2016/12/25 Javascript
js微信分享实现代码
2020/10/11 Javascript
React Native中Navigator的使用方法示例
2017/10/13 Javascript
vue滚动轴插件better-scroll使用详解
2017/10/17 Javascript
微信小程序实现指定显示行数多余文字去掉用省略号代替
2018/07/25 Javascript
vue路由教程之静态路由
2019/09/03 Javascript
vue中的使用token的方法示例
2020/03/10 Javascript
VueX模块的具体使用(小白教程)
2020/06/05 Javascript
详谈Vue.js框架下main.js,App.vue,page/index.vue之间的区别
2020/08/12 Javascript
ES11新增的这9个新特性,你都掌握了吗
2020/10/15 Javascript
python使用电子邮件模块smtplib的方法
2016/08/28 Python
Python实现的科学计算器功能示例
2017/08/04 Python
python读取和保存视频文件
2018/04/16 Python
python 动态迁移solr数据过程解析
2019/09/04 Python
pytorch 彩色图像转灰度图像实例
2020/01/13 Python
基于Pytorch SSD模型分析
2020/02/18 Python
Fossil加拿大官网:化石手表、手袋、首饰及配饰
2019/04/23 全球购物
有模特经验的简历自我评价
2013/09/19 职场文书
简单的辞职信范文
2014/01/18 职场文书
2014县政府领导班子对照检查材料思想汇报
2014/09/25 职场文书
承诺保证书格式
2015/02/28 职场文书
Springboot使用Spring Data JPA实现数据库操作
2021/06/30 Java/Android
你需要掌握的20个Python常用技巧
2022/02/28 Python