50 lines
2.1 KiB
JavaScript
50 lines
2.1 KiB
JavaScript
// 不自动运行:需要先 npm install,然后 npm run build
|
||
// webpack 5 配置示例:loader、plugin、splitChunks、contenthash、tree shaking、持久化缓存。以官方文档为准:https://webpack.js.org/concepts/
|
||
import path from "node:path";
|
||
import { fileURLToPath } from "node:url";
|
||
|
||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||
|
||
// 自定义 plugin:构建结束后打印每个产物的大小(plugin = 在编译生命周期的钩子上做事)
|
||
class SizeReportPlugin {
|
||
apply(compiler) {
|
||
compiler.hooks.done.tap("SizeReportPlugin", (stats) => {
|
||
const assets = stats.toJson({ all: false, assets: true }).assets ?? [];
|
||
for (const a of assets.sort((x, y) => y.size - x.size)) {
|
||
console.log(`[size] ${a.name.padEnd(36)} ${(a.size / 1024).toFixed(2)} KiB`);
|
||
}
|
||
});
|
||
}
|
||
}
|
||
|
||
export default (env, argv) => {
|
||
const isProd = argv.mode === "production";
|
||
return {
|
||
entry: { main: "./src/index.js", admin: "./src/admin.js" }, // 两个入口,共享 utils 和第三方代码
|
||
output: {
|
||
path: path.resolve(__dirname, "dist"),
|
||
filename: isProd ? "[name].[contenthash:8].js" : "[name].js", // 内容变了文件名才变,利于长期缓存
|
||
clean: true,
|
||
},
|
||
module: {
|
||
rules: [
|
||
// 自定义 loader:把 .md 文件转成导出字符串的 JS 模块(loader = 把某类文件转换成 JS 模块)
|
||
{ test: /\.md$/, use: [{ loader: path.resolve(__dirname, "loaders/md-loader.cjs"), options: { trim: true } }] },
|
||
],
|
||
},
|
||
optimization: {
|
||
usedExports: true, // 标记未使用的导出,压缩时删除(tree shaking)
|
||
runtimeChunk: "single", // webpack 运行时单独一个文件,避免业务代码变化影响 vendor 的哈希
|
||
splitChunks: {
|
||
chunks: "all",
|
||
cacheGroups: {
|
||
shared: { name: "shared", minChunks: 2, minSize: 0, priority: 10 }, // 两个入口都用到的代码
|
||
},
|
||
},
|
||
},
|
||
cache: { type: "filesystem" }, // 持久化缓存:第二次构建明显变快
|
||
plugins: [new SizeReportPlugin()],
|
||
devtool: isProd ? false : "eval-cheap-module-source-map",
|
||
};
|
||
};
|