构建打包速度
HotModuleReplacement
-
为什么?
HotModuleReplacement只编译所修改的模块,webpack默认将所有模块全部重新打包
-
是啥?
HotModuleReplacement(HMR):在程序运行中,替换、添加或者删除模块,而无需重新加载整个页面
-
用法
devServer: {
host: "localhost", // 启动服务器域名
port: "3000", // 启动服务器端口号
open: true, // 是否自动打开浏览器
hot:true //开启(HMR,webpack5默认为true)
}
热加载JS文件
if (module.hot){
module.hot.accept('./js/count')
}
实际开发中使用vue-loader或者react-loader进行HMR
OneOf
-
为啥?
打包所有文件都会经过loader处理,哪怕没有命中的正则也要过一遍,速度比较慢
-
是啥?
一旦命中一个loader,不会继续向下匹配
-
用法
module: {
rules: [
{
oneOf: [
{
// 用来匹配 .css 结尾的文件
test: /.css$/,
// use 数组里面 Loader 执行顺序是从右到左
use: [MiniCssExtractPlugin.loader, "css-loader", {
loader: "postcss-loader",
options: {
postcssOptions: {
plugins: ['postcss-preset-env']
}
}
}],
},
{
test: /.less$/,
use: [MiniCssExtractPlugin.loader, "css-loader", "less-loader"],
},
{
test: /.js$/,
exclude: /node_modules/, // 排除node_modules代码不编译
loader: "babel-loader",
},
]
}
],
},
生产模式依旧是这么配置
Include/Exclude
-
为啥?
有些文件我们在打包的时候并不需要进行编译(比如:node_modules)
-
是啥?
include:只处理指定文件
exclude:排除文件不进行处理
-
用法:
{
test: /.js$/,
//exclude: /node_modules/, // 排除node_modules代码不编译
include: path.resolve(__dirname,'../src'), //只处理src文件
loader: "babel-loader",
},
include与exclude 二选一,不能同时存存在,只针对JS文件(样式没必要)
Cache缓存
-
为啥?
每次进行打包操作都需要经过Eslint检查和Babel编译,速度较慢,我们可以缓存之前的Eslint检查和Babel编译结果,这样第二次打包速度就会很快了。
-
是啥?
是缓存(对Eslint和Babel编译结果进行缓存),只针对第二次......
-
使用
{
test: /.js$/,
//exclude: /node_modules/, // 排除node_modules代码不编译
include: path.resolve(__dirname,'../src'), //只处理src文件
loader: "babel-loader",
options: {
cacheDirectory:true, //开启babel缓存
cacheCompression:false //关闭缓存文件压缩
}
},
plugins: [
new ESLintWebpackPlugin({
// 指定检查文件的根目录
context: path.resolve(__dirname, "../src"),
cache: true, //开启缓存
exclude:"node_modules" //默认值
})
],
Thead
-
为啥?
项目变大,打包速度越来越慢,开启多线程同时处理js文件
-
是啥?
多线程打包:开启电脑的多个线程干同一件事
-
用法:
- 获取CPU核心数
const os = require('os') //node.js核心模块直接使用
const threads = os.cpus().length //cpu核心数
- 安装loader
npm i thread-loader -D - 使用:
JS Babel开启多线程(thread-loader必须在babel-loader之前)
{
test: /.js$/,
//exclude: /node_modules/, // 排除node_modules代码不编译
include: path.resolve(__dirname, '../src'), //只处理src文件
use: [
{
loader: "thread-loader", //开启多线程
options: {
workers:threads
}
},
{
loader: "babel-loader",
options: {
cacheDirectory: true, //开启babel缓存
cacheCompression: false //关闭缓存文件压缩
}
}
]
},
ESlint开启多线程
new ESLintWebpackPlugin({
// 指定检查文件的根目录
context: path.resolve(__dirname, "../src"),
cache: true,
exclude: "node_modules", //默认值
threads
}),
压缩 JavaScript
const TerserPlugin = require('terser-webpack-plugin')
optimization: {
minimize: true,
minimizer: [
//css压缩
new CssMinimizerPlugin(),
//多线程
new TerserPlugin({
parallel: threads
})
]
},
webpack5 默认安装terser-webpack-plugin 但是如果你需要自定义配置依旧需要安装
减少代码体积
Tree Shaking
- 为什么?
开发所定义的一些工具函数库或者第三方函数库或者组件库,不进行处理就会引入整个库但是我们可能使用的是极小部分功能。整个库打包进去,体积太大
- 是什么?
用于移除Javscript中没有使用的代码
- 如何使用: 默认开启,无需配置
Babel
- 为什么?
Babel 为编译的每个文件都插入了辅助代码,使代码体积过大,避免公共方法的重复引用,需要将这些辅助代码作为一个独立模块,避免重复引入。
-
是什么?
@babel/plugin-transform-runtime: 禁用了 Babel 自动对每个文件的 runtime 注入,而是引入@babel/plugin-transform-runtime并且使所有辅助代码从这里引用。 -
咋用?
- 安装
npm i @babel/plugin-transform-runtime -D - 配置
- 安装
{
test: /.js$/,
//exclude: /node_modules/, // 排除node_modules代码不编译
include: path.resolve(__dirname, '../src'), //只处理src文件
use: [
{
loader: "thread-loader", //开启多线程
options: {
workers: threads
}
},
{
loader: "babel-loader",
options: {
cacheDirectory: true, //开启babel缓存
cacheCompression: false, //关闭缓存文件压缩
plugins:["@babel/plugin-transform-runtime"] //减少代码体积
}
}
]
}
Image Minimizer
- 为啥?
项目图片较多,图片体积较大
-
是什么? 用来压缩图片的插件
-
咋用?
- 下载包
npm i image-minimizer-webpack-plugin imagemin -D - 无损压缩
npm install imagemin-gifsicle imagemin-jpegtran imagemin-optipng imagemin-svgo -D - 配置
- 下载包
const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");
optimization: {
minimize: true,
minimizer: [
//css压缩
new CssMinimizerPlugin(),
//多线程
new TerserPlugin({
parallel: threads
}),
new ImageMinimizerPlugin({
minimizer: {
implementation: ImageMinimizerPlugin.imageminGenerate,
options: {
plugins: [
["gifsicle", { interlaced: true }],
["jpegtran", { progressive: true }],
["optipng", { optimizationLevel: 5 }],
[ "svgo", { plugins: [ "preset-default", "prefixIds", { name: "sortAttrs", params: { xmlnsOrder: "alphabetical", }, }, ],
},
],
],
},
},
}),
]
},