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的逻辑运算符 ||
May 31 Javascript
使用jquery mobile做幻灯播放效果实现步骤
Jan 04 Javascript
HTML长文本截取含有HTML代码同样适用的两种方法
Jul 31 Javascript
JS控制一个DIV层在指定时间内消失的方法
Feb 17 Javascript
jQuery实现选中行变色效果(实例讲解)
Jul 06 jQuery
详解使用nvm管理多版本node的方法
Aug 30 Javascript
解决vue js IOS H5focus无法自动弹出键盘的问题
Aug 30 Javascript
vue动画打包后失效问题的解决方法
Sep 18 Javascript
vue-cli 3.x 修改dist路径的方法
Sep 19 Javascript
JavaScript中BOM对象原理与用法分析
Jul 09 Javascript
layui自定义ajax左侧三级菜单
Jul 26 Javascript
electron踩坑之dialog中的callback解决
Oct 06 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
ASP和PHP都是可以删除自身的
2007/04/09 PHP
PHP运行环境配置与开发环境的配置(图文教程)
2013/06/04 PHP
PHP安装memcached扩展笔记
2015/05/28 PHP
PHP实现清除wordpress里恶意代码
2015/10/21 PHP
PHP实现PDO操作mysql存储过程示例
2019/02/13 PHP
Javascript 匿名函数及其代码模式原理
2010/03/19 Javascript
在Windows上安装Node.js模块的方法
2011/09/25 Javascript
js或jquery实现页面打印可局部打印
2014/03/27 Javascript
Javascript中封装window.open解决不兼容问题
2014/09/28 Javascript
jquery实现鼠标点击后展开列表内容的导航栏效果
2015/09/14 Javascript
一步步教你利用Canvas对图片进行处理
2017/09/19 Javascript
详解react关于事件绑定this的四种方式
2018/03/09 Javascript
vue和webpack安装命令详解
2018/06/15 Javascript
详解Vue2.0组件的继承与扩展
2018/11/23 Javascript
详解一个基于套接字实现长连接的express
2019/03/28 Javascript
jquery实现动态创建form并提交的方法示例
2019/05/27 jQuery
简单了解前端渐进式框架VUE
2020/07/20 Javascript
[41:08]2014 DOTA2国际邀请赛中国区预选赛 HGT VS NE
2014/05/22 DOTA
[02:46]2014DOTA2国际邀请赛 选手为你解读比赛MVP充满梦想
2014/07/09 DOTA
[33:19]完美世界DOTA2联赛PWL S2 PXG vs InkIce 第一场 11.26
2020/11/30 DOTA
Python利用Django如何写restful api接口详解
2018/06/08 Python
python pillow模块使用方法详解
2019/08/30 Python
python 装饰器的基本使用
2021/01/13 Python
CSS实现的一闪而过的图片闪光效果
2014/04/23 HTML / CSS
一款纯css3实现的非常实用的鼠标悬停特效演示
2014/11/05 HTML / CSS
css3 仿写阿里云水纹效果的示例代码
2018/02/10 HTML / CSS
德国原装品牌香水、化妆品和手表网站:BRASTY.DE
2016/10/16 全球购物
新西兰领先的鞋类和靴子网上商城:Merchant 1948
2017/09/08 全球购物
医生进修自我鉴定
2014/01/19 职场文书
党员干部2014全国两会学习心得体会
2014/03/10 职场文书
关爱女孩行动实施方案
2014/03/13 职场文书
公司合作协议书范本
2014/04/18 职场文书
保洁员岗位职责
2015/02/04 职场文书
2015年行政管理人员工作总结
2015/10/15 职场文书
Python使用海龟绘图实现贪吃蛇游戏
2021/06/18 Python
详解Python中的进程和线程
2021/06/23 Python