From 3b7ea499613f0ac54c54326fba6734a4a1951e55 Mon Sep 17 00:00:00 2001 From: Dario Piotrowicz Date: Fri, 3 Jan 2025 11:42:53 +0100 Subject: [PATCH] fix: patch both `trace/tracer.js` files --- .../cli/build/open-next/createServerBundle.ts | 17 ++++++++ .../patches/to-investigate/wrangler-deps.ts | 43 +++++++++++-------- 2 files changed, 42 insertions(+), 18 deletions(-) diff --git a/packages/cloudflare/src/cli/build/open-next/createServerBundle.ts b/packages/cloudflare/src/cli/build/open-next/createServerBundle.ts index 3aaec1ff..bcca7614 100644 --- a/packages/cloudflare/src/cli/build/open-next/createServerBundle.ts +++ b/packages/cloudflare/src/cli/build/open-next/createServerBundle.ts @@ -17,6 +17,8 @@ import { openNextReplacementPlugin } from "@opennextjs/aws/plugins/replacement.j import { openNextResolvePlugin } from "@opennextjs/aws/plugins/resolve.js"; import type { FunctionOptions, SplittedFunctionOptions } from "@opennextjs/aws/types/open-next.js"; +import { patchTracerFile } from "../patches/to-investigate/wrangler-deps.js"; + export async function createServerBundle(options: buildHelper.BuildOptions) { const { config } = options; const foundRoutes = new Set(); @@ -152,6 +154,21 @@ async function generateBundle( isBundled ); + const tracerFilePath = path.join( + outputPath, + "node_modules", + "next", + "dist", + "server", + "lib", + "trace", + "tracer.js" + ); + + if (fs.existsSync(tracerFilePath)) { + patchTracerFile(tracerFilePath); + } + // Build Lambda code // note: bundle in OpenNext package b/c the adapter relies on the // "serverless-http" package which is not a dependency in user's diff --git a/packages/cloudflare/src/cli/build/patches/to-investigate/wrangler-deps.ts b/packages/cloudflare/src/cli/build/patches/to-investigate/wrangler-deps.ts index 6fed53ec..c0c17684 100644 --- a/packages/cloudflare/src/cli/build/patches/to-investigate/wrangler-deps.ts +++ b/packages/cloudflare/src/cli/build/patches/to-investigate/wrangler-deps.ts @@ -23,24 +23,7 @@ export function patchWranglerDeps(config: Config) { writeFileSync(pagesRuntimeFile, patchedPagesRuntime); - // Patch .next/standalone/node_modules/next/dist/server/lib/trace/tracer.js - // - // Remove the need for an alias in wrangler.toml: - // - // [alias] - // # @opentelemetry/api is `require`d when running wrangler dev, so we need to stub it out - // # IMPORTANT: we shim @opentelemetry/api to the throwing shim so that it will throw right away, this is so that we throw inside the - // # try block here: https://github.com/vercel/next.js/blob/9e8266a7/packages/next/src/server/lib/trace/tracer.ts#L27-L31 - // # causing the code to require the 'next/dist/compiled/@opentelemetry/api' module instead (which properly works) - // #"@opentelemetry/api" = "./.next/standalone/node_modules/cf/templates/shims/throw.ts" - const tracerFile = join(distPath, "server", "lib", "trace", "tracer.js"); - - const patchedTracer = readFileSync(tracerFile, "utf-8").replaceAll( - /\w+\s*=\s*require\([^/]*opentelemetry.*\)/g, - `throw new Error("@opentelemetry/api")` - ); - - writeFileSync(tracerFile, patchedTracer); + patchTracerFile(join(distPath, "server", "lib", "trace", "tracer.js")); } /** @@ -67,3 +50,27 @@ function getDistPath(config: Config): string { throw new Error("Unexpected error: unable to detect the node_modules/next/dist directory"); } + +/** + * Patch trace/tracer.js files that require from `@opentelemetry/api` by replacing such `require` + * calls with error throwing expressions. + * + * The replacement works because code that requires from `@opentelementry/api` is `try-catch`ed + * and a supported alternative is imported in the catch blocks + * (see: https://github.com/vercel/next.js/blob/9e8266a7/packages/next/src/server/lib/trace/tracer.ts#L27-L31) + * + * @param tracerFilePath path to the tracer file to patch + */ +export function patchTracerFile(tracerFilePath: string) { + const tracerFileContent = readFileSync(tracerFilePath, "utf-8"); + const patchedTracerFileContent = tracerFileContent.replaceAll( + /\w+\s*=\s*require\([^/]*opentelemetry.*\)/g, + `throw new Error("@opentelemetry/api")` + ); + + if (patchedTracerFileContent === tracerFileContent) { + throw new Error(`Failed to patch tracer file at ${tracerFilePath}`); + } + + writeFileSync(tracerFilePath, patchedTracerFileContent); +}