Skip to content

Commit

Permalink
refactor: patch getBuildId using ast-grep (#401)
Browse files Browse the repository at this point in the history
  • Loading branch information
vicb authored Feb 20, 2025
1 parent 49a1377 commit 624d75a
Show file tree
Hide file tree
Showing 8 changed files with 120 additions and 16 deletions.
3 changes: 2 additions & 1 deletion packages/cloudflare/src/cli/build/bundle-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { build } from "esbuild";
import { patchVercelOgLibrary } from "./patches/ast/patch-vercel-og-library.js";
import { patchWebpackRuntime } from "./patches/ast/webpack-runtime.js";
import * as patches from "./patches/index.js";
import { inlineBuildId } from "./patches/plugins/build-id.js";
import { ContentUpdater } from "./patches/plugins/content-updater.js";
import { inlineEvalManifest } from "./patches/plugins/eval-manifest.js";
import { patchFetchCacheSetMissingWaitUntil } from "./patches/plugins/fetch-cache-wait-until.js";
Expand Down Expand Up @@ -95,6 +96,7 @@ export async function bundleServer(buildOpts: BuildOptions): Promise<void> {
inlineEvalManifest(updater, buildOpts),
inlineFindDir(updater, buildOpts),
inlineLoadManifest(updater, buildOpts),
inlineBuildId(updater),
// Apply updater updaters, must be the last plugin
updater.plugin,
],
Expand Down Expand Up @@ -197,7 +199,6 @@ export async function updateWorkerBundledCode(

const patchedCode = await patchCodeWithValidations(code, [
["require", patches.patchRequire],
["`buildId` function", (code) => patches.patchBuildId(code, buildOpts)],
["cacheHandler", (code) => patches.patchCache(code, buildOpts)],
[
"'require(this.middlewareManifestPath)'",
Expand Down
2 changes: 1 addition & 1 deletion packages/cloudflare/src/cli/build/patches/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
export * from "./investigated/index.js";
export * from "./to-investigate/index.js";
export * from "./to-investigate/inline-middleware-manifest.js";
31 changes: 31 additions & 0 deletions packages/cloudflare/src/cli/build/patches/plugins/build-id.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/**
* Inline `getBuildId` as it relies on `readFileSync` that is not supported by workerd.
*/

import { getCrossPlatformPathRegex } from "@opennextjs/aws/utils/regex.js";

import { patchCode } from "../ast/util.js";
import type { ContentUpdater } from "./content-updater.js";

export function inlineBuildId(updater: ContentUpdater) {
return updater.updateContent(
"inline-build-id",
{
filter: getCrossPlatformPathRegex(String.raw`/next/dist/server/next-server\.js$`, { escape: false }),
contentFilter: /getBuildId\(/,
},
async ({ contents }) => patchCode(contents, rule)
);
}

export const rule = `
rule:
kind: method_definition
has:
field: name
regex: ^getBuildId$
fix: |-
getBuildId() {
return process.env.NEXT_BUILD_ID;
}
`;
85 changes: 85 additions & 0 deletions packages/cloudflare/src/cli/build/patches/plugins/find-dir.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import { describe, expect, test } from "vitest";

import { patchCode } from "../ast/util.js";
import { rule } from "./build-id.js";

describe("getBuildId", () => {
test("patch", () => {
const code = `
class NextNodeServer extends _baseserver.default {
constructor(options){
// Initialize super class
super(options);
this.handleNextImageRequest = async (req, res, parsedUrl) => { /* ... */ };
}
async handleUpgrade() {
// The web server does not support web sockets, it's only used for HMR in
// development.
}
loadEnvConfig({ dev, forceReload, silent }) {
(0, _env.loadEnvConfig)(this.dir, dev, silent ? {
info: ()=>{},
error: ()=>{}
} : _log, forceReload);
}
async hasPage(pathname) {
var _this_nextConfig_i18n;
return !!(0, _require.getMaybePagePath)(pathname, this.distDir, (_this_nextConfig_i18n = this.nextConfig.i18n) == null ? void 0 : _this_nextConfig_i18n.locales, this.enabledDirectories.app);
}
getBuildId() {
const buildIdFile = (0, _path.join)(this.distDir, _constants.BUILD_ID_FILE);
try {
return _fs.default.readFileSync(buildIdFile, "utf8").trim();
} catch (err) {
if (err.code === "ENOENT") {
throw new Error(\`Could not find a production build in the '\${this.distDir}' directory. Try building your app with 'next build' before starting the production server. https://nextjs.org/docs/messages/production-start-no-build-id\`);
}
throw err;
}
}
getEnabledDirectories(dev) {
const dir = dev ? this.dir : this.serverDistDir;
return {
app: (0, _findpagesdir.findDir)(dir, "app") ? true : false,
pages: (0, _findpagesdir.findDir)(dir, "pages") ? true : false
};
}
// ...
}`;

expect(patchCode(code, rule)).toMatchInlineSnapshot(`
"class NextNodeServer extends _baseserver.default {
constructor(options){
// Initialize super class
super(options);
this.handleNextImageRequest = async (req, res, parsedUrl) => { /* ... */ };
}
async handleUpgrade() {
// The web server does not support web sockets, it's only used for HMR in
// development.
}
loadEnvConfig({ dev, forceReload, silent }) {
(0, _env.loadEnvConfig)(this.dir, dev, silent ? {
info: ()=>{},
error: ()=>{}
} : _log, forceReload);
}
async hasPage(pathname) {
var _this_nextConfig_i18n;
return !!(0, _require.getMaybePagePath)(pathname, this.distDir, (_this_nextConfig_i18n = this.nextConfig.i18n) == null ? void 0 : _this_nextConfig_i18n.locales, this.enabledDirectories.app);
}
getBuildId() {
return process.env.NEXT_BUILD_ID;
}
getEnabledDirectories(dev) {
const dir = dev ? this.dir : this.serverDistDir;
return {
app: (0, _findpagesdir.findDir)(dir, "app") ? true : false,
pages: (0, _findpagesdir.findDir)(dir, "pages") ? true : false
};
}
// ...
}"
`);
});
});
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Inline `loadManifest` as it relies on `readFileSync`that is not supported by workerd.
* Inline `loadManifest` as it relies on `readFileSync` that is not supported by workerd.
*/

import { readFile } from "node:fs/promises";
Expand Down

This file was deleted.

This file was deleted.

0 comments on commit 624d75a

Please sign in to comment.