Webpack 基础(二)
第二篇笔记是关于webpack优化的部分内容的学习。
一、优化构建速度
resolve
resolve配置主要用于控制模块解析的行为。它决定了 Webpack 在import或require模块时如何寻找文件路径。
常用配置项如下:
| 选项 | 作用 | 常见配置示例 |
|---|---|---|
extensions | 如果用户引入模块时不带扩展名,就会按照此数组从左到右去尝试解析模块 | extensions:['.js', '.ts', '.tsx', '.json'] |
alias | 配置模块路径别名,简化路径书写 | alias: { '@': path.resolve(__dirname, 'src')} |
externals
指定某些模块不打包,而是直接通过全局变量或外部加载。
例如:假设我们想将React和ReactDOM从打包中排除,并通过 CDN 加载它们:
webpack.config.js:
externals: {
react: 'React',
'react-dom': 'ReactDOM',
}
当代码中使用import React from 'react'时,Webpack 不会将 React 打包,而是假定项目运行时已经通过<script>标签加载了 React 并定义了全局变量React
index.html
<script src="https://unpkg.com/react@17/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.production.min.js"></script>
最终 React 和 ReactDOM 不会被打包进输出的文件,在运行时,通过<script>标签加载的全局变量提供它们。引用的时候照常引用。
缩小处理范围
1. include 和 exclude
这两个选项主要用于 Loader 的配置中,用来指定哪些文件应该被某个 Loader 处理或者排除。
- 作用: 提高构建效率,避免不必要的文件处理。
include
- 表示只处理指定目录或文件。
- 接收的值通常是一个路径或者正则表达式。
- 例子:
module.exports = { module: { rules: [ { test: /\.js$/, use: "babel-loader", include: /src/, // 只处理 src 目录下的文件 }, ], }, };
exclude
- 表示排除指定目录或文件,不进行处理。
- 适合排除
node_modules这样的外部依赖库。 - 例子:
module.exports = { module: { rules: [ { test: /\.js$/, use: "babel-loader", exclude: /node_modules/, // 排除 node_modules 目录 }, ], }, };
同时使用 include 和 exclude
可以更精准地控制范围,但需确保逻辑不冲突。
例如:
module.exports = {
module: {
rules: [
{
test: /\.js$/,
use: "babel-loader",
include: /src/,
exclude: /node_modules/,
},
],
},
};
2. noParse
noParse 是 Webpack 中用来优化模块解析的配置,作用是告知 Webpack 不解析某些模块的依赖关系。
- 作用: 提高构建速度,适用于不需要解析依赖的库(如预编译的库)。
- 注意事项:被标记为
noParse的模块仍然会被打包,但 Webpack 不会分析它们的依赖树。 - 常见使用场景:指定不包含依赖关系的库,比如 jQuery、lodash 的独立文件。
例子:
module.exports = {
module: {
noParse: /jquery|lodash/, // 不解析 jquery 和 lodash 的依赖关系
},
};
注意:
noParse的模块不能包含import、require等动态导入语法,否则会报错。- 适用于独立、完整的库,通常和
CDN配合使用。
利用缓存
babel-loader开启缓存
const config = {
module: {
noParse: /jquery|lodash/,
rules: [
{
test: /\.js$/i,
include: resolve("src"),
exclude: /node_modules/,
use: [
// ...
{
loader: "babel-loader",
options: {
cacheDirectory: true, // 启用缓存
},
},
],
},
// ...
],
},
};
其他的 loader 可以安装使用cache-loader来将结果缓存。
二、优化构建结果
压缩 CSS
最常用的插件是css-minimizer-webpack-plugin,用于优化和压缩 CSS 文件。
配置示例:
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
module.exports = {
mode: "production",
optimization: {
minimizer: [
"...", // 其他
new CssMinimizerPlugin(),
],
},
};
压缩 JS
在生成环境下打包默认会开启 js 压缩,但是当我们手动配置 optimization 选项之后,就不再默认对 js 进行压缩,需要我们手动去配置。
webpack5 内置了terser-webpack-plugin,直接引用就可以。
配置示例:
const TerserPlugin = require('terser-webpack-plugin');
module.exports = {
mode: "production",
optimization: {
minimize: true, // 是否进行压缩
minimizer: [
new TerserPlugin({
terserOptions: {
compress: {
drop_console: true, //传true就是干掉所有的console.*这些函数的调用.
drop_debugger: true, //干掉那些debugger;
},
},
}),
],
},
};
三、优化运行时体验
运行时,是指用户在浏览器中加载、解析和执行前端代码的阶段。
运行时优化的核心就是提升首屏加载速度。
代码懒加载
针对首屏加载不太需要的一些资源,我们可以通过懒加载的方式去实现。 示例:
// 按需加载
img.addEventListener('click', () => {
import('./desc').then(({ default: element }) => {
document.body.appendChild(element)
})
})
使用上述方法异步加载文件时,如果文件比较大,在点击时去加载影响体验。可以考虑使用prefetch来进行预拉取,它会在浏览器空间的时候进行拉取。
示例如下:
img.addEventListener('click', () => {
import( /* webpackPrefetch: true */ './desc').then(({ default: element }) => {
console.log(element)
document.body.appendChild(element)
})
})