Skip to content

pmd-pixui-cli

TypeScript strict

PixUI 命令行工具集 — 提供 pfbs 编码、资源优化等构建时工具,输出可直接部署到 CDN 的静态文件。

功能特性

pfbs 命令

  • 递归扫描目录,对 .html / .js 文件进行 pfbs 编码
  • 输出到独立目录,保持原始目录结构
  • 非目标文件原样拷贝,输出目录可直接部署
  • 支持 pfbs 版本指定、扩展名过滤、并发控制
  • dry-run 模式预览、明确退出码,CI/CD 友好

bundle 命令

  • 将小应用资源打包为版本包
  • 支持 Unity/Cocos 等引擎配置
  • 支持自定义图片目录
  • 支持多页面打包
  • 配置文件支持 JS 和 JSON 格式
  • 支持自动生成默认配置

whitepublish 命令

  • 白名单发布(仅白名单用户可见)
  • 自动从七彩石获取版本 ID
  • 支持 test / preRelease / prod 三种模式
  • 支持 --notify-msg 输出发布结果

whitelist 命令

  • Pandora 白名单管理工具
  • 支持 add / rm / clean / query 四个子命令
  • 纯参数驱动,便于流水线和 Hook 集成
  • 支持 --mode 指定版本解析模式(test / preRelease / prod)

config 命令

  • 生成各类配置文件
  • 支持 bundle 配置生成
  • 支持 dry-run 预览模式

upload 命令

  • 上传小应用版本包到 Pandora 平台
  • 支持 test / preRelease / prod 三种发布模式
  • 支持全量同步和部分同步两种同步策略
  • 自动从七彩石获取源版本 ID(根据 mode 映射字段)
  • 自动生成版本描述(基于 Git 信息)
  • 支持 --notify-msg 输出发布结果
  • 支持环境变量配置(Pandora Token 等)

安装

bash
# 在 monorepo 内
pnpm install

# 或单独安装
pnpm add -g pmd-pixui-cli

使用

主命令帮助

bash
pmd-pixui-cli --help

输出:

pmd-pixui-cli — PixUI 命令行工具集

Usage:
  pmd-pixui-cli <command> [options]

Commands:
  pfbs          PixUI pfbs 构建时预编码工具
  bundle        PixUI 小应用版本包打包工具
  upload        上传小应用版本包到 Pandora 平台
  whitepublish  白名单发布(仅白名单用户可见)
  whitelist     Pandora 白名单管理工具
  config        生成配置文件

Options:
  --help, -h  Show help

Examples:
  pmd-pixui-cli pfbs --dir dist --version 0.5
  pmd-pixui-cli bundle --config ./bundle.config.js
  pmd-pixui-cli --help

环境变量

部分命令需要配置环境变量才能正常工作:

环境变量必填说明
PANDORA_TOKEN_TEST测试环境 Pandora API 访问令牌
PANDORA_TOKEN_PROD生产环境 Pandora API 访问令牌
PANDORA_SAASIDSaas ID(用于 API 请求签名,默认 0)
PANDORA_SECRETAPI 请求签名密钥(可选)
RAINBOW_APPID七彩石应用 ID(upload / whitepublish / whitelist 命令需要)
RAINBOW_USERID七彩石用户 ID(upload / whitepublish / whitelist 命令需要)
RAINBOW_SECRETKEY七彩石密钥(upload / whitepublish / whitelist 命令需要)

注意:工具所有命令通过 --mode 参数控制环境。--mode=test(默认)使用 PANDORA_TOKEN_TEST--mode=preRelease--mode=prod 使用 PANDORA_TOKEN_PROD

pfbs 命令

bash
pmd-pixui-cli pfbs --dir <path> --version <ver> [options]

必填参数

参数缩写说明
--dir-d源目录路径
--version-vpfbs 版本号(0.2 | 0.3 | 0.4 | 0.5)

可选参数

参数缩写默认值说明
--outdir-o<dir>-pfbs输出目录
--ext-ehtml,js处理的扩展名(逗号分隔)
--copytrue拷贝非目标文件到输出目录
--no-copy不拷贝非目标文件
--cleanfalse构建前清空输出目录
--concurrency5并行编码数
--dry-run只打印不执行
--verbose详细输出
--help-h显示帮助

示例

bash
# 基本用法:编码 dist 目录,使用 pfbs 0.5
pmd-pixui-cli pfbs -d dist -v 0.5

# 指定输出目录,构建前清空
pmd-pixui-cli pfbs -d dist -v 0.5 -o dist-pfbs --clean

# 只编码 html 文件,不拷贝其他文件
pmd-pixui-cli pfbs -d dist -v 0.5 --ext html --no-copy

# 预览模式:查看会处理哪些文件
pmd-pixui-cli pfbs -d dist -v 0.5 --dry-run

# 查看 pfbs 命令帮助
pmd-pixui-cli pfbs --help

输出示例

pfbs-build v1.0.0
  source:      /path/to/dist
  output:      /path/to/dist-pfbs
  version:     0.5
  ext:         html, js
  copy:        true
  concurrency: 5
──────────────────────────────────────────────────
[encode] index.html          2.3 KB → 1.8 KB
[encode] pages/about.html    5.1 KB → 4.2 KB
[encode] js/app.js         120.0 KB → 98.4 KB
──────────────────────────────────────────────────
✓ 3 files encoded, 2 files copied. (1.2s)

项目配置文件

工具会读取项目根目录的 .pmd-devops/app.json.pixiderc/.frmwkrc.json.pixiderc/apps.json

.pmd-devops/app.json 需要业务自行生成和维护的配置文件

json
// .pmd-devops/app.json 示例
{
  "projectId": 10512,
  "appId": 9194,
  "appName": "pvpCampus",
  "engineType": "unity"
}

.pixiderc/* 是 PixUI 框架自带的配置文件

json
// .pixiderc/apps.json 示例
[
  {
    "name": "app",
    "template": "./src/app/index.html",
    "entry": "./src/app/main.tsx"
  },
  {
    "name": "match",
    "template": "./src/match/index.html",
    "entry": "./src/match/main.tsx"
  },
  {
    "name": "preprocess",
    "template": "./src/preprocess/index.html",
    "entry": "./src/preprocess/main.tsx"
  }
]
json
// .pixiderc/.frmwkrc.json 示例
{
  "title": "PI",
  "name": "pi",
  "type": "pi",
  "entryScriptName": "main.tsx",
  "srcRoot": "src",
  "distDir": "dist",
  "prodDistDir": "html-pro",
  "devDistDir": "html-dev",
  "assetDir": "static",
  "outDirMode": "pi",
  "preservedDirs": [
      "src",
      "faas",
      ".git"
  ],
  "pkgmgr": "yarn",
  "$__metaVersion": "1.0.0"
}

bundle 命令

bash
pmd-pixui-cli bundle [options]

可选参数

参数缩写说明
--config-c配置文件路径 (JS 或 JSON),不指定则自动生成

自动生成配置

如果不指定 --config 参数,工具会自动生成默认配置(内存中,不写入文件)。

配置来源

配置项来源说明
app.id.pmd-devops/app.jsonappId 字段小应用 ID
app.name.pmd-devops/app.jsonappName 字段小应用名称
engineType.pmd-devops/app.jsonengineType 字段引擎类型
其他字段.pixiderc/.frmwkrc.json.pixiderc/apps.json项目配置

打包配置示例

JSON 格式 (bundle.config.json):

javascript
{
  outputDir: '/data1/play-ground/pixide-demo-projects/empty-aaa/.bundles',
  bundleVersion: '1.1.0',
  app: {
    id: 4724,
    name: 'ababila',
  },
  engineType: 'unity',
  customizedImageDirs: [
    'aaaaa',
    'bbbbb',
  ],
  engineContribConfigs: {
    unity: {
      baseDir: '/data1/play-ground/unity-mock-projects/unity-demo-hello/Assets/StreamingAssets/Pandora',
    },
    puerts: {
      baseDir: '/data1/play-ground/pixide-demo-projects/empty-aaa/dist/.build/html-pro',
    },
  },
  pagesDir: '/data1/play-ground/pixide-demo-projects/empty-aaa/dist/.build/html-pro',
  pageNames: [
    'app',
    'popup',
    'preprocess',
  ],
  assetDirName: 'static',
  jsLowerCaseInBundle: false,
  projectFrameworkType: 'pi',
}

配置字段说明

字段必填说明
outputDir输出目录
bundleVersion打包结构规范版本,详细查阅:小应用平台资源包文件结构
app.id小应用 ID
app.name小应用名称
engineType引擎类型 (unity/cocos等),王者荣耀是 unity
pagesDir页面目录
pageNames页面名称数组
projectFrameworkType项目框架类型 (pi/vue等)
customizedImageDirs自定义图片目录数组,详细查阅:自定义图片目录
engineContribConfigs引擎资源配置
assetDirName静态资源目录名 (默认 static)
jsLowerCaseInBundleJS 文件名小写 (默认 false)

示例

bash
# 使用 JS 配置文件
pmd-pixui-cli bundle -c ./bundle.config.js

# 使用 JSON 配置文件
pmd-pixui-cli bundle --config ./bundle.config.json

# 自动生成配置并打包(不指定 --config 参数)
pmd-pixui-cli bundle

# 查看 bundle 命令帮助
pmd-pixui-cli bundle --help

输出示例

bundle — PixUI 小应用版本包打包工具
  app:         my-app (ID: 4724)
  version:     1.1.0
  engine:      unity
  pagesDir:    /path/to/dist/.build/html-pro
  pageNames:   app, popup
  outputDir:   /path/to/.bundles
  framework:   pi
──────────────────────────────────────────────────
✓ Bundle created successfully. (3.2s)
  Output: /path/to/.bundles/my-app.zip

upload 命令

bash
pmd-pixui-cli upload [options]

上传小应用版本包到 Pandora 平台,支持多种同步模式。

同步模式

upload 命令通过以下参数控制同步行为:

参数说明
--version-id-sync <id>全量同步指定版本的配置(含白名单),与 --whitelist-skip-sync 互斥(指定后 --mode 不生效)
--whitelist-skip-sync <id>不同步白名单,需指定源版本 ID,与 --version-id-sync 互斥(指定后 --mode 不生效)
--mode <mode>根据 mode 从七彩石读取对应版本 ID 进行全量同步,未指定 --version-id-sync/--whitelist-skip-sync 时作为兜底逻辑

同步决策树

  1. --whitelist-skip-sync--version-id-sync 两者互斥 → 同时指定则报错终止(--mode 不参与互斥,是两者未指定时的兜底逻辑)
  2. --whitelist-skip-sync <id> → 使用用户指定的源版本 ID 执行部分同步(不同步白名单)
  3. --version-id-sync <id> → 全量同步用户指定的版本配置(未指定 ID 则报错)
  4. 都不指定 → 根据 --mode(默认 test)查七彩石对应版本 ID(preReleasepreVersionIdprodprodVersionId,其他 → versionId
    • 有值 → 全量同步
    • 无值 → 兜底调用 Pandora 获取最新版本 ID → 降级为部分同步(兜底也失败 → 报错终止)

可选参数

参数说明
--zip <path>zip 包路径(默认 ./.bundles/{appName}.zipappName.pmd-devops/app.json 读取)
--version-id-sync <id>全量同步的源版本 ID(与 --whitelist-skip-sync 互斥,指定后 --mode 不生效)
--whitelist-skip-sync <id>不同步白名单,需指定源版本 ID(与 --version-id-sync 互斥,指定后 --mode 不生效)
--desc <text>版本描述(未指定时自动生成;指定时自动添加 [分支名] 前缀)
--mode <mode>模式:test(测试发布,默认)、preRelease(预发布)或 prod(正式),未指定 --version-id-sync/--whitelist-skip-sync 时作为兜底逻辑
--notify-msg将运行结果写入 notify-msg.md
--offline-old-version上线时下线同分支旧版本(默认不下线)
--version <ver>指定版本号(如 1.0.0,不指定则自动递增)
--help / -h显示帮助

版本描述

1. 未指定 --desc 时(自动生成)

[feature/pixui-pfbs][feat: 本周版本发布][518b9614]

2. 指定 --desc 时(自动添加分支名前缀)

bash
pmd-pixui-cli upload --desc "修复登录bug"
# 实际描述:[feature/pixui-pfbs]修复登录bug

自动生成规则

  • 使用 getGitCommitInfo 获取 Git 信息和 git log 获取提交标题
  • 分支名:当前分支名(如 feature/pixui-pfbs
  • 提交标题:最新提交的标题(如 feat: 本周版本发布
  • 短hash:提交短 hash(如 518b9614
  • 获取失败时兜底为 [Auto]

依赖:需要安装 t-comm 包(已作为依赖包含)

配置文件

upload 命令读取项目根目录的 .pmd-devops/app.json 获取应用信息:

json
{
  "projectId": 10523,
  "appId": 9194,
  "appName": "vpCampus",
  "engineType": "unity"
}

配置字段

字段必填说明
projectId小应用所属项目的项目 ID
appId小应用 ID
appName小应用名称
engineType引擎类型(unity/cocos 等)

环境变量

环境变量必填说明
PANDORA_TOKEN_TEST测试环境 Pandora API 访问令牌
PANDORA_TOKEN_PROD生产环境 Pandora API 访问令牌
PANDORA_SAASIDSaas ID(用于 API 请求签名,默认 0
PANDORA_SECRETAPI 请求签名密钥(可选)

工作流程

1. 读取配置 (.pmd-devops/app.json)

2. 获取最新版本信息 (Pandora API)

3. 创建新版本 (create_version_v2)

4. 上传版本包 (upload)

5. 完成

示例

bash
# 基本用法:自动获取版本 ID 并同步,默认使用 ./.bundles/{appName}.zip
pmd-pixui-cli upload

# 指定 zip 包路径
pmd-pixui-cli upload --zip ./dist/bundle.zip

# 不同步白名单(需指定源版本 ID)
pmd-pixui-cli upload --whitelist-skip-sync 12345

# 指定全量同步的源版本 ID
pmd-pixui-cli upload --version-id-sync 12345

# 指定版本描述
pmd-pixui-cli upload --desc "修复登录 bug"

# 预发布模式上传
pmd-pixui-cli upload --mode preRelease

# 正式环境上传
pmd-pixui-cli upload --mode prod

# 组合使用:指定源版本 + 自定义描述
pmd-pixui-cli upload --version-id-sync 12345 --desc "从 v1.2.3 同步"

# 上线时下线同分支旧版本
pmd-pixui-cli upload --offline-old-version

# 将运行结果写入 notify-msg.md
pmd-pixui-cli upload --notify-msg

# 查看 upload 命令帮助
pmd-pixui-cli upload --help

输出示例

upload — 上传小应用版本包到 Pandora 平台
  app:         vpCampus (ID: 9194)
  env:         test
  sync mode:   自动获取最新版本 ID (模式 1)
──────────────────────────────────────────────────
✔ Latest version: 1.2.0 (ID: 12345)
✔ Created version: 1.2.1 (ID: 12346)
✔ Upload success. (5.2s)

注意事项

  1. 版本号自动递增:新版本号 = 最新版本号 + 0.0.1,也可通过 --version 手动指定
  2. 三种模式--mode test(默认,测试发布)、--mode preRelease(预发布)、--mode prod(正式发布)
  3. 同步决策:根据 --whitelist-skip-sync <id> / --version-id-sync <id> / --mode <mode> 三种互斥方式,详见同步模式章节
  4. 七彩石字段映射testversionIdpreReleasepreVersionIdprodprodVersionId
  5. 环境映射--mode=testenv="olsb"isLog="1"--mode=preRelease--mode=prodenv="prod"isLog="0"
  6. 版本描述:未指定时自动生成([分支名][提交标题][短hash]
  7. 旧版本下线:默认不下线旧版本,如需下线需指定 --offline-old-version
  8. notify-msg--notify-msg 将发布结果写入 notify-msg.md,用于流水线通知

whitepublish 命令

bash
pmd-pixui-cli whitepublish [options]

白名单发布命令,发布后只有白名单中的用户才能访问该版本。

流程

读取参数 → 从七彩石获取版本 ID → 调用 Pandora 白名单发布接口

可选参数

参数说明
--app-id <id>小应用 ID(不指定则读取 .pmd-devops/app.json
--branch <branch>分支名(不指定则读取当前 git 分支)
--mode <mode>模式:test(测试发布,默认)、preRelease(预发布)或 prod(正式)
--notify-msg将运行结果写入 notify-msg.md
--help / -h显示帮助

版本 ID 解析

根据 --mode 从七彩石读取对应字段:

mode七彩石字段说明
test(默认)versionId测试环境版本
preReleasepreVersionId预发布版本
prodprodVersionId正式环境版本

示例

bash
# 使用默认参数(从 app.json 和 git 获取)
pmd-pixui-cli whitepublish

# 指定 appId 和分支
pmd-pixui-cli whitepublish --app-id 9194 --branch feature/my-feature

# 预发布模式
pmd-pixui-cli whitepublish --mode preRelease

# 正式环境发布
pmd-pixui-cli whitepublish --mode prod

# 将结果写入 notify-msg.md
pmd-pixui-cli whitepublish --notify-msg

whitelist 命令

bash
pmd-pixui-cli whitelist <subcommand> [options]

白名单管理命令,提供 add / rm / clean / query 四个子命令。所有子命令纯参数驱动,不读取本地配置文件和 Git 信息。

通用参数

所有 whitelist 子命令支持 --mode 参数,用于指定版本解析模式:

参数说明
--mode <mode>模式:test(默认)、preRelease(预发布)或 prod(正式)

当使用 --branch 时,--mode 决定从七彩石读取哪个版本字段(同 whitepublish 的版本 ID 解析规则)。

子命令

whitelist add — 添加 openid
bash
pmd-pixui-cli whitelist add <openid...> --app-id <id> [options]
参数必填说明
<openid...>要添加的 openid(支持空格或逗号分隔多个)
--app-id <id>小应用 ID
--version-id <id>目标版本 ID(与 --branch 二选一)
--branch <branch>分支名(与 --version-id 二选一,从七彩石查询版本 ID)
--mode <mode>模式(默认 test
--dry-run只打印,不实际写入

6 平台并行同步:查询旧列表 → 合并去重 → 插入新列表 → 删除旧列表。

whitelist rm — 移除 openid
bash
pmd-pixui-cli whitelist rm <openid...> --app-id <id> [options]
参数必填说明
<openid...>要移除的 openid(支持空格或逗号分隔多个)
--app-id <id>小应用 ID
--version-id <id>目标版本 ID(与 --branch 二选一)
--branch <branch>分支名(与 --version-id 二选一,从七彩石查询版本 ID)
--mode <mode>模式(默认 test
--dry-run只打印,不实际写入
whitelist clean — 清除版本包白名单
bash
pmd-pixui-cli whitelist clean --app-id <id> [options]
参数必填说明
--app-id <id>小应用 ID
--version-id <id>目标版本 ID(与 --branch 二选一)
--branch <branch>分支名(与 --version-id 二选一,从七彩石查询版本 ID)
--mode <mode>模式(默认 test

⚠️ 不可逆操作,清除后所有白名单用户将无法访问该版本。

whitelist query — 查询 openid 是否在白名单
bash
pmd-pixui-cli whitelist query [options] <openid...>

调用 Pandora get_list 接口并发查询,客户端按 ';' 分隔后做大小写不敏感匹配。

参数必填说明
<openid...>要查询的 openid(支持空格或逗号分隔多个)
--app-id <id>小应用 ID
--version-id <id>目标版本 ID(与 --branch 二选一)
--branch <branch>分支名(与 --version-id 二选一,从七彩石查询版本 ID)
--mode <mode>模式(默认 test
--fallback主查询未命中时自动触发全分支兜底查询

环境变量

环境变量必填说明
PANDORA_TOKEN_TEST测试环境 Pandora API 访问令牌
PANDORA_TOKEN_PROD生产环境 Pandora API 访问令牌
PANDORA_SAASIDSaas ID(默认 0)
PANDORA_SECRET签名密钥
RAINBOW_APPID七彩石应用 ID
RAINBOW_USERID七彩石用户 ID
RAINBOW_SECRETKEY七彩石密钥

示例

bash
# 添加体验者
pmd-pixui-cli whitelist add openid_zhangsan openid_lisi --app-id 9194 --branch feature/pixui-pfbs

# 添加到预发布版本
pmd-pixui-cli whitelist add openid_zhangsan --app-id 9194 --branch feature/pixui-pfbs --mode preRelease

# 移除体验者
pmd-pixui-cli whitelist rm openid_zhangsan --app-id 9194 --branch feature/pixui-pfbs

# 清除版本白名单
pmd-pixui-cli whitelist clean --app-id 9194 --branch feature/already-merged

# 查询单个 openid
pmd-pixui-cli whitelist query --app-id 4724 --version-id 12345 oid1

# 查询分支对应版本中的多个 openid
pmd-pixui-cli whitelist query --app-id 4724 --branch feature/test oid1 oid2 oid3

# 逗号分隔多个 openid
pmd-pixui-cli whitelist query --app-id 4724 --version-id 12345 "oid1,oid2"

# 主查询未命中时自动兜底扫描其他分支
pmd-pixui-cli whitelist query --app-id 4724 --version-id 12345 --fallback oid1

提示:位置参数 <openid...> 与命名选项(--app-id 等)顺序不限,"oid1,oid2" 写在前面或后面均可。


config 命令

bash
pmd-pixui-cli config --type <type> [options]

必填参数

参数缩写说明
--type-t配置类型 (bundle)

可选参数

参数缩写说明
--dry-run仅输出配置内容,不写入文件
--output-o输出文件路径
--help-h显示帮助

示例

bash
# 生成 bundle 配置文件
pmd-pixui-cli config -t bundle

# 仅输出配置内容(不写入文件)
pmd-pixui-cli config --type bundle --dry-run

# 指定输出路径
pmd-pixui-cli config -t bundle -o ./custom-bundle.config.json

输出示例

Generated: /path/to/bundle.config.json
Bundle Version: 1.0.1

退出码

所有命令统一使用 0/1 退出码,由 bin/index.jshandleAction 包装函数统一管理:

含义
0成功
1错误(详情输出到 stderr)

源文件中不再有任何 process.exit() 调用。错误通过 throw 传递到 handleAction,统一以 exit code 1 退出。bundle 命令不调用 process.exit(0),让事件循环自然排空后在 Node.js 层面自行退出,避免截断文件写入流。

CI/CD 集成

蓝盾流水线

yaml
steps:
  - name: Build Frontend
    script: npm run build

  - name: PFBS Encode
    script: npx pmd-pixui-cli pfbs -d dist -v 0.5 -o dist-pfbs --clean

  - name: Deploy
    script: upload dist-pfbs/ to CDN

Shell 脚本

bash
#!/bin/bash
set -e

npm run build
pmd-pixui-cli pfbs -d dist -v 0.5 -o dist-pfbs --clean

# 检查退出码
if [ $? -eq 0 ]; then
  echo "PFBS encode success, deploying..."
  # deploy dist-pfbs/
fi

工作原理

pfbs 命令

dist/                              dist-pfbs/
├── index.html  ──── pfbs ────→         ├── index.html      (Buffer)
├── pages/                              ├── pages/
│   └── about.html ─ pfbs ───→          │     └── about.html   (Buffer)
├── js/                                 ├── js/
│   └── app.js ───── pfbs ────→         │     └── app.js       (Buffer)
├── css/                                ├── css/
│   └── style.css ── copy ────→         │     └── style.css    (原样)
└── images/                             └── images/
    └── logo.png ─── copy ────→               └── logo.png     (原样)

底层依赖 @novlan/pfbs(v2.x),通过调用平台原生 pfbs 二进制完成编码:

  • macOS: pfbs
  • Linux: pfbs-linux
  • Windows: pfbs.exe

bundle 命令

项目目录/                         .bundles/
├── dist/.build/html-pro/  ─┐
├── assets/images/         ─┤
├── unity/Assets/...        ─┼──→  my-app-1.1.0.zip (版本包)
└── bundle.config.js        ─┘

底层依赖 gamelet-bundle 完成打包。

扩展新命令

要添加新命令(如 optimize),只需:

  1. src/ 目录创建新的 TypeScript 文件(如 optimize.ts
  2. 导出命令函数(如 export async function optimize(opts: OptimizeOptions): Promise<void>
  3. src/index.ts 中添加导出
  4. bin/index.js 中添加 Commander 命令定义
  5. 更新本文档中的命令列表

详细开发指南请参考 bin/index.js 中的 Commander 用法。

开发注意事项

1. 禁止在业务函数内调用 process.exit()

源文件(src/*.ts)中的命令函数不得在成功路径调用 process.exit(),应改为 return 或通过抛出异常让调用方处理。

原因process.exit() 立即杀死 Node.js 进程,不会等待异步文件流(如 fs.WriteStream)刷盘,会导致打包产物(.zip)不完整或损坏。

Note:对于 gamelet-bundle 这类第三方库,其内部的 WriteStream 可能在 await bundle() resolve 后尚未完成刷盘。解决方案是在业务函数返回前主动等待一个 event loop tick:

ts
// bundle.ts
await bundle(config);

// 等待一个 tick,让 WriteStream 的 finish 回调全部触发
await new Promise<void>(resolve => setImmediate(resolve));

return { success: true };

setImmediate 在 Node.js 事件循环的 check 阶段执行,此时所有 I/O 回调(含 finish)均已处理完毕,数据已提交到内核 page cache,后续 process.exit() 不会被截断。

2. CLI action 必须显式退出

所有 bin/index.js 中的 Commander action 末尾必须显式调用 process.exit(),因为 Commander.js 可能持有未释放的事件监听器导致进程挂起。目前通过统一的 handleAction 包装函数实现了这一规范。bundle 命令因上述 setImmediate 保障,已和其他命令一样使用 handleAction

js
function handleAction(fn) {
  return async (...args) => {
    try {
      await fn(...args);
      process.exit(0);
    } catch (err) {
      console.error(`Error: ${err.message}`);
      process.exit(1);
    }
  };
}

3. 退出码规范

所有命令统一使用 0/1 退出码,由 handleAction 统一管理。源文件中不再有任何 process.exit() 调用。

退出码含义
0成功
1错误

4. 终端样式辅助函数

命令行帮助文本和日志输出中禁止使用原始的 \x1b ANSI 转义码,应使用 helper/symbols.ts 中导出的样式函数:

ts
import { bold, yellow } from './helper/symbols';

console.log(`${bold('title')} — description`);
console.log(`${yellow('Usage:')}`);

当前支持的样式函数:

函数效果
bold(text)粗体
yellow(text)黄色前景

如需新增样式(如红色、绿色),在 src/helper/symbols.ts 中添加:

ts
export const red = ansi('31', '0');
export const green = ansi('32', '0');

本地开发

bash
# 构建
pnpm --filter="./packages/pixui-cli" build

# 测试命令
node packages/pixui-cli/bin/index.js pfbs -d ./test-dist -v 0.5
node packages/pixui-cli/bin/index.js bundle
node packages/pixui-cli/bin/index.js config -t bundle --dry-run
node packages/pixui-cli/bin/index.js upload
node packages/pixui-cli/bin/index.js upload --whitelist-skip-sync 12345
node packages/pixui-cli/bin/index.js upload --mode preRelease
node packages/pixui-cli/bin/index.js upload --help
node packages/pixui-cli/bin/index.js whitepublish
node packages/pixui-cli/bin/index.js whitepublish --app-id 9194 --branch feature/xxx
node packages/pixui-cli/bin/index.js whitepublish --mode preRelease
node packages/pixui-cli/bin/index.js whitelist add openid_test --app-id 9194 --branch feature/xxx
node packages/pixui-cli/bin/index.js whitelist clean --app-id 9194 --branch feature/xxx
node packages/pixui-cli/bin/index.js whitelist query --app-id 9194 --version-id 12345 oxxxxx

更新日志

点此查看