webpack性能优化2
1.优化构建速度:用在开发环境中
- DllPlugin:已经快过时了,配置繁琐
- HardSourceWebpackPlugin:配置简单
DllPlugin插件打包第三方类库 优化构建性能
Dll动态链接库 其实就是做缓存:一个项目中我们经常会用到第三方类库,比如React、lodash等,没特别的需求一般这些类库我们不会去动他的代码,但是在打包的过程中这些库会非常占用打包时间,打包的时候我们分开来打包来提升打包速度,而DllPlugin动态链接库插件,其原理就是把页面依赖的基础模块抽离出来打包到dll文件中,当需要导入的模块存在于某个dll中时,这个模块不再被打包,而是去dll中获取
动态链接库只需要被编译一次;webpack已经内置了对动态链接库的支持
- DllPlugin:用于打包出一个个单独的动态链接库文件-----负责打包
- DllReferencePlugin:用于在主要的配置文件中引入DllPlugin插件打包好的动态链接库文件------负责使用
.
首先新建webpack.dll.config.js文件,打包基础模块
const path = require("path"); const {DllPlugin} = require("webpack"); module.exports = { mode:"development", entry:{ react:["react","react-dom"], //lodash:["lodash"] //多个库的引用 在entry里追加即可 以lodash为例 }, output:{ path:path.resolve(__dirname,"./dll"), filename:"[name]-dll.js", library:"[name]" }, plugins:[ new DllPlugin({ //manifeast.json文件的输出位置 path:path.join(__dirname,"./dll","[name]-manifest.json"),//与动态库的映射关系 //定义打包的公共vendor文件对外暴露的函数名,name必须和library的name那么保持一致 name:"[name]" }) ] }
在package.json中添加
"dev:dll":"webpack --config ./webpack.dll.config.js"
运行:npm run dev:dll
你会发现多了一个dll文件夹,里面有dll.js文件,这样我们就把我们的React这些已经单独打包了
- dll文件包含了大量模块的代码,这些模块被存放在一个数组里,用数组的索引号为ID,通过变量将自己暴露在全局中,就可在window.xxx访问到其中的模块
- manifest.json描述了与其对应的dll.js包含了哪些模块,以及ID和路径---映射文件
使用:
- 将网页依赖的基础模块抽离,打包到单独的动态链接库,一个动态链接库是可以包含多个模块的--上面已完成
- 当需要导入的模块存在于某个动态链接库中时,不要再次打包,直接使用构建好的动态链接库即可--下面是使用步骤
---------------------------------------------------------------------------------------------
##webpack.config.js
new DllReferencePlugin({ manifest:require("./dll/react-manifest.json") })/* //多个文件的引用就在下面追加即可--以lodash为例new DllReferencePlugin({ manifest:require("./dll/lodash-manifest.json") }) */
然后html页面依赖的所有动态链接库都需要被加载----即通过script标签将dll文件夹下的文件引入页面,手动添加体验不好,这里推荐使用add-asset-html-webpack-plugin插件帮助我们做这个事情
(因为使用推荐方法 所以我们将上面的webpack.config.js中的引用删除)
-----------------------------------------------------------------------------------------------------
使用add-asset-html-webpack-plugin:
安装:npm i add-asset-html-webpack-plugin -D
他会将我们打包后的dll.js文件注入到我们生成的index.html中
#webpack.config.js
new AddAssetHtmlWebpackPlugin({ filepath:path.resolve(__dirname,"./dll/react.dll.js") })/* 如果有多个库 后面追加即可 以lodash为例
new AddAssetHtmlWebpackPlugin({ filepath:path.resolve(__dirname,"./dll/react.dll.js") })
*/
运行:npm run dev
生成的index.html里会自动引入
梳理:
- 生成打包,生成dll文件夹
- 命令行的配置气动打包
- 引用打包,与html文件关联
操作起来比较费劲,索性webpack5中已经不用它了,而是用HardSourceWebpackPlugin,一样的优化效果,但是使用极其简单
使用HardSourceWebpackPlugin:
安装:npm i hard-source-webpack-plugin -D
const HardSourceWebpackPlugin = require("hard-source-webpack-plugin") new HardSourceWebpackPlugin() 保存在硬盘上 构建速度的提升 只支持4x后较新的版本 dll用在开发环境中
运行:npm run dev
第一次构建速度比较慢,是因为将文件保存在硬盘上
第二次构建速度有明显的提升,是因为直接读取缓存中的数据
2.使用happypack并发执行任务:提升构建速度,用在开发环境
运行在node之上的webpack是单线程模型的,也就是说webpack需要一个一个的处理任务,不能同时处理多个任务;happy pack就能让webpack做到这一点,他将任务分解给多个子进程去执行并发执行,子进程处理完后再将结果发送给主进程,从而发挥多核cpu电脑的威力
安装:npm i -D happypack
const happyPack = require("happypack") const happyThreadPool = happyPack.ThreadPool({size:os.cpus().length})//共享子进程size子进程的数量,可写死,可获取核数 module.exports = { module:{ rules:[ { test:/\.css$/, include:path.resolve(__dirname,"./src"),//没指定这个字段,他会在整个项目中搜索检查css格式的再使用对应loader执行,比较消耗时间,限制范围指定搜索范围 //use:["style-loader","css-loader"],//loader是有执行顺序的,从后往前,先执行css-loader后执行style-loader //use的改造 use:[{ loader:"happypack/loader?id=css" }] }, { test:/\.(png|jpe?g|gif)$/, /*use:{ loader:"file-loader",//支持各种文件 图片 外部字体库 options:{ name:‘[name].[ext]‘,//名字和后缀 outputPath:‘images/‘ } },*/ //use的改造 use:{ loader:"happypack/loader?id=pic" }, } ] }, plugins:[ new happyPack({ id:"css",//用唯一的标识符id,来代表当前的HappyPack是用来处理一类特定的文件 loaders:["style-loader","css-loader"],//如何处理css文件,用法和上面的改造前的loader配置中一样 threadPool:happyThreadPool//共享线程池 }), new happyPack({ id:"pic",// loaders: [{ loader:"file-loader",//支持各种文件 图片 外部字体库 options:{ name:‘[name].[ext]‘,//名字和后缀 outputPath:‘images/‘ } }], threadPool:happyThreadPool }) ] }
运行:npm run dev
happypack的坑:happypack和mini-css-extract-plugin配合起来是有问题的,暂未找到解决方案 ,与其他loader结合是没有问题的