打包工具怎么控制产物生成
打包工具怎么控制产物生成
可以干预的环节
1. 入口(Entry)
告诉打包工具从哪里开始分析依赖:
// webpack.config.js
module.exports = {
entry: {
main: "./src/main.tsx",
admin: "./src/admin.tsx", // 多入口,生成多个 bundle
},
};
2. 输出(Output)
控制产物放在哪里、叫什么名字:
module.exports = {
output: {
path: path.resolve(__dirname, "dist"),
filename: "js/[name].[contenthash:8].js", // hash 文件名
chunkFilename: "js/chunk.[contenthash:8].js", // 懒加载分包名
clean: true, // 每次构建清空 dist
},
};
3. 代码分割(Code Splitting)
控制怎么拆包:
module.exports = {
optimization: {
splitChunks: {
chunks: "all",
cacheGroups: {
// 第三方库单独打包
vendor: {
test: /[\\/]node_modules[\\/]/,
name: "vendor",
chunks: "all",
},
// React 单独打包
react: {
test: /[\\/]node_modules[\\/](react|react-dom)[\\/]/,
name: "react",
chunks: "all",
},
},
},
},
};
4. Tree Shaking
自动移除没用到的代码:
// package.json
{
"sideEffects": false // 告诉打包工具所有模块都可以 Tree Shaking
}
// 或指定哪些文件有副作用,不能 Tree Shaking
{
"sideEffects": ["*.css", "*.global.js"]
}
开发时写法也影响 Tree Shaking:
// ✅ 支持 Tree Shaking,只打包用到的
import { add } from "lodash-es";
// ❌ 整个 lodash 都打包进去
import _ from "lodash";
5. 懒加载(动态导入)
人为控制哪些代码延迟加载:
// React
const HeavyPage = lazy(() => import("./HeavyPage"));
// 手动命名 chunk
const HeavyPage = lazy(
() => import(/* webpackChunkName: "heavy-page" */ "./HeavyPage"),
);
6. 环境变量
控制不同环境的打包产物:
// webpack.config.js
module.exports = {
plugins: [
new webpack.DefinePlugin({
"process.env.NODE_ENV": JSON.stringify(process.env.NODE_ENV),
"process.env.API_URL": JSON.stringify(process.env.API_URL),
}),
],
};
// 代码里判断环境,生产打包会移除 dev 代码
if (process.env.NODE_ENV === "development") {
console.log("调试信息"); // 生产包里这段会被移除
}
7. Loader(资源转换)
控制各种文件怎么处理:
module.exports = {
module: {
rules: [
{
test: /\.tsx?$/,
use: "babel-loader", // TS/JSX 转 JS
},
{
test: /\.css$/,
use: ["style-loader", "css-loader", "postcss-loader"],
},
{
test: /\.(png|jpg)$/,
type: "asset",
parser: {
dataUrlCondition: {
maxSize: 8 * 1024, // 8kb 以下转 base64
},
},
},
],
},
};
8. 压缩(Minify)
控制产物怎么压缩:
const TerserPlugin = require("terser-webpack-plugin");
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
terserOptions: {
compress: {
drop_console: true, // 移除所有 console.log
},
},
}),
new CssMinimizerPlugin(), // CSS 压缩
],
},
};
常见优化手段汇总
| 优化点 | 方式 | 效果 |
|---|---|---|
| 减少首屏体积 | 懒加载 + 代码分割 | 首屏只下载必要代码 |
| 第三方库缓存 | 单独打包 vendor | 库不变则长期缓存 |
| 移除无用代码 | Tree Shaking | 减少包体积 |
| 图片优化 | 小图转 base64 | 减少 HTTP 请求 |
| 压缩代码 | Terser + CSS Minimizer | 减少文件体积 |
| 移除调试代码 | drop_console |
减少体积 |
| 分析包体积 | webpack-bundle-analyzer |
找出体积大的模块 |
分析打包产物
用可视化工具找出哪个包体积大:
npm install webpack-bundle-analyzer -D
const { BundleAnalyzerPlugin } = require("webpack-bundle-analyzer");
module.exports = {
plugins: [
new BundleAnalyzerPlugin(), // 构建后自动打开可视化页面
],
};
