部署流程

本站是纯静态站点,没有服务端代码。但有一条硬性要求:必须能设置自定义响应头

前置要求

本地构建

npm install
npm run build      # 准备 ORT 资源 → 类型检查 → 打包
npm run preview    # 本地起服务,带上 COOP/COEP 头

构建产物结构:

dist/
├── index.html            中文首页(压缩功能)
├── upscale/index.html    中文放大页
├── cutout/index.html     中文抠图页
├── blog/                 中文博客(手写静态页)
├── docs/                 本套文档
├── en/  zh-CN/           英文 / 中文旧路径,结构同上
├── assets/               打包后的 JS + CSS
├── ort/                  ONNX Runtime 资源(构建时生成,gzip 存储)
├── models/               放大模型权重
├── _headers              Cloudflare 响应头(跨域隔离 + 缓存)
└── robots.txt  sitemap.xml  site.webmanifest

方式一:Cloudflare Pages(推荐)

仓库已带 wrangler.toml,直接推送到 Cloudflare 即可:

npm run deploy     # = npm run build && wrangler pages deploy dist --project-name=image-tools

或者在 Cloudflare 控制台连接 Git 仓库,构建设置填:

构建命令npm run build
输出目录dist
环境变量不需要

public/_headers 是 Cloudflare Pages 的原生特性,跨域隔离头会自动生效,无需额外配置。

方式二:其他静态托管

没有任何服务端代码,把 dist/ 丢上去即可。但要注意三点:

  1. public/_headers 是 Cloudflare 专有格式。 其他平台要写各自等价的配置 —— Netlify 用同名的 _headers、 nginx 用 add_header、EdgeOne 用响应头规则。 跨域隔离头必须真的生效,否则会掉到单线程 WASM。
  2. ORT 运行时在 dist/ort/,别漏传。
  3. 放大模型权重在 dist/models/(已提交到仓库)。 抠图权重不在 dist/ —— 它是运行时从 HuggingFace 按需拉取并缓存的, 部署时不需要额外准备。

nginx 示例

location / {
  add_header Cross-Origin-Opener-Policy "same-origin" always;
  add_header Cross-Origin-Embedder-Policy "require-corp" always;
  try_files $uri $uri/ $uri/index.html =404;
}

部署前必须知道的几件事

1. 跨域隔离是性能开关,不是可选项

Cross-Origin-Opener-Policy: same-originCross-Origin-Embedder-Policy: require-corp 是解锁 SharedArrayBuffer、进而让 WASM 多线程推理生效的前提。 缺了它们站点仍然能用,但没有 WebGPU 的机器会掉到单线程 WASM, 慢好几倍。详见浏览器端推理

2. require-corp 会拦 no-cors 子资源

页面目前只加载自己的资源,所以是安全的。但如果你加了 CDN 脚本、远程字体或统计代码, 就必须给它们配好 CORP 头,否则会被拦下 —— 或者重新考虑这套策略。

fetch() 是唯一的例外,抠图拉权重靠的就是它。

3. ORT 的 wasm 是 25.5 MB,超过 Cloudflare 单文件 25 MiB 上限

scripts/prepare-ort.mjs 因此在构建时把它转成 gzip 存储(约 6.3 MB), 浏览器端用 DecompressionStream 解压。这同时把首次加载量砍掉了四分之三。

出于同样的原因,放大模型权重必须提交到仓库: 构建环境里既没有 Python 也没有上游模型源,不可能在构建时下载。 (抠图权重是 94–452 MB,远超任何静态托管能接受的范围,所以走运行时拉取这条路。)

换自定义域名

canonicalhreflangog:urlog:image、 JSON-LD、sitemap 与 robots.txt 用的都是绝对 URL, 所以换域名要在这些文件里全局查找替换:

中文规范路径没有语言前缀。中文版在 //upscale//cutout//zh-CN/** 是早期路径,其 canonical 一律指回非 zh-CN 的版本,属于别名。