| .. | .. |
|---|
| 2 | 2 | * 命令行发行(不上传)+ 自动用微信开发者工具打开产物 |
|---|
| 3 | 3 | * |
|---|
| 4 | 4 | * 用法: |
|---|
| 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 # 只打印将要执行的命令 |
|---|
| 10 | 10 | * |
|---|
| 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 → 用微信开发者工具打开产物 |
|---|
| 14 | 13 | * |
|---|
| 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 生成,这里再兜底校正一次)。 |
|---|
| 16 | 18 | * |
|---|
| 17 | 19 | * 外部工具(HBuilderX cli.exe、微信开发者工具 cli.bat)不写死绝对路径,按顺序自动查找: |
|---|
| 18 | 20 | * 1) 环境变量 HBUILDERX_CLI / WX_DEVTOOLS_CLI |
|---|
| .. | .. |
|---|
| 24 | 26 | const { spawnSync } = require('child_process'); |
|---|
| 25 | 27 | const fs = require('fs'); |
|---|
| 26 | 28 | const path = require('path'); |
|---|
| 29 | +const manifest = require('./manifest'); |
|---|
| 27 | 30 | |
|---|
| 28 | 31 | const ROOT = path.resolve(__dirname, '..'); |
|---|
| 29 | 32 | const ENV_DIR = path.join(ROOT, 'config', 'env'); |
|---|
| .. | .. |
|---|
| 189 | 192 | |
|---|
| 190 | 193 | const argv = process.argv.slice(2); |
|---|
| 191 | 194 | 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; |
|---|
| 193 | 196 | const noOpen = argv.indexOf('--no-open') > -1; |
|---|
| 194 | 197 | const dryRun = argv.indexOf('--dry-run') > -1; |
|---|
| 195 | 198 | |
|---|
| 196 | | -const OWN_ARGS = ['--sync', '--no-open', '--dry-run']; |
|---|
| 199 | +const OWN_ARGS = ['--no-gen', '--no-open', '--dry-run']; |
|---|
| 197 | 200 | // 透传给 HBuilderX cli 的额外参数(保留 "参数 值" 成对关系) |
|---|
| 198 | 201 | const passthrough = []; |
|---|
| 199 | 202 | let envNameSkipped = false; |
|---|
| .. | .. |
|---|
| 243 | 246 | putOnPath(hx.file); |
|---|
| 244 | 247 | if (wx) putOnPath(wx.file); |
|---|
| 245 | 248 | |
|---|
| 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 | + |
|---|
| 246 | 254 | console.log('[release] 环境 : ' + envName + '(' + env.ENV_NAME + ')'); |
|---|
| 247 | 255 | console.log('[release] 小程序appid : ' + env.APPID); |
|---|
| 248 | 256 | console.log('[release] 接口地址 : ' + env.HTTP_REQUEST_URL); |
|---|
| 249 | 257 | console.log('[release] 产物目录 : ' + DIST_DIR); |
|---|
| 250 | 258 | console.log('[release] HBuilderX : ' + hx.file + '(' + hx.source + ')'); |
|---|
| 251 | 259 | 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 + ',生成物不入库)')); |
|---|
| 253 | 263 | |
|---|
| 254 | 264 | 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 + '"' : ''; |
|---|
| 257 | 267 | |
|---|
| 258 | 268 | if (dryRun) { |
|---|
| 269 | + console.log('[release] 0) 生成: manifest.json ← manifest.json.demo' + (noGen ? '(已指定 --no-gen,跳过)' : '')); |
|---|
| 259 | 270 | console.log('[release] 1) 编译: "' + hx.file + '" ' + cliArgs.join(' ')); |
|---|
| 260 | 271 | console.log('[release] 2) 产物 appid 回写为 ' + env.APPID + ' → ' + DIST_CONFIG); |
|---|
| 261 | 272 | if (!noOpen) console.log('[release] 3) 打开: ' + openCmd); |
|---|
| .. | .. |
|---|
| 263 | 274 | return; |
|---|
| 264 | 275 | } |
|---|
| 265 | 276 | |
|---|
| 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); |
|---|
| 271 | 282 | } |
|---|
| 272 | 283 | |
|---|
| 273 | 284 | // 2) 发行编译(产物:unpackage/dist/build/mp-weixin) |
|---|
| .. | .. |
|---|
| 276 | 287 | if (build.error) fail('调用 cli.exe 失败:' + build.error.message); |
|---|
| 277 | 288 | if (build.status !== 0) fail('cli.exe 退出码 ' + build.status + ',请查看 HBuilderX 控制台输出'); |
|---|
| 278 | 289 | |
|---|
| 279 | | - // 3) 校正产物 appid(--sync 时通常已一致,这里兜底保证) |
|---|
| 290 | + // 3) 校正产物 appid(正常应与 manifest 一致,这里兜底保证) |
|---|
| 280 | 291 | if (!fs.existsSync(DIST_CONFIG)) { |
|---|
| 281 | 292 | fail('发行产物缺少 project.config.json:' + DIST_CONFIG + '\n 请确认 HBuilderX 编译是否成功'); |
|---|
| 282 | 293 | } |
|---|