部署应用

目前,Modern.js 提供了两种部署方式:

  • 你可以将应用自行托管在包含 Node.js 环境的容器中,这为应用提供了部署的灵活性。
  • 你也可以通过平台部署应用,目前 Modern.js 官方支持了 NetlifyVercel 平台。
INFO

目前 Modern.js 仅支持在 Node.js 环境中运行,未来将提供更多运行时环境的支持。

构建部署产物

执行 modern deploy 命令将自动输出部署产物。此过程包括优化 Bundler 构建产物及产物依赖,检测当前部署平台,并自动生成可以在该平台运行的产物。 如果你希望在本地生成并测试特定部署平台的产物,可以通过设置环境变量来指定平台:

MODERNJS_DEPLOY=netlify npx modern deploy
INFO

在 Modern.js 官方支持的部署平台中部署时,无需指定环境变量。

Node.js

单仓库项目

默认情况下,如果未检测到 Modern.js 支持的部署平台,Modern.js 将生成可以在 Node.js 环境下运行的部署产物。

你可以使用以下命令构建项目:

npx modern deploy

当执行 modern deploy 命令时,Modern.js 将生成可执行的部署产物,并在控制台输出以下内容:

Static directory: `.output/static`
You can preview this build by `node .output/index`

现在,你可以通过执行 node .output/index 命令来运行服务器。在 .output/static 目录中,存放了页面运行所需的静态资源,你可以选择将这些资源上传到 CDN 以提高访问速度。

INFO

默认情况下,运行 Modern.js 服务器时会监听 8080 端口,如果你想修改监听的端口,可以指定 PORT 环境变量:

PORT=3000 node .output/index

Monorepo

对于 Monorepo 项目,除了需要构建当前的项目外,还需要构建当前项目依赖的仓库中其他子项目。

假设当前项目的 package.json 中的 name 为 app,以 pnpm 作为 Monorepo 管理工具为例,你可以在项目 package.json 中添加以下命令用于构建:

app/package.json
{
  "scripts": {
    "build:packages": "pnpm --filter 'app^...' run build",
    "deploy": "pnpm run build:packages && modern deploy",
  }
}

如果你使用 rush 作为 Monorepo 管理工具,可以在 package.json 中添加以下命令:

{
  "scripts": {
    "build:packages": "rush rebuild --to-except app",
    "deploy": "rushx build:packages && modern deploy",
  }
}

构建完成后,框架会将项目中所有的依赖生成在 .output/node_modules 目录下。你同样可以使用 node .output/index 运行 Modern.js 服务器。

Netlify

Netlify 是一个流行的 Web 开发平台,专为构建、发布和维护现代 Web 项目而设计。在 Netlify 上部署,通常需要配置 netlify.toml 文件,你可以根据项目复杂度,渐进地配置该文件。

纯前端项目

在当前项目的根目录添加 netlify.toml 文件:

./
├── src
├── modern.config.ts
├── netlify.toml
└── package.json

netlify.toml 中添加以下内容:

[build]
  publish = "dist"
  command = "modern deploy"

在 Netlify 平台上添加项目,部署即可。

全栈项目

全栈项目是指使用了自定义 Web Server、SSR、BFF 的项目,这些项目需要部署在 Netlify Functions 上。你需要基于上述的 netlify.toml 文件,添加以下配置:

netlify.toml
[build]
  publish = "dist"
  command = "modern deploy"

[functions]
  directory = ".netlify/functions"
  node_bundler = "none"
  included_files = [".netlify/functions/**"]
INFO

目前 Modern.js 还不支持在 Netlify Edge Functions 进行部署,我们将在后续的版本中支持。

Monorepo 项目

INFO

以下指南主要针对于全栈项目,对于纯 CSR 的项目,只需要按照纯前端项目部署即可。

对于 Monorepo 项目,除了需要构建当前的项目外,还需要构建当前项目依赖的仓库中其他子项目。这里以一个 pnpm Monorepo 仓库为例,在 Netlify 上对 Monorepo 项目进行部署。

假设 Monorepo 仓库目录结构如下:

. ├── packages │ ├── app │ └── app-dep1 ├── package.json ├── pnpm-lock.yaml └── pnpm-workspace.yaml

你需要在 Netlify 平台上配置 Base directorypackages/app:

packages/app/package.json 中添加以下 script,在执行 app 仓库的部署命令之前,先执行 workspace 中其他仓库的构建:

{
  "scripts": {
    "build:packages": "pnpm --filter 'app^...' run build",
    "deploy": "pnpm run build:packages && modern deploy",
  }
}

netlify.toml 配置构建命令:

[build]
  publish = "dist"
  command = "npm run deploy"

[functions]
  directory = ".netlify/functions"
  node_bundler = "none"
  included_files = [".netlify/functions/**"]

提交你的代码,使用 Netlify 平台部署即可。

Vercel

Vercel 是一个面向现代 Web 应用的部署平台,它提供了丰富的功能,支持部署静态网站,服务端渲染应用等。在 Vercel 上部署,通常需要配置 vercel.json 文件,你可以根据项目复杂度,渐进地配置该文件。

纯前端项目

在当前项目的根目录添加 vercel.json 文件:

./
├── src
├── modern.config.ts
├── vercel.json
└── package.json

vercel.json 中添加以下内容:

vercel.json
{
  "buildCommand": "modern deploy",
  "outputDirectory": ".vercel/output"
}

提交你的项目到 git,在 Vercel 平台上选择 Frmeworkwork Preset 为 Other,部署即可。

全栈项目

全栈项目是指使用了自定义 Web Server、SSR、BFF 的项目,这些项目需要部署在 Vercel Functions 上。

全栈项目除了按照纯前端项目的方式配置 vercel.json 外,有两点需要注意:

  1. 当前,Modern.js 还不支持在 Vercel 平台上部署 BFF 项目,我们将在后续的版本中支持。
  2. Vercel 平台部署时,默认 node 运行时为 20.x,部署全栈项目时建议选择 18.x,具体原因详见Serverless Function contains invalid runtime error,你可以修改 package.json 指定版本:
package.json
"engines": {
  "node": "18.x"
}

Monorepo 项目

INFO

以下指南主要针对于全栈项目,对于纯 CSR 的项目,只需要按照纯前端项目部署即可。

对于 Monorepo 项目,除了需要构建当前的项目外,还需要构建当前项目依赖的仓库中其他子项目。这里以一个 pnpm Monorepo 仓库为例,在 Vercel 上对 Monorepo 项目进行部署。

假设 Monorepo 仓库目录结构如下:

. ├── packages │ ├── app │ └── app-dep1 ├── package.json ├── pnpm-lock.yaml └── pnpm-workspace.yaml

首先,你需要在 Vercel 平台上配置 Root Directorypackages/app:

将 Node.js 运行时设置为 18.x

package.json
"engines": {
  "node": "18.x"
},

packages/app/package.json 中添加以下 script,在执行 app 仓库的部署命令之前,先执行 workspace 中其他仓库的构建:

{
  "scripts": {
    "build:packages": "pnpm --filter 'app^...' run build",
    "deploy": "pnpm run build:packages && modern deploy",
  }
}

packages/app/vercel.json 文件中添加以下内容:

vercel.json
{
  "buildCommand": "npm run deploy",
  "outputDirectory": ".vercel/output"
}

提交你的代码,使用 Vercel 平台部署即可。