Skip to content

Commit

Permalink
fix build issues with @opentelemetry (#302)
Browse files Browse the repository at this point in the history
  • Loading branch information
vicb authored Jan 30, 2025
1 parent deaf845 commit 67acb2f
Show file tree
Hide file tree
Showing 7 changed files with 329 additions and 42 deletions.
7 changes: 7 additions & 0 deletions .changeset/selfish-pumpkins-sin.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@opennextjs/cloudflare": patch
---

fix build issues with `@opentelemetry`

By using the pre-compiled library provided by Next.
14 changes: 6 additions & 8 deletions packages/cloudflare/src/cli/build/bundle-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { build, Plugin } from "esbuild";
import { patchOptionalDependencies } from "./patches/ast/optional-deps.js";
import { patchVercelOgLibrary } from "./patches/ast/patch-vercel-og-library.js";
import * as patches from "./patches/index.js";
import fixRequire from "./patches/plugins/require.js";
import inlineRequirePagePlugin from "./patches/plugins/require-page.js";
import setWranglerExternal from "./patches/plugins/wrangler-external.js";
import { normalizePath, patchCodeWithValidations } from "./utils/index.js";
Expand Down Expand Up @@ -49,7 +50,6 @@ export async function bundleServer(buildOpts: BuildOptions): Promise<void> {

console.log(`\x1b[35m⚙️ Bundling the OpenNext server...\n\x1b[0m`);

patches.patchWranglerDeps(buildOpts);
await patches.updateWebpackChunksFile(buildOpts);
patchVercelOgLibrary(buildOpts);

Expand All @@ -70,6 +70,7 @@ export async function bundleServer(buildOpts: BuildOptions): Promise<void> {
createFixRequiresESBuildPlugin(buildOpts),
inlineRequirePagePlugin(buildOpts),
setWranglerExternal(),
fixRequire(),
],
external: ["./middleware/handler.mjs", ...optionalDependencies],
alias: {
Expand Down Expand Up @@ -102,7 +103,6 @@ export async function bundleServer(buildOpts: BuildOptions): Promise<void> {
"process.env.NODE_ENV": '"production"',
"process.env.NEXT_MINIMAL": "true",
},
// We need to set platform to node so that esbuild doesn't complain about the node imports
platform: "node",
banner: {
js: `
Expand Down Expand Up @@ -168,7 +168,10 @@ globalThis.__BUILD_TIMESTAMP_MS__ = ${Date.now()};
/**
* This function applies patches required for the code to run on workers.
*/
async function updateWorkerBundledCode(workerOutputFile: string, buildOpts: BuildOptions): Promise<void> {
export async function updateWorkerBundledCode(
workerOutputFile: string,
buildOpts: BuildOptions
): Promise<void> {
const code = await readFile(workerOutputFile, "utf8");

const patchedCode = await patchCodeWithValidations(code, [
Expand All @@ -191,11 +194,6 @@ async function updateWorkerBundledCode(workerOutputFile: string, buildOpts: Buil
// TODO: implement for cf (possibly in @opennextjs/aws)
.replace("patchAsyncStorage();", "//patchAsyncStorage();"),
],
[
'`eval("require")` calls',
(code) => code.replaceAll('eval("require")', "require"),
{ isOptional: true },
],
[
"`require.resolve` call",
// workers do not support dynamic require nor require.resolve
Expand Down
54 changes: 54 additions & 0 deletions packages/cloudflare/src/cli/build/patches/plugins/require.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import fs from "node:fs/promises";

import type { PluginBuild } from "esbuild";

export default function fixRequire() {
return {
name: "fix-require",

setup: async (build: PluginBuild) => {
build.onLoad({ filter: /.*/ }, async ({ path }) => {
let contents = await fs.readFile(path, "utf-8");

// `eval(...)` is not supported by workerd.
contents = contents.replaceAll(`eval("require")`, "require");

// `@opentelemetry` has a few issues.
//
// Next.js has the following code in `next/dist/server/lib/trace/tracer.js`:
//
// try {
// api = require('@opentelemetry/api');
// } catch (err) {
// api = require('next/dist/compiled/@opentelemetry/api');
// }
//
// The intent is to allow users to install their own version of `@opentelemetry/api`.
//
// The problem is that even when users do not explicitely install `@opentelemetry/api`,
// `require('@opentelemetry/api')` resolves to the package which is a dependency
// of Next.
//
// The second problem is that when Next traces files, it would not copy the `api/build/esm`
// folder (used by the `module` conditions in package.json) it would only copy `api/build/src`.
// This could be solved by updating the next config:
//
// const nextConfig: NextConfig = {
// // ...
// outputFileTracingIncludes: {
// "*": ["./node_modules/@opentelemetry/api/build/**/*"],
// },
// };
//
// We can consider doing that when we want to enable users to install their own version
// of `@opentelemetry/api`. For now we simply use the pre-compiled version.
contents = contents.replace(
/require\(.@opentelemetry\/api.\)/g,
`require("next/dist/compiled/@opentelemetry/api")`
);

return { contents };
});
},
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,3 @@ export * from "./patch-exception-bubbling.js";
export * from "./patch-find-dir.js";
export * from "./patch-load-instrumentation-module.js";
export * from "./patch-read-file.js";
export * from "./wrangler-deps.js";

This file was deleted.

Loading

0 comments on commit 67acb2f

Please sign in to comment.