Skip to content

构建与部署 ​

在不同平台之间切换不需要改代码:构建时选择的 preset 决定产物形态和部署方式。

bash
npx cell build                                # preset node:.cell/output
npx cell build --preset cloudflare
npx cell deploy --preset fc --dry-run         # 只给出计划,不上传

preset 的来源依次是:--preset,cell.config.ts 的 preset,CELL_PRESET 环境变量,CI 平台识别(Workers Builds 中为 cloudflare,Vercel 上为 vercel),最后是 node。npx cell info 会显示用的是哪个以及原因。

preset ​

preset产物本地运行部署
node(默认)Node.js HTTP 服务,server/index.mjscell preview把 .cell/output 拷到任何能运行 Node.js 18+、Bun 或 Deno 的地方
cli基于 Cell DI 的命令行程序,不起 HTTP 服务cell preview分发文件或可执行文件
cloudflareWorker + 静态资源 + wrangler.jsoncell preview(经 Wrangler 在 workerd 中运行)cell deploy --preset cloudflare
fc阿里云函数计算 3.0 自定义运行时cell previewcell deploy --preset fc
scf腾讯云 SCF Web 函数cell previewcell deploy --preset scf
lambdaAWS Lambda + 函数 URLcell previewcell deploy --preset lambda
vercelVercel Build Output API(.vercel/output)cell previewcell deploy --preset vercel

产物 ​

text
.cell/output/
├── server/index.mjs     # 后端:内联了全部依赖的单个 ES 模块
├── public/              # 前端产物(有前端时)
└── manifest.json        # preset、格式、目标:cell preview 和 cell deploy 读取它

产物不需要项目的 node_modules。无法打包的包(原生模块、cell.config.ts 的 build.external)会拷到 server/node_modules。

选项结果
--single前端内嵌进 server/index.mjs:一个文件运行整个应用
--compile [bun|node|deno]可执行文件 .cell/output/app,主机上不需要 Node.js
-m <mode>额外读取 cell.<mode>.yml(构建时 production 总是生效)
--sourcemap、--format cjs、--out-dir <dir>source map、CommonJS 产物、其他输出目录

生产环境的配置 ​

  • 后端配置在服务端启动时求值。 同一份产物到处运行;各环境的值通过环境变量给出:在 cell.yml 里引用("${env.DATABASE_URL}"),或直接覆盖(CELL_SERVER__PORT=8080)。见项目结构与配置。
  • 不要把密钥标成 public。 配置默认只在服务端,只有 schema 标记为 public 的键和 app.public 会进前端;前端的值在构建时求值并发给浏览器。
  • 服务默认监听 127.0.0.1:3000。容器里设置 CELL_SERVER__HOST=0.0.0.0;平台通过 PORT 给端口时设置 CELL_SERVER__PORT='${env.PORT}'。
  • 设置自己的 web.cookies.keys(cookie 和 session 的签名密钥),例如 CELL_WEB__COOKIES__KEYS='["..."]'。
  • 安全检查。 cell check 会列出在生产环境不安全的设置(CELL_SECURITY_* 警告:开发用的 cookie 密钥、过短的 jwt.secret 等)。生产启动时(NODE_ENV=production,cell build 会把它写进服务端产物)同样会把这些警告写进日志;设置 securityChecks: fail(或 CELL_SECURITY_CHECKS=fail)则拒绝启动,off 则不检查。
  • 错误信息。 生产环境下服务端错误只返回状态文本(Internal Server Error),错误信息和调用栈写进日志;4xx 的 HttpError 信息照常返回。可用 web.errors.exposeMessages 改变这一行为。

容器镜像 ​

dockerfile
FROM node:22-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npx cell build

FROM node:22-alpine
ENV NODE_ENV=production
ENV CELL_SERVER__HOST=0.0.0.0
WORKDIR /app
COPY --from=build --chown=node:node /app/.cell/output ./
USER node
EXPOSE 3000
CMD ["node", "server/index.mjs"]

cell deploy ​

cell deploy 用 preset 构建,生成计划(要创建或更新的资源),再执行它。--dry-run 到计划为止,没有凭据也能用;--skip-build 部署已有的产物。

preset凭据(环境变量)cell.config.ts 中的平台选项
cloudflareCLOUDFLARE_API_TOKEN(及 CLOUDFLARE_ACCOUNT_ID),或 npx wrangler login项目根目录的 wrangler.jsonc:名称、vars、绑定、routes
fcALIBABA_CLOUD_ACCESS_KEY_ID、ALIBABA_CLOUD_ACCESS_KEY_SECRETfc: { name, region, memory, cpu, timeout, concurrency, env }
scfTENCENTCLOUD_SECRET_ID、TENCENTCLOUD_SECRET_KEYscf: { name, region, namespace, memory, timeout, env }
lambdaAWS_ACCESS_KEY_ID、AWS_SECRET_ACCESS_KEY,或 AWS_PROFILElambda: { name, region, architecture, memory, timeout, role, env }
vercelVERCEL_TOKEN,或 npx vercel loginvercel: { project, scope, environment, memory, maxDuration, regions }
ts
// cell.config.ts
import { defineConfig } from '@celljs/cli';

export default defineConfig({
    preset: 'fc',
    fc: { region: 'cn-shanghai', memory: 512, env: { DATABASE_URL: process.env.DATABASE_URL ?? '' } },
});

函数平台(fc、scf、lambda)直接调用云 API,不安装云厂商的 SDK 或 CLI。Wrangler 和 Vercel CLI 优先用项目里安装的,否则经 npx 使用。每种失败都有错误码:CELL_DEPLOY_CREDENTIALS_MISSING、CELL_DEPLOY_UNAUTHORIZED、CELL_DEPLOY_PACKAGE_TOO_LARGE……

各平台的细节(自定义域名、运行时、代码包大小上限、部署器会创建什么)见 CLI 文档。

hooks ​

在工具链事件上执行 shell 命令,用于代码生成之类的步骤:

ts
export default defineConfig({
    hooks: {
        'build:before': 'prisma generate',                      // 失败会取消构建
        'output:done': 'cp extra/* "$CELL_OUT_DIR/server/"',
    },
});

需要写代码的扩展(Vite 插件、额外的产物文件、检查项、MCP 工具)写成 toolchain 模块,见 CLI 文档。