Jacob
2026-10-14 c5c8af3b41faad94be35e88dd65d418cefb83b1e
scripts/publish.js
....@@ -2,17 +2,19 @@
22 * 命令行发行(不上传)+ 自动用微信开发者工具打开产物
33 *
44 * 用法:
5
- * node scripts/publish.js sit # 发行 SIT 版本并打开微信开发者工具
6
- * node scripts/publish.js prod # 发行 PROD 版本并打开微信开发者工具
7
- * node scripts/publish.js sit --sync # 同时把 appid 同步进 manifest.json(默认不动 manifest)
8
- * node scripts/publish.js sit --no-open # 只编译,不打开微信开发者工具
9
- * node scripts/publish.js sit --dry-run # 只打印将要执行的命令
5
+ * node scripts/publish.js sit # 发行 SIT 版本并打开微信开发者工具
6
+ * node scripts/publish.js prod # 发行 PROD 版本并打开微信开发者工具
7
+ * node scripts/publish.js sit --no-gen # 不改 manifest.json(要求它已存在)
8
+ * node scripts/publish.js sit --no-open # 只编译,不打开微信开发者工具
9
+ * node scripts/publish.js sit --dry-run # 只打印将要执行的命令
1010 *
11
- * 环境值统一取自 config/env/<env>.js(唯一数据源),接口地址等运行时参数由包内自动识别,
12
- * 本脚本只负责让“编译期 appid”与目标环境一致 —— 微信开发者工具打开的产物 appid,
13
- * 就是 unpackage/dist/build/mp-weixin/project.config.json 里的 appid(构建时由 manifest 生成)。
11
+ * 流程:从 manifest.json.demo 生成 manifest.json(按目标环境注入 appid)→ 发行编译 →
12
+ * 校正产物 appid → 用微信开发者工具打开产物
1413 *
15
- * 默认策略:不动 manifest.json(仓库保持基线,git 无噪音),只回写未跟踪的产物文件。
14
+ * 环境值统一取自 config/env/<env>.js(唯一数据源),接口地址等运行时参数由包内按 appid 自动识别;
15
+ * manifest.json 是生成物(已 .gitignore),因此 git 永远没有环境噪音。
16
+ * 微信开发者工具打开的产物 appid = unpackage/dist/build/mp-weixin/project.config.json 的 appid
17
+ * (构建时由 manifest 生成,这里再兜底校正一次)。
1618 *
1719 * 外部工具(HBuilderX cli.exe、微信开发者工具 cli.bat)不写死绝对路径,按顺序自动查找:
1820 * 1) 环境变量 HBUILDERX_CLI / WX_DEVTOOLS_CLI
....@@ -24,6 +26,7 @@
2426 const { spawnSync } = require('child_process');
2527 const fs = require('fs');
2628 const path = require('path');
29
+const manifest = require('./manifest');
2730
2831 const ROOT = path.resolve(__dirname, '..');
2932 const ENV_DIR = path.join(ROOT, 'config', 'env');
....@@ -189,11 +192,11 @@
189192
190193 const argv = process.argv.slice(2);
191194 const envName = (argv.find(function(a) { return a.charAt(0) !== '-'; }) || '').trim();
192
-const syncManifest = argv.indexOf('--sync') > -1;
195
+const noGen = argv.indexOf('--no-gen') > -1;
193196 const noOpen = argv.indexOf('--no-open') > -1;
194197 const dryRun = argv.indexOf('--dry-run') > -1;
195198
196
-const OWN_ARGS = ['--sync', '--no-open', '--dry-run'];
199
+const OWN_ARGS = ['--no-gen', '--no-open', '--dry-run'];
197200 // 透传给 HBuilderX cli 的额外参数(保留 "参数 值" 成对关系)
198201 const passthrough = [];
199202 let envNameSkipped = false;
....@@ -243,19 +246,27 @@
243246 putOnPath(hx.file);
244247 if (wx) putOnPath(wx.file);
245248
249
+ // 目标编译产物由 manifest.json 决定,而 manifest.json 是生成物
250
+ if (noGen && !fs.existsSync(manifest.TARGET)) {
251
+ fail('--no-gen 需要 manifest.json 已存在,请先运行:node scripts/set-env.js ' + envName);
252
+ }
253
+
246254 console.log('[release] 环境 : ' + envName + '(' + env.ENV_NAME + ')');
247255 console.log('[release] 小程序appid : ' + env.APPID);
248256 console.log('[release] 接口地址 : ' + env.HTTP_REQUEST_URL);
249257 console.log('[release] 产物目录 : ' + DIST_DIR);
250258 console.log('[release] HBuilderX : ' + hx.file + '(' + hx.source + ')');
251259 if (wx) console.log('[release] 开发者工具 : ' + wx.file + '(' + wx.source + ')');
252
- console.log('[release] manifest.json: ' + (syncManifest ? '同步为 ' + envName + ' 的 appid(会产生 git 改动)' : '保持不动(仓库维持基线,无 git 改动)'));
260
+ console.log('[release] manifest.json: ' + (noGen
261
+ ? '不改动(--no-gen)'
262
+ : '由 manifest.json.demo 生成(appid ' + env.APPID + ',生成物不入库)'));
253263
254264 const cliArgs = ['publish', '--platform', 'mp-weixin', '--project', ROOT].concat(passthrough);
255
- // 路径含空格/中文,交给 cmd 解析更稳
256
- const openCmd = '"' + wx.file + '" open --project "' + DIST_DIR + '"';
265
+ // 路径含空格/中文,交给 cmd 解析更稳(--no-open 时没有微信开发者工具,不拼这条命令)
266
+ const openCmd = wx ? '"' + wx.file + '" open --project "' + DIST_DIR + '"' : '';
257267
258268 if (dryRun) {
269
+ console.log('[release] 0) 生成: manifest.json ← manifest.json.demo' + (noGen ? '(已指定 --no-gen,跳过)' : ''));
259270 console.log('[release] 1) 编译: "' + hx.file + '" ' + cliArgs.join(' '));
260271 console.log('[release] 2) 产物 appid 回写为 ' + env.APPID + ' → ' + DIST_CONFIG);
261272 if (!noOpen) console.log('[release] 3) 打开: ' + openCmd);
....@@ -263,11 +274,11 @@
263274 return;
264275 }
265276
266
- // 1) 可选:同步 manifest.json(会让被跟踪文件产生改动,默认不做)
267
- if (syncManifest) {
268
- console.log('[release] 同步 manifest.json 的 appid…');
269
- const sync = spawnSync(process.execPath, [path.join(__dirname, 'set-env.js'), envName], { cwd: ROOT, stdio: 'inherit' });
270
- if (sync.status !== 0) fail('同步 manifest.json 失败');
277
+ // 1) 生成 manifest.json(HBuilderX 的编译输入,模板:manifest.json.demo)
278
+ if (noGen) {
279
+ console.log('[release] 跳过 manifest.json 生成(--no-gen)');
280
+ } else {
281
+ manifest.generate(env);
271282 }
272283
273284 // 2) 发行编译(产物:unpackage/dist/build/mp-weixin)
....@@ -276,7 +287,7 @@
276287 if (build.error) fail('调用 cli.exe 失败:' + build.error.message);
277288 if (build.status !== 0) fail('cli.exe 退出码 ' + build.status + ',请查看 HBuilderX 控制台输出');
278289
279
- // 3) 校正产物 appid(--sync 时通常已一致,这里兜底保证)
290
+ // 3) 校正产物 appid(正常应与 manifest 一致,这里兜底保证)
280291 if (!fs.existsSync(DIST_CONFIG)) {
281292 fail('发行产物缺少 project.config.json:' + DIST_CONFIG + '\n 请确认 HBuilderX 编译是否成功');
282293 }