morphe

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Morphe Deploy

Morphe 部署

Overview

概述

Deploy a Next.js, Bigfish (
@alipay/bigfish
), or Vite project to Morphe (runtime
custom.debian11
, linux-x64-gnu). The runtime always starts the function with
node server.js
, so every framework packages down to a zip whose root is a
server.js
:
  • Next.js → the standalone server (
    .next/standalone/server.js
    ) plus its traced
    node_modules
    . Packaging prunes wrong-platform native bindings and repairs pnpm partial packages.
  • Bigfish → a static / SPA build (
    dist/
    ). Packaging generates a zero-dependency static
    server.js
    (Node built-ins only — nothing to install) that serves the build dir with SPA fallback to
    index.html
    .
  • Vite → two modes. A pure SPA (
    vite build
    dist/
    , no server) reuses the same zero-dependency static wrapper as Bigfish. A custom-server app (a
    server.ts
    /
    server.js
    , e.g. Express, that serves
    dist/
    and backend API routes) is esbuild-bundled into a self-contained
    server.js
    at the zip root, with the build dir alongside it.
The fragile, deterministic API work (auth, presign, upload, CRC64,
.morphe.json
, deploy) lives in
scripts/morphe.py
. The build/config judgment steps are done by you.
Run all
scripts/morphe.py
commands from the project root. Replace
SKILL_DIR
below with this skill's directory (the folder containing this file).
Next.jsBigfish
@alipay/bigfish
)或Vite项目部署到Morphe(运行时为
custom.debian11
,linux-x64-gnu)。运行时始终通过
node server.js
启动服务,因此每个框架都需要打包为根目录包含
server.js
的压缩包:
  • Next.js → 独立服务器(
    .next/standalone/server.js
    )及其追踪到的
    node_modules
    。打包过程会剔除错误平台的原生绑定,并修复pnpm的部分包问题。
  • Bigfish → 静态/SPA构建产物(
    dist/
    )。打包过程会生成一个零依赖的静态
    server.js
    (仅使用Node内置模块——无需安装任何依赖),用于提供构建目录的服务,并支持SPA路由回退到
    index.html
  • Vite → 两种模式。纯SPA(
    vite build
    dist/
    ,无服务器)会复用与Bigfish相同的零依赖静态包装器。自定义服务器应用(包含
    server.ts
    /
    server.js
    ,例如Express,同时提供
    dist/
    静态资源和后端API路由)会通过esbuild打包为自包含的
    server.js
    ,放在压缩包根目录,构建目录与其同级。
复杂且确定性的API操作(认证、预签名、上传、CRC64校验、
.morphe.json
管理、部署)都在
scripts/morphe.py
中实现。构建/配置判断步骤由你完成。
从项目根目录运行所有
scripts/morphe.py
命令。将下方的
SKILL_DIR
替换为该技能的目录(包含此文件的文件夹)。

Workflow

工作流程

Execute these steps in order. Stop and report if any step fails.
按顺序执行以下步骤。若任何步骤失败,立即停止并报告。

1. Ensure logged in

1. 确保已登录

bash
python3 SKILL_DIR/scripts/morphe.py check-auth
  • Exit 0 → already logged in (valid
    accessToken
    in
    ~/.morphe/auth.json
    ). Continue.
  • Exit 1 → not logged in. Ask the user for their username and password, then:
bash
python3 SKILL_DIR/scripts/morphe.py login --username "USER" --password "PASS"
Never echo the password back. On success the token is saved to
~/.morphe/auth.json
. If login fails (e.g. HTTP 401), report the error and stop.
bash
python3 SKILL_DIR/scripts/morphe.py check-auth
  • 退出码0 → 已登录(
    ~/.morphe/auth.json
    中存在有效的
    accessToken
    )。继续执行。
  • 退出码1 → 未登录。向用户索要用户名密码,然后执行:
bash
python3 SKILL_DIR/scripts/morphe.py login --username "USER" --password "PASS"
切勿回显密码。登录成功后,令牌将保存到
~/.morphe/auth.json
。若登录失败(例如HTTP 401),报告错误并停止。

2. Detect the framework

2. 检测框架

bash
python3 SKILL_DIR/scripts/morphe.py detect-framework --project-root .
Prints
nextjs
,
bigfish
,
vite
, or
unknown
(exit 1). Detection is ordered (first match wins):
  • bigfish
    @alipay/bigfish
    in
    package.json
    deps, or a
    config/config.ts
    exists (checked first; Bigfish projects also have next-like build scripts and vite-style tooling).
  • nextjs
    next
    in deps, or a
    next.config.{js,mjs,ts}
    exists.
  • vite
    vite
    in deps, or a
    vite.config.{js,mjs,ts,mts,cjs}
    exists (checked last; it's the broadest).
If it prints
unknown
, tell the user "暂不支持该项目类型(仅支持 Next.js、Bigfish 与 Vite)" and stop. Otherwise remember the framework — it selects the build and packaging path below.
bash
python3 SKILL_DIR/scripts/morphe.py detect-framework --project-root .
输出
nextjs
bigfish
vite
unknown
(退出码1)。检测顺序为(匹配到第一个即停止):
  • bigfish
    package.json
    依赖中包含
    @alipay/bigfish
    ,或存在
    config/config.ts
    (优先检测;Bigfish项目也有类似Next.js的构建脚本和Vite风格的工具链)。
  • nextjs — 依赖中包含
    next
    ,或存在
    next.config.{js,mjs,ts}
  • vite — 依赖中包含
    vite
    ,或存在
    vite.config.{js,mjs,ts,mts,cjs}
    (最后检测;范围最广)。
若输出
unknown
,告知用户“暂不支持该项目类型(仅支持 Next.js、Bigfish 与 Vite)”并停止。否则记录检测到的框架——它将决定后续的构建和打包流程。

3. Resolve the function name

3. 确定函数名称

Ask the user what function name to deploy under. Tell them: 如果不知道填什么, 可以留空,会自动生成一个
user-xxxxxxxx
格式的随机函数名。
  • If
    .morphe.json
    already has a
    function_name
    , mention it as the current default and let the user keep it (just press enter) or override.
  • Persist the choice (empty input → keep existing or generate):
bash
undefined
询问用户要部署到哪个函数名称下。告知用户:如果不知道填什么,可以留空,会自动生成一个
user-xxxxxxxx
格式的随机函数名。
  • .morphe.json
    中已存在
    function_name
    ,将其作为当前默认值告知用户,允许用户保留(直接按回车)或覆盖。
  • 保存用户的选择(空输入 → 保留现有名称或自动生成):
bash
undefined

user provided a name:

用户提供了名称:

python3 SKILL_DIR/scripts/morphe.py set-function-name --name "NAME" --project-root .
python3 SKILL_DIR/scripts/morphe.py set-function-name --name "NAME" --project-root .

user left it blank:

用户留空:

python3 SKILL_DIR/scripts/morphe.py set-function-name --project-root .

The command prints the final function name and writes it to `.morphe.json`.
This name is reused on every redeploy, so the same function is updated.
python3 SKILL_DIR/scripts/morphe.py set-function-name --project-root .

该命令会输出最终的函数名称并写入`.morphe.json`。后续重新部署时会复用此名称,从而更新同一个函数。

4. Validate & fix the build config

4. 验证并修复构建配置

Steps 4–6 differ by framework. Follow the branch for the framework detected in step 2.
步骤4–6因框架而异。根据步骤2中检测到的框架执行对应分支。

4a. Next.js

4a. Next.js

The goal: the runtime target (
linux-x64-gnu
) binary of every native dep must be installed on disk before the build, so Next's tracer can pick it up. The
morphe.py package
step (step 6) handles top-level placement, pruning, and zipping — but it can only ship a binary that the install actually downloaded.
Edit the config in place to ensure:
  1. standalone output
    output: "standalone"
    (else there is no
    .next/standalone/
    to zip).
  2. Install the linux binaries on the build host. Native addons ship as per-platform optional deps; a macOS install only fetches the darwin one.
    • pnpm (
      pnpm-workspace.yaml
      ) — add
      supportedArchitectures
      so the linux-x64-gnu binaries are fetched too. This is the single most important fix; with it, the tracer auto-includes the binding and you usually need NO
      outputFileTracingIncludes
      at all:
      yaml
      supportedArchitectures:
        os: [current, linux]
        cpu: [current, x64]
        libc: [current, glibc]
      Then re-run
      pnpm install
      .
    • npm/yarn — install the specific binding(s) for the target, e.g.
      npm i --no-save @resvg/resvg-js-linux-x64-gnu --force --os=linux --cpu=x64 --libc=glibc
      .
  3. (Optional) trim the bundle further.
    morphe.py package
    already prunes every non-linux-x64-gnu native binary, so you do NOT need
    outputFileTracingExcludes
    for those. Only add excludes for project data the server doesn't need at runtime (large fixtures, raw datasets, docs). Keep anything read at runtime via
    process.cwd()
    (fonts, JSON the route reads).
See
references/nextjs-config.md
for details, per-package binding names, and how to confirm the linux binary is on disk.
目标:在构建前,确保每个原生依赖的目标运行时(
linux-x64-gnu
)二进制文件已安装到本地磁盘,以便Next.js的追踪器能捕获到它。
morphe.py package
步骤(步骤6)会处理顶级目录放置、剔除和压缩——但它只能打包安装过程中实际下载的二进制文件。
就地编辑配置以确保:
  1. 独立模式输出
    output: "standalone"
    (否则没有
    .next/standalone/
    可供压缩)。
  2. 在构建主机上安装Linux二进制文件。原生扩展以按平台可选依赖的形式发布;macOS环境下仅会下载darwin版本。
    • pnpm(存在
      pnpm-workspace.yaml
      ) — 添加
      supportedArchitectures
      ,以便同时获取linux-x64-gnu二进制文件。这是最重要的修复;配置后,追踪器会自动包含绑定,通常完全不需要
      outputFileTracingIncludes
      yaml
      supportedArchitectures:
        os: [current, linux]
        cpu: [current, x64]
        libc: [current, glibc]
      然后重新运行
      pnpm install
    • npm/yarn — 安装目标平台的特定绑定,例如
      npm i --no-save @resvg/resvg-js-linux-x64-gnu --force --os=linux --cpu=x64 --libc=glibc
  3. (可选)进一步精简包体积
    morphe.py package
    已经会剔除所有非linux-x64-gnu的原生二进制文件,因此你不需要为这些文件设置
    outputFileTracingExcludes
    。仅需排除服务器运行时不需要的项目数据(大型测试用例、原始数据集、文档)。保留所有通过
    process.cwd()
    在运行时读取的文件(字体、路由读取的JSON文件)。
详情请参考
references/nextjs-config.md
,其中包含各包的绑定名称以及如何确认Linux二进制文件已安装到本地的方法。

4b. Bigfish

4b. Bigfish

No native-binding work — Bigfish builds a static / SPA bundle and
morphe.py package
generates a zero-dependency
server.js
(Node built-ins only). There is nothing to install for the linux target and no config to patch in the common case.
  • Confirm the app builds to a static bundle. A default Bigfish
    site
    build emits
    dist/
    (
    index.html
    + hashed JS/CSS), which is what the generated static server serves.
    deployMode: 'render'
    (SSR) is not covered by this static wrapper — if the app truly needs server-side rendering at runtime, stop and tell the user the static path won't serve their SSR routes.
  • If the build output dir is not
    dist/
    (Bigfish lets you override it), note the dir name; you'll pass it via
    --static-dir
    in step 6.
无需处理原生绑定——Bigfish构建的是静态/SPA包,
morphe.py package
会生成一个零依赖
server.js
(仅使用Node内置模块)。通常无需为Linux目标安装任何依赖或修改配置。
  • 确认应用构建为静态包。默认的Bigfish
    site
    构建会生成
    dist/
    index.html
    + 带哈希的JS/CSS),这正是生成的静态服务器所服务的内容。
    deployMode: 'render'
    (SSR)不适用此静态包装器——如果应用确实需要运行时服务端渲染,停止并告知用户静态部署方式无法支持其SSR路由。
  • 若构建输出目录不是
    dist/
    (Bigfish允许自定义),记录该目录名称;在步骤6中通过
    --static-dir
    参数传入。

4c. Vite

4c. Vite

Vite has two modes;
morphe.py package
(step 6) auto-detects which by probing for a server entry (
server.{ts,js,mjs,cjs}
, also under
src/
).
  • Pure SPA (no server entry) — nothing to install or patch, exactly like Bigfish.
    vite build
    emits
    dist/
    (
    index.html
    + hashed assets) and the generated zero-dependency static
    server.js
    serves it with SPA fallback. If the output dir isn't
    dist/
    , note it for
    --static-dir
    in step 6.
  • Custom-server (a
    server.ts
    /
    server.js
    serving
    dist/
    and API routes) —
    package
    will esbuild-bundle that entry into a self-contained
    server.js
    . Make sure the server:
    1. listens on
      process.env.PORT || 3000
      and binds
      0.0.0.0
      (the runtime sets
      PORT
      and routes to all interfaces);
    2. reads its static dir from
      process.cwd()
      (e.g.
      path.join(process.cwd(), "dist")
      ), since the zip ships the build dir alongside
      server.js
      at the runtime working dir;
    3. keeps any
      vite
      import dev-only.
      vite
      is always externalized from the bundle (it's huge and pulls in native
      .node
      addons — esbuild/ lightningcss/fsevents — that can't be bundled and break the build). A production server must not load it. Put any dev-middleware vite usage behind a lazy, non-production branch, e.g.:
      ts
      if (process.env.NODE_ENV !== "production") {
        const { createServer } = await import("vite");  // lazy: never bundled
        // ... dev middleware
      }
    Runtime secrets (API keys, etc.) belong in the function environment, not in the zip — the build never bundles your
    .env
    .
    • If your server needs an extra package kept out of the bundle (e.g. a native
      .node
      addon esbuild can't inline), pass it via
      --external NAME
      in step 6 — but then that package must be reachable at runtime (this is an edge case; most pure-JS deps bundle fine).
Vite有两种模式;
morphe.py package
(步骤6)会通过探测服务器入口文件(
server.{ts,js,mjs,cjs}
,也包括
src/
目录下的文件)自动检测模式。
  • 纯SPA(无服务器入口) — 无需安装或修改配置,与Bigfish完全相同。
    vite build
    生成
    dist/
    index.html
    + 带哈希的资源),生成的零依赖静态
    server.js
    会提供服务并支持SPA路由回退。若输出目录不是
    dist/
    ,记录该目录名称以便在步骤6中传入
    --static-dir
  • 自定义服务器(包含
    server.ts
    /
    server.js
    ,同时提供
    dist/
    静态资源和API路由) —
    package
    会将入口文件通过esbuild打包为自包含的
    server.js
    。确保服务器:
    1. 监听
      process.env.PORT || 3000
      并绑定
      0.0.0.0
      (运行时会设置
      PORT
      并路由到所有接口);
    2. process.cwd()
      读取静态目录
      (例如
      path.join(process.cwd(), "dist")
      ),因为压缩包会将构建目录与
      server.js
      放在运行时工作目录的同级;
    3. 仅在开发环境导入
      vite
      vite
      会被强制排除在包外(体积庞大且会引入无法打包的原生
      .node
      扩展——如esbuild/lightningcss/fsevents——导致构建失败)。生产服务器绝不能加载它。将所有开发中间件的vite使用放在惰性加载的非生产分支中,例如:
      ts
      if (process.env.NODE_ENV !== "production") {
        const { createServer } = await import("vite");  // 惰性加载:不会被打包
        // ... 开发中间件逻辑
      }
    运行时密钥(API密钥等)应放在函数环境变量中,而非压缩包内——构建过程绝不会打包你的
    .env
    文件。
    • 若服务器需要将某个额外包排除在打包外(例如esbuild无法内联的原生
      .node
      扩展),在步骤6中通过
      --external NAME
      参数传入——但该包必须在运行时可访问(这是边缘情况;大多数纯JS依赖都能正常打包)。

5. Build

5. 构建

bash
npm run build   # or: pnpm build / yarn build  (Bigfish: also `bigfish build`)
Do NOT hand-copy assets or hand-zip — step 6 does all assembly. (Vite: run only the frontend build here to produce
dist/
. For a custom-server app you do not need to bundle the server yourself —
package
runs esbuild for you in step 6. If your
build
script already esbuilds the server, that's harmless;
package
re-bundles into the staged zip regardless.)
bash
npm run build   # 或:pnpm build / yarn build (Bigfish也可执行 `bigfish build`)
切勿手动复制资源或手动压缩——步骤6会完成所有组装工作。(Vite:此处仅运行前端构建以生成
dist/
。对于自定义服务器应用,你不需要自行打包服务器——
package
会在步骤6中通过esbuild为你完成打包。若你的
build
脚本已经包含esbuild打包服务器的逻辑,也不会有问题;
package
会重新打包并放入临时压缩包中。)

6. Assemble the minimal deploy zip

6. 组装最小化部署压缩包

bash
python3 SKILL_DIR/scripts/morphe.py package --project-root .
package
auto-detects the framework (override with
--framework nextjs|bigfish|vite
). It is idempotent (safe to re-run, but re-run the build first if you changed code).
Next.js — assembles
.next/standalone
into a runnable zip:
  • copies
    .next/static
    and
    public/
    into the bundle (not traced by the build);
  • repairs pnpm partial packages — top-level
    node_modules/<pkg>
    dirs that hold only
    package.json
    while the real files live in
    .pnpm
    (this shadowing is what crashes
    node server.js
    with e.g. Cannot find module
    @swc/helpers/cjs/_interop_require_default.cjs
    );
  • prunes every native binding that isn't
    linux-x64-gnu
    (darwin/musl/arm64 — often 100M+) and symlinks the kept linux bindings to top-level node_modules, where the runtime resolves them with a bare
    require("<pkg>-linux-x64-gnu")
    . Missing this is why SVG-style code paths work but anything hitting the native addon 500s with Cannot find module
    …-linux-x64-gnu
    ;
  • zips with symlinks preserved (
    zip -y
    )
    to
    ./code.zip
    OUTSIDE the standalone dir (so it never nests a previous
    code.zip
    ). The runtime preserves symlinks, and pnpm's layout is mostly symlinks into
    .pnpm
    , so this roughly halves the zip.
Bigfish — assembles a static-server zip:
  • locates the build output dir (auto-probes
    dist
    ,
    build
    ,
    out
    for one containing
    index.html
    ; override with
    --static-dir DIR
    );
  • generates a zero-dependency
    server.js
    (Node
    http
    /
    fs
    /
    path
    only) that serves the build dir and falls back to
    index.html
    for client-side routes;
  • stages
    server.js
    + the build dir and zips so
    server.js
    is at the zip root with the build dir alongside it. No
    node_modules
    , so the zip is small.
Vite — two modes, auto-selected by probing for a server entry:
  • SPA (no server entry found) — identical to the Bigfish path above: a generated zero-dependency static
    server.js
    + the build dir.
  • Custom-server (a
    server.{ts,js,mjs,cjs}
    entry, auto-probed; force/override with
    --server-entry PATH
    ) — esbuild-bundles the entry (
    --bundle --platform=node --format=cjs
    ,
    vite
    always external
    , plus any
    --external NAME
    you pass) into a self-contained
    server.js
    , then stages it with the build dir (auto-probes
    dist
    /
    build
    /
    out
    , override
    --static-dir
    ) and zips so
    server.js
    is at the zip root. Deps are inlined, so no
    node_modules
    ships.
It prints the final path, size, and framework, e.g.
packaged: …/code.zip (25M)
or
packaged: …/code.zip (0.2M, framework=bigfish)
or
packaged: …/code.zip (0.7M, framework=vite, mode=server, entry=server.ts)
.
bash
python3 SKILL_DIR/scripts/morphe.py package --project-root .
package
会自动检测框架(可通过
--framework nextjs|bigfish|vite
参数手动指定)。该操作是幂等的(可安全重复运行,但如果修改了代码,需先重新运行构建)。
Next.js — 将
.next/standalone
组装为可运行的压缩包:
  • .next/static
    public/
    复制到包中(这些文件不会被构建过程追踪);
  • 修复pnpm的部分包问题——顶级
    node_modules/<pkg>
    目录仅包含
    package.json
    ,而实际文件存放在
    .pnpm
    中(这种阴影结构会导致
    node server.js
    崩溃,例如出现*Cannot find module
    @swc/helpers/cjs/_interop_require_default.cjs
    *错误);
  • 剔除所有非
    linux-x64-gnu
    的原生绑定
    (darwin/musl/arm64版本——通常体积超过100M),并将保留的Linux绑定软链接到顶级node_modules,以便运行时通过
    require("<pkg>-linux-x64-gnu")
    解析。忽略此步骤会导致SVG等代码路径正常工作,但涉及原生扩展的路径会返回500错误,提示Cannot find module
    …-linux-x64-gnu
  • 保留软链接进行压缩(
    zip -y
    ,生成
    ./code.zip
    (位于独立目录外,避免嵌套之前的
    code.zip
    )。运行时会保留软链接,而pnpm的布局主要是指向
    .pnpm
    的软链接,因此这能将压缩包体积大致减半。
Bigfish — 组装静态服务器压缩包:
  • 定位构建输出目录(自动探测
    dist
    build
    out
    目录中包含
    index.html
    的那个;可通过
    --static-dir DIR
    参数手动指定);
  • 生成零依赖的
    server.js
    (仅使用Node的
    http
    /
    fs
    /
    path
    模块),用于提供构建目录的服务,并支持客户端路由回退到
    index.html
  • server.js
    和构建目录放入临时目录并压缩,确保
    server.js
    位于压缩包根目录,构建目录与其同级。无需包含
    node_modules
    ,因此压缩包体积很小。
Vite — 两种模式,通过探测服务器入口文件自动选择:
  • SPA(未找到服务器入口) — 与Bigfish流程完全相同:生成零依赖的静态
    server.js
    + 构建目录。
  • 自定义服务器(自动探测到
    server.{ts,js,mjs,cjs}
    入口;可通过
    --server-entry PATH
    参数强制指定) — 通过esbuild打包入口文件(参数为
    --bundle --platform=node --format=cjs
    vite
    始终排除在外
    ,加上你传入的
    --external NAME
    参数)为自包含的
    server.js
    ,然后将其与构建目录(自动探测
    dist
    /
    build
    /
    out
    ;可通过
    --static-dir
    参数指定)放入临时目录并压缩,确保
    server.js
    位于压缩包根目录。依赖会被内联,因此无需包含
    node_modules
命令会输出最终路径、体积和框架信息,例如
packaged: …/code.zip (25M)
packaged: …/code.zip (0.2M, framework=bigfish)
packaged: …/code.zip (0.7M, framework=vite, mode=server, entry=server.ts)

7–11. Upload, checksum, and deploy

7–11. 上传、校验和部署

A single command does presign → curl PUT upload → CRC64 checksum → update
.morphe.json
(writes
checksum
; uses the
function_name
resolved in step 3, generating one only if somehow still absent) → call
/api/deploy
:
bash
python3 SKILL_DIR/scripts/morphe.py deploy --zip code.zip --project-root .
On success it prints the deploy result JSON (including
action
,
functionName
, and
triggerUrl
when available), then deletes the local
code.zip
(it's already in OSS and is a large throwaway). Pass
--keep-zip
to retain it for inspection. On failure the zip is kept so a redeploy can retry. Report the outcome to the user — give them the
triggerUrl
if present. If it prints
not-logged-in
or an HTTP error, go back to step 1 (the token may have expired) or report the failure.
单个命令即可完成预签名 → curl PUT上传 → CRC64校验和 → 更新
.morphe.json
(写入
checksum
;使用步骤3中确定的
function_name
,仅当该名称仍不存在时才自动生成) → 调用
/api/deploy
bash
python3 SKILL_DIR/scripts/morphe.py deploy --zip code.zip --project-root .
成功时会输出部署结果JSON(包含
action
functionName
和可用的
triggerUrl
),然后删除本地的
code.zip
(已上传到OSS,属于大体积临时文件)。若需保留用于检查,可传入
--keep-zip
参数。失败时会保留压缩包以便重新部署重试。向用户报告结果——若存在
triggerUrl
,告知用户。若输出
not-logged-in
或HTTP错误,回到步骤1(令牌可能已过期)或报告失败。

Notes

注意事项

  • The Morphe API advertises cookie auth but login returns an
    accessToken
    ; the script sends it as both a
    morphe_session
    cookie and a Bearer header.
  • function_name
    in
    .morphe.json
    is generated ONCE and reused on every redeploy so the same function is updated rather than duplicated. Do not hand-edit or regenerate it.
  • All frameworks deploy with the default
    command="node server.js"
    ,
    port=3000
    — no per-framework deploy flags. The Bigfish / Vite-SPA static server honors
    process.env.PORT
    (defaults to 3000) so it matches; a Vite custom-server must do the same (step 4c).
  • (Next.js) Keeping
    code.zip
    small
    is mostly automatic via
    morphe.py package
    (binding pruning + symlink-preserving zip). The remaining large item is usually project data the build traced in (raw datasets, fixtures, generated outputs under a dir a server component
    readdir
    s). Trim those with
    outputFileTracingExcludes
    in the Next config — but never exclude files read at runtime via
    process.cwd()
    (fonts, JSON the route parses). (Bigfish zips are just the static build — already small, no
    node_modules
    .)
  • (Next.js) If a native addon still 500s at runtime with Cannot find module
    <pkg>-linux-x64-gnu
    : the binary wasn't installed on the build host. Fix the install (step 4a:
    supportedArchitectures
    for pnpm, or
    npm i --os=linux --cpu=x64 --libc=glibc …
    ), reinstall, rebuild, repackage.
    package
    warns when an expected linux binding is absent.
  • (Bigfish) A blank page or 404 on a client route means the SPA fallback isn't reaching
    index.html
    , or the build dir wasn't
    dist/
    . Confirm
    index.html
    exists in the build dir and pass
    --static-dir
    if it's not one of
    dist
    /
    build
    /
    out
    . The generated static server is for static builds; an SSR (
    deployMode: 'render'
    ) app needs a real server entry, not this wrapper.
  • (Vite)
    package
    esbuild step fails
    (e.g. No loader is configured for ".node" files or a glob/
    require.resolve
    error from
    vite
    /
    lightningcss
    /
    fsevents
    ): the server entry imports
    vite
    (or another native-addon dep) at the top level. Make that import dev-only / lazy (step 4c) so it's externalized, or pass the dep via
    --external NAME
    .
  • (Vite) SPA blank page / 404 on a client route — same as Bigfish: confirm
    index.html
    is in the build dir and pass
    --static-dir
    if it isn't
    dist
    /
    build
    /
    out
    . A custom-server route 500ing usually means a dep was externalized but actually needed at runtime, or the server reads its static dir from a path other than
    process.cwd()
    — fix per step 4c.
  • (Vite) A 500 from a backend route at runtime but not locally is often a missing runtime secret — set API keys etc. in the function environment (they're never bundled into the zip from your
    .env
    ).
  • Full API reference:
    references/api.md
    .
  • Morphe API支持Cookie认证,但登录会返回
    accessToken
    ;脚本会同时将其作为
    morphe_session
    Cookie和Bearer头发送。
  • .morphe.json
    中的
    function_name
    仅生成一次,后续重新部署时会复用,从而更新同一个函数而非创建新函数。请勿手动编辑或重新生成。
  • 所有框架均使用默认的
    command="node server.js"
    port=3000
    部署——无需针对框架设置部署参数。Bigfish/Vite-SPA的静态服务器会遵循
    process.env.PORT
    (默认3000),因此匹配该设置;Vite自定义服务器也必须遵循此设置(步骤4c)。
  • (Next.js)缩小
    code.zip
    体积
    主要通过
    morphe.py package
    自动完成(绑定剔除 + 保留软链接压缩)。剩余的大体积内容通常是构建过程中追踪到的项目数据(原始数据集、测试用例、服务器组件
    readdir
    读取的目录下的生成文件)。可通过Next.js配置中的
    outputFileTracingExcludes
    剔除这些内容——但绝不能排除通过
    process.cwd()
    在运行时读取的文件(字体、路由解析的JSON文件)。(Bigfish压缩包仅包含静态构建产物——体积已很小,无
    node_modules
    。)
  • (Next.js)若原生扩展在运行时仍返回500错误,提示Cannot find module
    <pkg>-linux-x64-gnu
    :说明二进制文件未安装到构建主机。修复安装过程(步骤4a:pnpm使用
    supportedArchitectures
    ,或npm执行
    npm i --os=linux --cpu=x64 --libc=glibc …
    ),重新安装、构建、打包。当预期的Linux绑定缺失时,
    package
    会发出警告。
  • (Bigfish)客户端路由出现空白页或404:说明SPA回退未指向
    index.html
    ,或构建目录不是
    dist/
    。确认构建目录中存在
    index.html
    ,若目录不是
    dist
    /
    build
    /
    out
    ,传入
    --static-dir
    参数。生成的静态服务器仅适用于静态构建;SSR(
    deployMode: 'render'
    )应用需要真实的服务器入口,而非此包装器。
  • (Vite)
    package
    的esbuild步骤失败
    (例如No loader is configured for ".node" files或来自
    vite
    /
    lightningcss
    /
    fsevents
    的glob/
    require.resolve
    错误):说明服务器入口文件顶层导入了
    vite
    (或其他带原生扩展的依赖)。将该导入改为仅在开发环境使用/惰性加载(步骤4c),使其被排除在包外,或通过
    --external NAME
    参数传入该依赖。
  • (Vite)SPA出现空白页/客户端路由404 — 与Bigfish情况相同:确认构建目录中存在
    index.html
    ,若目录不是
    dist
    /
    build
    /
    out
    ,传入
    --static-dir
    参数。自定义服务器路由返回500错误通常是因为依赖被排除在包外但运行时需要,或服务器从
    process.cwd()
    以外的路径读取静态目录——按照步骤4c修复。
  • (Vite)后端路由在运行时返回500但本地正常:通常是缺少运行时密钥——在函数环境变量中设置API密钥等(这些内容绝不会从你的
    .env
    文件打包到压缩包中)。
  • 完整API参考:
    references/api.md