成为构建大师:用 Webpack 插件实现流程自动化
手动修改版本号的“最后一次”
想象一下,你正在维护一个快速迭代的项目。每次发布新版本前,你可能都需要做一个重复性的工作:
打开某个
config.ts
文件,手动将版本号从1.2.0
改成1.2.1
,再更新一下发布时间。
这个操作虽然简单,但却充满了“工业时代”的笨拙感:
- 容易忘记:一忙起来,你就可能忘记修改,导致线上版本信息不正确。
- 信息孤岛:这个版本号与
package.json
里的版本号是脱节的,你实际上在维护两个版本号。
如果有一种方法,能让构建过程自动读取 package.json
的版本号,并把它注入到我们的代码里,那该多好?
答案是:你可以做到!通过自定义 ArenaPro 项目的 Webpack 构建流程,你可以成为一名“构建大师”,让许多重复性工作自动化。
⚠️ 在成为“大师”之前,请务必阅读!
Danger
这是一个非常高级的功能,请谨慎使用。
- 责任自负: 一旦你创建了自定义的
webpack.config.js
,你就接管了项目的构建配置。如果因配置不当导致构建失败或运行时错误,你需要自行排查解决。 - 高风险: 很多 Webpack 插件,特别是那些会修改代码逻辑的(如混淆、压缩),可能会与 ArenaPro 引擎产生冲突,导致游戏无法正常运行。
- 从小处着手: 不要直接复制粘贴网上复杂的配置。从一个最简单的配置开始,一次只增加或修改一个选项,并立即测试其效果。
- 充分测试: 每次修改配置后,请务必完整地测试你的游戏,确保所有功能都正常。
如果你不确定自己在做什么,我们强烈建议你不要使用这个功能。
实战:打造一个“版本信息自动注入器”
我们的目标是:在代码中能直接使用 __APP_VERSION__
和 __BUILD_DATE__
这两个全局变量,并且它们的值是在每次构建时自动生成的。
我们将通过 Webpack 内置的 DefinePlugin
插件轻松实现这个目标。
第 1 步:创建 webpack.config.js
在你的项目根目录(与 package.json
同级)创建一个名为 webpack.config.js
的文件。
这个文件的基本结构如下,它导出一个函数,该函数需要返回一个 Webpack 配置对象。ArenaPro 会将你返回的对象与默认配置进行智能合并。
// webpack.config.js
// 默认的 webpack 配置会作为参数传入,方便你进行微调
module.exports = function (defaultConfig) {
// 你可以在这里修改 defaultConfig
// ...
// 或者完全返回一个新的配置对象
return {
...defaultConfig, // 推荐继承默认配置
// 在这里添加你的自定义配置
plugins: [
...(defaultConfig.plugins || []), // 继承默认插件
// ... 在这里添加你的新插件
],
};
};
第 2 步:配置 DefinePlugin
现在,我们来配置 DefinePlugin
,让它为我们注入想要的变量。
// webpack.config.js
const webpack = require("webpack");
const packageJson = require("./package.json"); // 引入 package.json 文件,以读取版本号
module.exports = function (defaultConfig) {
//...
plugins: [
// 使用 DefinePlugin 注入全局常量
new webpack.DefinePlugin({
// 注入版本号,值从 package.json 读取
__APP_VERSION__: JSON.stringify(packageJson.version),
// 注入构建日期,值为当前构建时的时间戳
__BUILD_DATE__: JSON.stringify(new Date().toLocaleString()),
}),
],
//...
};
第 3 步:在代码中享受自动化成果
配置完成后,你需要重启一下构建进程(如果正在运行的话)才能让 webpack.config.js
生效。
然后,你就可以在代码中直接使用这两个新变量了!为了获得更好的代码提示,建议在你的 types
目录下创建一个 .d.ts
文件(如 types/global.d.ts
),声明一下这两个全局变量。
// types/global.d.ts
declare const __APP_VERSION__: string;
declare const __BUILD_DATE__: string;
现在,在你的游戏入口处,你可以这样写:
// server/src/index.ts
console.log(`欢迎来到游戏!`);
console.log(`当前版本: ${__APP_VERSION__}`);
console.log(`构建于: ${__BUILD_DATE__}`);
当你运行游戏时,就会看到:
欢迎来到游戏!
当前版本: 1.2.1
构建于: 2025/6/26 10:30:00 AM
从此以后,你再也无需手动管理版本信息了!每次构建,最新的信息都会被自动烧录进你的代码中。
进阶挑战:保护你的代码 (代码混淆)
如果你对构建流程的自定义意犹未尽,可以挑战一个更高级的任务:代码混淆。
代码混淆是一种通过重命名变量、加密字符串等方式,让你的代码变得极难阅读的技术。这可以有效地保护你的核心逻辑不被轻易地逆向破解。
警告:这是一个高风险操作,请务必在充分理解和测试后再使用。
我们将使用 webpack-obfuscator
插件来实现这个目标。
安装插件:
npm install webpack-obfuscator javascript-obfuscator --save-dev
配置
webpack.config.js
:
// webpack.config.js
const WebpackObfuscator = require("webpack-obfuscator");
const webpack = require("webpack");
const packageJson = require("./package.json");
module.exports = function (defaultConfig) {
// ...
plugins: [
// ... 此处省略我们上面已添加的 DefinePlugin ...
new webpack.DefinePlugin({
__APP_VERSION__: JSON.stringify(packageJson.version),
__BUILD_DATE__: JSON.stringify(new Date().toLocaleString()),
}),
new WebpackObfuscator({
// 一个相对安全的配置集,可以有效混淆,同时降低与引擎冲突的风险
compact: true,
stringArray: true,
rotateStringArray: true,
selfDefending: false,
shuffleStringArray: true,
splitStrings: true,
stringArrayEncoding: ["base64"],
stringArrayThreshold: 0.75,
}),
].filter(Boolean), // 使用 .filter(Boolean) 优雅地移除数组中的 false 值
// ...
};
配置完成后,当你执行完整构建 (Alt+Q
) 时,最终输出的代码就会被加密混淆。