将其他框架与 Express.js 集成

通过一些额外的配置,您可以基于基本的框架感知型 CLI 功能,对集成功能进行扩展,以支持 Angular 和 Next.js 之外的更多框架。

准备工作

在开始将 Next.js 应用部署到 Firebase 之前,请先了解以下要求和相关选项:

  • 拥有 Firebase CLI 11.14.2 或更高版本。请务必使用您首选的方法安装 CLI
  • 可选:在 Firebase 项目中启用结算功能(如果您计划使用 SSR,则必须完成此操作)

初始化 Firebase

首先,请为您的框架项目初始化 Firebase。对于新项目,您可以使用 Firebase CLI 完成初始化;对于现有项目,则可以通过修改 firebase.json 执行此操作。

初始化新项目

  1. 在 Firebase CLI 中,启用 Web 框架预览:
    firebase experiments:enable webframeworks
  2. 通过 CLI 运行初始化命令,然后按照提示操作:
    firebase init hosting
  3. 选择您的托管源目录;它可以包含一个现有的 Web 应用。
  4. 选择“使用 Web 框架进行动态网站托管”。
  5. 选择“Express.js”/“自定义”

初始化现有项目

firebase.json 中的托管配置更改为使用 source 选项,而不是 public 选项。例如:

{
  "hosting": {
    "source": "./path-to-your-express-directory",
  }
}

提供静态内容

在部署静态内容之前,您需要配置您的应用。

配置

为了知道应如何部署应用,Firebase CLI 需要能够构建应用并了解您的工具会将资源部署到 Hosting 上的什么位置。这是使用 package.json 中的 npm 构建脚本和 CJS 目录指令来实现的。

假定有以下 package.json:

{
    "name": "express-app",
    "version": "0.0.0",
    "scripts": {
        "build": "spack",
        "static": "cp static/* dist",
        "prerender": "ts-node prerender.ts"
    },
    …
}

这里,Firebase CLI 仅调用构建脚本,因此您需要确保该构建脚本的完整性。

{
    "name": "express-app",
    "version": "0.0.0",
    "scripts": {
        "build": "spack && npm run static && npm run prerender",
        "static": "cp static/* dist",
        "prerender": "ts-node prerender.ts"
    },
    …
}

如果您的框架不支持开箱即用型预呈现功能,不妨考虑使用诸如 Rendertron 之类的工具。Rendertron 让您可以对应用的本地实例发出无头 Chrome 请求,以便您可以保存生成的 HTML 并将其托管在 Hosting 上。

最后需要注意的是,不同的框架和构建工具会将其工件存储在不同的位置。您可以使用 directories.serve 让 CLI 知道您的构建脚本会将生成的工件输出到什么位置:

{
    "name": "express-app",
    "version": "0.0.0",
    "scripts": {
        "build": "spack && npm run static && npm run prerender",
        "static": "cp static/* dist",
        "prerender": "ts-node prerender.ts"
    },
    "directories": {
        "serve": "dist"
    },
    …
}

部署

配置应用后,您可以使用标准部署命令来提供静态内容:

firebase deploy

提供动态内容

如需在 Cloud Functions for Firebase 上提供 Express 应用,在导出 Express 应用(或 Express 样式的网址处理程序)时,需确保在您的库经过 npm 打包后,Firebase 仍然能够找到您的应用。

为此,请确保您的 files 指令包含服务器所需的所有内容,并且您的主入口点已在 package.json 中正确设置:

{
    "name": "express-app",
    "version": "0.0.0",
    "scripts": {
        "build": "spack && npm run static && npm run prerender",
        "static": "cp static/* dist",
        "prerender": "ts-node tools/prerender.ts"
    },
    "directories": {
        "serve": "dist"
    },
    "files": ["dist", "server.js"],
    "main": "server.js",
    ...
}

通过名为 app 的函数导出 Express 应用:

// server.js
export function app() {
  const server = express();
   …
   return server;
}

或者,如果您希望导出 Express 样式的网址处理程序,应将其命名为 handle

export function handle(req, res) {
   res.send(‘hello world’);
}

部署

firebase deploy

该步骤会将您的静态内容部署到 Firebase Hosting,并允许 Firebase 回退到 Cloud Functions for Firebase 上托管的 Express 应用。

可选:与 Firebase Authentication 集成

Web 框架感知型 Firebase 部署工具可以使用 Cookie 自动同步客户端和服务器的状态。若要访问身份验证上下文,可以视需要向 Express res.locals 对象添加经过身份验证的 Firebase 应用实例 (firebaseApp) 及当前登录的用户 (currentUser)。