针对与webpack项目打包,我们正常做的最多的就是脚手架安装,后run build
直接部署,不会去做过多的处理。
对webpack学习,使用webpack打包优化,主要注重两点
- 面向开发者:提示打包速度
- 面向用户:缩小打包体积
webpack 优化常用
打包速度优化
- 安装
speed-measure-webpack-plugin
speed-measure-webpack-plugin中有对应操作。 来看下项目打包的速度。
npm i speed-measure-webpack-plugin -D
使用
代码语言:txt复制const SpeedMeasurePlugin = require("speed-measure-webpack-plugin");
const smp = new SpeedMeasurePlugin();
// 将webpack配置内容用wrap包裹起来
const webpackConfig = smp.wrap({
plugins: [new MyPlugin(), new MyOtherPlugin()],
});
执行打包命令后,可以看出哪个插件打包耗时比较高,已进行针对优化打包速度
使用thread-loader
进行多线程打包优化
- 安装
thread-loader
npm install --save-dev thread-loader
使用时在配置loader时将thread-loader加在比较耗时的loader前面
代码语言:txt复制 module: {
rules: [
{
test: /.js$/,
include: path.resolve('src'),
use: [
"thread-loader", // 在耗时的loader前加上thread-loader进行多线程打包
// 耗时的 loader (例如 babel-loader)
],
},
],
},
官方提供了thread-loader的配置参数,可以修改参数达到提速的效果。
代码语言:txt复制 use: [
{
loader: "thread-loader",
// 有同样配置的 loader 会共享一个 worker 池
options: {
// 产生的 worker 的数量,默认是 (cpu 核心数 - 1),或者,
// 在 require('os').cpus() 是 undefined 时回退至 1
workers: 2,
// 一个 worker 进程中并行执行工作的数量
// 默认为 20
workerParallelJobs: 50,
// 额外的 node.js 参数
workerNodeArgs: ['--max-old-space-size=1024'],
// 允许重新生成一个僵死的 work 池
// 这个过程会降低整体编译速度
// 并且开发环境应该设置为 false
poolRespawn: false,
// 闲置时定时删除 worker 进程
// 默认为 500(ms)
// 可以设置为无穷大,这样在监视模式(--watch)下可以保持 worker 持续存在
poolTimeout: 2000,
// 池分配给 worker 的工作数量
// 默认为 200
// 降低这个数值会降低总体的效率,但是会提升工作分布更均一
poolParallelJobs: 50,
// 池的名称
// 可以修改名称来创建其余选项都一样的池
name: "my-pool"
},
},
// 耗时的 loader(例如 babel-loader)
];
现在的脚手架大多更新迭代很快,可能会出现 使用了多线程但是速度并未提升很多的可能。除了工具还需要阅读代码,查看使用的插件在项目中的场景,综合考虑解决办法
打包体积优化
- 安装
webpack-bundle-analyzer
会弹出一个网页来显示项目打包后的体积大小,根据打包提及来优化 使用
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
module.exports = {
plugins: [
// 只需要在plugin中new一个实例就可以了。
new BundleAnalyzerPlugin()
]
}
webpack 分包处理
我们可以自行决定将webpack中哪内容分包出去。
例如我们要将项目中的react-dom
和@material-ui/xxx
相关内容分包出去
- 创建
webpack.dll.config,js
用来写分包的配置文件
const path = require('path')
const webpack = require('webpack')
modules.exports = {
mode:'production', // 只在生产环境才使用
entry:{
common:[
// 想要分包的依赖
'react-dom',
'@material-ui/core',
'@material-ui/icons',
'@material-ui/lab'
]
},
output:{
path:path.resolve(__dirname, "../dll"), //文件生成的路径再上一级的dll文件夹
fillname:'[name].dll.js', // [name]会与入口文件名称相同,
library:'[name]_[hash]' // [hash] 会自动生成hash值
},
plugins:[
new webpack.DllPlugin({
path: path.resolve(__dirname, "../dll", "[name]-manifest.json"),
name: '[name]_[hash]' // 要与library名称相同
})
]
}
随后需要在package.json中配置分包命令
代码语言:txt复制"scripts": {
"build-dll":"webpack --config config/webpack.dll.config.js" //config/webpack.dll.config.js 是分包的配置文件地址
}
运行时需要安装webpack-cli
如果没有安装,会提示安装
npm run build-dll
运行成功后,dll文件夹下会生成 对应的 common-manifest.json
和conmon.dll.js
文件
- 生产分包需要需要在webpack中将分的包排除出去 在项目打包的webpack配置文件中
plugins:[
new webpack.DllReferencePlugin({
context:path.resolve(__dirname, '../'),
manifest:path.resolve(__dirname, '../dll/common-manifest.json') //对应生成的manifest文件路径
})
]
此时运行npm run build
webpack-bundle-analyzer
弹出页面,分包出去的依赖就已经消失了。体积也会缩小。
- 引入分包文件
引入分包文件需要安装
copy-webpack-plugin
和html-webpack-tags-plugin
npm i copy-webpack-plugin html-webpack-tags-plugin -Dcopy-webpack-plugin
使用如果webpack版本可能会报错,报错可以尝试修改copy-webpack-plugin
的版本后再重新打包 - 使用
const CopyWebpackPlugin =require('copy-webpack-plugin')
const HtmlWebpackTagsPlugin = require('html-webpack-tags-plugin')
plugins:[
new webpack.DllReferencePlugin({
context:path.resolve(__dirname, '../'),
manifest:path.resolve(__dirname, '../dll/common-manifest.json') //对应生成的manifest文件路径
}),
// 将生成的dll文件拷贝到打包生成的目录
new CopyWebpackPlugin = ({
patterns:[
{
from:"./dll/common.dll.js", // 分包生成的文件
to:"./static/js" //打包生成目录
}
]
})
// 将拷贝过来的分包文件进行引用
new HtmlWebpackTagsPlugin({
tags:['/static/js/common.dll.js'],
append:false
})
]
这里可能会存在打包后生成的连接名称替换不成功,大多是因为speed-measure-webpack-plugin
可能会有冲突,将speed-measure-webpack-plugin禁用可以解决。
const smp = new SpeedMeasurePlugin({
disable:true
});
常用的webpack plugin
plugin名称 | 作用 |
---|---|
HotModuleReplacementPlugin | 模块热更新 |
clean-webpack-plugin | 目录清理 |
html-webpack-plugin | 自动生成一个index.html文件,将打包的js文件自动通过 |
uglifyjs-webpack-plugin | js压缩 |
mini-css-extract-plugin | 分离样式文件,将ss提取为单独文件 |
DefinePlugin | 定义全局常量,应用:在不用环境下引入不通的配置 |
speed-measure-webpack-plugin | 输出打包内容速度 |
webpack-bundle-analyzer | 可视化webpack输入文件体积 |
常用loader 介绍
loader名称 | 作用 |
---|---|
css-loader | 用于处理css文件,是的在js文件中可以引入 |
style-loader | 将css文件注入到index.html中的style标签上 |
less-loader | 处理less代码 |
sass-loader | 处理sass代码 |
babel-loader | 把ES6转ES5 |
ts-loader | 把typescript 转成es5 |
file-loader | 打包图片,打包字体图标 |
webpack-bundle-analyzer | 可视化webpack输入文件体积 |
html-withimg-loader | 打包HTML文件中的图片 |
eslint-loader | 用于检查常见的代码错误,和书写规范检查 |