AWS
内部原理
插件

Open-next 使用 esbuild 来构建项目。考虑到我们需要支持多个版本的 Next.js 和多种运行时环境,我们开发了一个插件,通过 esbuild 插件在构建时覆盖代码的某些部分。

⚠️

目前该插件是内部使用的,并未向用户公开。未来我们可能会开放它,但现在仅供内部使用。

使用方法

你需要创建一个 ts 文件来覆盖代码。在这个文件中,可以使用以下语法:

//#import
// 这里的全部内容会被放置在文件顶部
const test = "test";
//#endImport
 
//#override import
// 这里的全部内容会替换掉指定id为import的覆盖内容
// 你需要查看要覆盖的文件来获取对应的id
import { requestHandler } from "./util.js";
//#endOverride
 
//#override fnId
// 这里的全部内容会替换掉指定id为fnId的覆盖内容
export const fnId = (req: IncomingMessage, res: ServerResponse) => {
  requestHandler(req, res);
};
//#endOverride

然后这样使用插件:

import openNextPlugin from "./plugin.js";
 
openNextPlugin({
  name: "插件名称",
  target: /plugins\/serverHandler\.js/g, // 用于匹配要覆盖文件的正则表达式
  replacements: ["./serverHandler.replacement.js"], // 包含覆盖内容的文件路径
}),
 

已知问题

不要在 #override 和 #imports 中包含 types,因为 esbuild 在构建时会移除前置注释(即它会移除 //#override id)。

正确的做法是将 import type 放在外部,例如:

import type { PluginHandler } from "../next-types.js";
import type { IncomingMessage } from "../request.js";
import type { ServerResponse } from "../response.js";

//#override imports
import { requestHandler } from "./util.js";
//#endOverride

反正这些类型声明在最终输出中都会被移除。