dll预编译提高webpack打包速度
栏目: JavaScript · 发布时间: 5年前
内容简介:我们构建前端项目的时候,往往希望第三方库(通常为了对抗缓存,我们会给售出文件的文件名中加入
我们构建前端项目的时候,往往希望第三方库( 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
也变化了
这么一来,意味着每次发布版本的时候,vendor代码都要刷新,即使我并没有修改其中的代码。这样并不符合我们分开打包的初衷
-
Dll
是Webpack
最近新加的功能 -
Dll
这个概念应该是借鉴了Windows
系统的dll
。一个dll
包,就是一个纯纯的依赖库,它本身不能运行,是用来给你的app
引用的 - 打包
dll
的时候,Webpack
会将所有包含的库做一个索引,写在一个manifest
文件中,而引用dll
的代码(dll user
)在打包的时候,只需要读取这个manifest
文件,就可以了。
优势
-
Dll
打包以后是独立存在的,只要其包含的库没有增减、升级,hash
也不会变化,因此线上的dll
代码不需要随着版本发布频繁更新 -
App
部分代码修改后,只需要编译app
部分的代码,dll
部分,只要包含的库没有增减、升级,就不需要重新打包。这样也大大提高了每次编译的速度 - 假设你有多个项目,使用了相同的一些依赖库,它们就可以共用一个
dll
1.1 使用
首先要先建立一个 dll
的配置文件, entry
只包含第三方库
第一步:新建webpack.dll.conf.js
-
webpack.DllPlugin
的选项中,path
是manifest
文件的输出路径;name
是dll
暴露的对象名,要跟output.library
保持一致
// build/webpack.dll.conf.js const path = require('path') const webpack = require('webpack') module.exports = { entry: { // 把这些资源打包成dll,提高编译速度 react: ['react','react-router-dom','redux','redux-immutable','immutable','react-redux','react-router','redux-logger','redux-thunk','styled-components'], ui: ['antd-mobile','antd'], others: ['react-icons','axios','clipboard','humps','lodash','md5','moment','normalizr'] }, output: { path: path.resolve(__dirname, "../dll/"), filename: '[name].dll.js', library: '[name]' }, plugins: [ new webpack.DllPlugin({ path: path.join(__dirname,'../dll/','[name]-manifest.json'), name: '[name]' }), new webpack.optimize.UglifyJsPlugin() ] }
第二步:加一个命令
// package.json "scripts": { "dll": "webpack --config config/webpack.dll.conf.js" }
执行 npm run dll
- 运行
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
来引用
第三步: 在plugins中增加配置
// build/webpack.prod.conf.js module.exports = { plugins: [ new webpack.DllReferencePlugin({ manifest: require('../dll/react-manifest.json') }), new webpack.DllReferencePlugin({ manifest: require('../dll/ui-manifest.json') }), new webpack.DllReferencePlugin({ manifest: require('../dll/others-manifest.json') }) ] }
再次执行 npm run build
之前
之后
二、happypack 多线程打包
一般情况下,js是单线程执行的,但 node
不是。利用 node
提供的多线程环境, happypack
是可以多线程打包的。基本上打开官网看了一下readme就可以配置了,特别是我只针对js的编译进行优化,配置还是比较简单的。
https://www.npmjs.com/package/happypack
-
happyPack
把所有串行的东西并行处理,使得loader
并行处理,较少文件处理时间
// build/webpack.prod.conf.js // @file: webpack.config.js const HappyPack = require('happypack'); exports.module = { rules: [ { test: /.js$/, // 1) replace your original list of loaders with "happypack/loader": // loaders: [ 'babel-loader?presets[]=es2015' ], use: 'happypack/loader', include: [ /* ... */ ], exclude: [ /* ... */ ] } ], plugins: [ // 2) create the plugin: new HappyPack({ // 3) re-add the loaders you replaced above in #1: loaders: [ 'babel-loader?presets[]=es2015' ] }) ] }
这时的编译时间也减小了一些
三、更多参考
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- Android 编译打包的那些疑问
- Android 编译打包的那些疑问
- 前端打包编译时代来临对漏洞挖掘的影响
- Android逆向入门篇--编译、打包、安装 - 先知社区
- Android应用程序资源的编译和打包过
- [nghttp2]压测工具,源码编译并进行deb打包过程
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。