Skip to content

启动清单(Startup Manifest)

Egg 提供了启动清单(Manifest)机制,通过缓存文件发现和模块解析结果来加速应用的冷启动。

原理

应用每次启动时,框架需要执行大量文件系统操作:

  • 模块解析:数百次 fs.existsSync 调用,探测 .ts.js.mjs 等后缀
  • 文件发现:多次 globby.sync 扫描插件、配置、扩展等目录
  • tegg 模块扫描:遍历模块目录,import() 装饰器文件收集元数据

Manifest 机制在首次启动时收集这些结果,写入 .egg/manifest.json。后续启动直接读取缓存,跳过重复的文件 I/O。

性能提升

在容器冷启动场景下(无文件系统缓存),以 cnpmcore 项目实测:

指标无 Manifest有 Manifest提升
应用启动~980ms~780ms~20%
文件加载~660ms~490ms~26%
加载 app.js~280ms~150ms~46%

注意:在本地开发环境中,操作系统的页面缓存(page cache)会使文件 I/O 接近零开销,因此提升不明显。Manifest 主要优化的是容器冷启动、CI/CD 等无缓存场景。

使用方式

通过 CLI 管理(推荐)

egg-bin 提供了 manifest 命令来管理启动清单:

生成清单

bash
# 为生产环境生成
$ egg-bin manifest generate --env=prod

# 指定环境和作用域
$ egg-bin manifest generate --env=prod --scope=aliyun

# 指定框架
$ egg-bin manifest generate --env=prod --framework=yadan

生成过程会以 metadataOnly 模式启动应用(跳过生命周期钩子,只收集元数据),然后将结果写入 .egg/manifest.json

验证清单

bash
$ egg-bin manifest validate --env=prod

输出示例:

[manifest] Manifest is valid
[manifest]   version: 1
[manifest]   generatedAt: 2026-03-29T12:13:18.039Z
[manifest]   serverEnv: prod
[manifest]   serverScope:
[manifest]   resolveCache entries: 416
[manifest]   fileDiscovery entries: 31
[manifest]   extension entries: 1

如果清单无效或不存在,命令将以非零退出码退出。

清理清单

bash
$ egg-bin manifest clean

自动生成

应用正常启动后,框架会在 ready 阶段自动生成清单(通过 dumpManifest)。下次启动时如果清单有效,则自动使用。

清单失效机制

清单包含指纹信息,以下情况会自动失效:

  • 锁文件变更pnpm-lock.yamlpackage-lock.jsonyarn.lock 的修改时间或大小变化
  • 配置目录变更config/ 目录下的文件发生变化(基于 MD5 指纹)
  • 环境不匹配serverEnvserverScope 与清单中记录的不一致
  • TypeScript 状态变更EGG_TYPESCRIPT 启用/禁用状态发生变化
  • 版本不匹配:清单格式版本号不一致

清单失效时,框架会回退到正常的文件发现流程,不会影响启动。

环境变量

变量说明默认值
EGG_MANIFEST在本地环境启用清单false(本地环境默认不加载清单)

本地开发环境(serverEnv=local)默认不加载清单,因为开发时文件频繁变更,清单容易失效。设置 EGG_MANIFEST=true 可强制启用。

部署建议

容器化部署

在 Dockerfile 中,构建完成后生成清单:

dockerfile
# 安装依赖并构建
RUN npm install --production
RUN npm run build

# 生成启动清单
RUN npx egg-bin manifest generate --env=prod

# 启动应用(将自动使用清单)
CMD ["npm", "start"]

CI/CD 流水线

在构建阶段生成清单,随制品一起部署:

bash
# 构建
npm run build

# 生成清单
npx egg-bin manifest generate --env=prod

# 验证清单
npx egg-bin manifest validate --env=prod

# 打包(包含 .egg/manifest.json)
tar -zcvf release.tgz .

注意事项

  1. 清单与环境绑定:清单绑定了 serverEnvserverScope(部署类型,如 aliyun),不同环境或部署类型需要分别生成
  2. 依赖变更后需重新生成:安装或更新依赖后,锁文件变更会自动使清单失效
  3. .egg 目录:清单存储在 .egg/manifest.json,建议将 .egg/ 加入 .gitignore
  4. 回退安全:清单缺失或无效时,框架会自动回退到正常流程,不会导致启动失败
  5. metadataOnly 模式manifest generate 不会启动完整的应用生命周期,不会连接数据库或外部服务

清单结构

json
{
  "version": 1,
  "generatedAt": "2026-03-29T12:13:18.039Z",
  "invalidation": {
    "lockfileFingerprint": "pnpm-lock.yaml:1711234567890:12345",
    "configFingerprint": "a1b2c3d4e5f6...",
    "serverEnv": "prod",
    "serverScope": "",
    "typescriptEnabled": true
  },
  "extensions": {
    "tegg": { ... }
  },
  "resolveCache": {
    "config/plugin": "config/plugin.ts",
    "config/plugin.default": null
  },
  "fileDiscovery": {
    "app/middleware": ["trace.ts", "auth.ts"]
  }
}

Born to build better enterprise frameworks and apps