Skip to content

Commit

Permalink
fix: patch both trace/tracer.js files
Browse files Browse the repository at this point in the history
  • Loading branch information
dario-piotrowicz committed Jan 3, 2025
1 parent 4b6a50b commit 3b7ea49
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 18 deletions.
17 changes: 17 additions & 0 deletions packages/cloudflare/src/cli/build/open-next/createServerBundle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<string>();
Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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"));
}

/**
Expand All @@ -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);
}

0 comments on commit 3b7ea49

Please sign in to comment.