From 13a5f899187bb6a44a856e282c20740ef81a5de9 Mon Sep 17 00:00:00 2001 From: Dario Piotrowicz Date: Tue, 14 Jan 2025 20:26:02 +0000 Subject: [PATCH] instead of patching the `tracer.js` file to throw on `@opentelemetry/api` imports, delete the `@opentelemetry/api` dependency itself --- .changeset/forty-jobs-press.md | 9 ++++++++ .../cli/build/open-next/createServerBundle.ts | 7 +++++- .../investigated/delete-open-telemetry-dep.ts | 23 +++++++++++++++++++ .../cli/build/patches/investigated/index.ts | 1 + .../patches/to-investigate/wrangler-deps.ts | 20 ++-------------- 5 files changed, 41 insertions(+), 19 deletions(-) create mode 100644 .changeset/forty-jobs-press.md create mode 100644 packages/cloudflare/src/cli/build/patches/investigated/delete-open-telemetry-dep.ts diff --git a/.changeset/forty-jobs-press.md b/.changeset/forty-jobs-press.md new file mode 100644 index 00000000..889781e7 --- /dev/null +++ b/.changeset/forty-jobs-press.md @@ -0,0 +1,9 @@ +--- +"@opennextjs/cloudflare": patch +--- + +instead of patching the `tracer.js` file to throw on `@opentelemetry/api` imports, delete the `@opentelemetry/api` dependency itself + +the problem that this addresses is that the `@opentelemetry/api` package is not only imported by the `tracer.js` file +we patch, so just deleting the library itself makes sure that all files requiring it get the same throwing behavior +(besides decreasing the overall worker size) diff --git a/packages/cloudflare/src/cli/build/open-next/createServerBundle.ts b/packages/cloudflare/src/cli/build/open-next/createServerBundle.ts index dbaae8a2..8f0db31d 100644 --- a/packages/cloudflare/src/cli/build/open-next/createServerBundle.ts +++ b/packages/cloudflare/src/cli/build/open-next/createServerBundle.ts @@ -17,6 +17,7 @@ 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 { deleteOpenTelemetryDep } from "../patches/index.js"; import { normalizePath } from "../utils/index.js"; export async function createServerBundle(options: buildHelper.BuildOptions) { @@ -86,12 +87,14 @@ export async function createServerBundle(options: buildHelper.BuildOptions) { } // Generate default function - await generateBundle("default", options, { + const outputPath = await generateBundle("default", options, { ...defaultFn, // @ts-expect-error - Those string are RouteTemplate routes: Array.from(remainingRoutes), patterns: ["*"], }); + + deleteOpenTelemetryDep(outputPath); } async function generateBundle( @@ -250,6 +253,8 @@ CMD ["node", "index.mjs"] ` ); } + + return outputPath; } function shouldGenerateDockerfile(options: FunctionOptions) { diff --git a/packages/cloudflare/src/cli/build/patches/investigated/delete-open-telemetry-dep.ts b/packages/cloudflare/src/cli/build/patches/investigated/delete-open-telemetry-dep.ts new file mode 100644 index 00000000..794f4c11 --- /dev/null +++ b/packages/cloudflare/src/cli/build/patches/investigated/delete-open-telemetry-dep.ts @@ -0,0 +1,23 @@ +import { rmSync } from "node:fs"; +import { join } from "node:path"; + +/** + * Given a directory path, it deletes a `node_modules/@opentelemetry` subdirectory if present. + * + * Explanation: + * The standard `@opentelemetry/api` library doesn't work in workerd since there are paths that it can't resolve (without a + * compilation step), fortunately Next.js has a try-catch statement that replaces, when failing, `require('@opentelemetry/api')` + * calls with a precompiled version of the library ('next/dist/compiled/@opentelemetry/api') which does properly in our runtime + * (source code: https://github.com/vercel/next.js/blob/9e8266a7/packages/next/src/server/lib/trace/tracer.ts#L27-L31) + * + * So this function is used to delete the `@opentelemetry` dependency entirely so to guarantee that + * `require('@opentelemetry/api')` fail ensuring that the precompiled version is used + */ +export async function deleteOpenTelemetryDep(path: string): Promise { + const nodeModulesDirPath = join(path, "node_modules"); + + rmSync(join(nodeModulesDirPath, "@opentelemetry"), { + recursive: true, + force: true, + }); +} diff --git a/packages/cloudflare/src/cli/build/patches/investigated/index.ts b/packages/cloudflare/src/cli/build/patches/investigated/index.ts index 9d46a4d8..2800555a 100644 --- a/packages/cloudflare/src/cli/build/patches/investigated/index.ts +++ b/packages/cloudflare/src/cli/build/patches/investigated/index.ts @@ -1,4 +1,5 @@ export * from "./copy-package-cli-files.js"; +export * from "./delete-open-telemetry-dep.js"; export * from "./patch-cache.js"; export * from "./patch-require.js"; export * from "./update-webpack-chunks-file/index.js"; 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 11810823..c2f56c33 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 @@ -5,6 +5,7 @@ import * as ts from "ts-morph"; import { Config } from "../../../config.js"; import { tsParseFile } from "../../utils/index.js"; +import { deleteOpenTelemetryDep } from "../investigated/delete-open-telemetry-dep.js"; export function patchWranglerDeps(config: Config) { console.log("# patchWranglerDeps"); @@ -28,24 +29,7 @@ export function patchWranglerDeps(config: Config) { patchRequireReactDomServerEdge(config); - // 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); + deleteOpenTelemetryDep(config.paths.output.standaloneRoot); } /**