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
反正这些类型声明在最终输出中都会被移除。