Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 0 additions & 10 deletions TODO.txt
Original file line number Diff line number Diff line change
Expand Up @@ -46,16 +46,6 @@ minify = false

# Use the new Workers + Assets to host the static frontend files
experimental_assets = { directory = ".worker-next/assets", binding = "ASSETS" }

# The aliases below should not be needed (we don't want users to have to define the aliases themselves)
[alias]
# critters is `require`d from `pages.runtime.prod.js` when running wrangler dev, so we need to stub it out
"critters" = "./.next/standalone/node_modules/cf/templates/shims/empty.ts"
# @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"
```

- Build the builder
Expand Down
14 changes: 5 additions & 9 deletions builder/src/build/build-worker/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { patchReadFile } from "./patches/to-investigate/patchReadFile";
import { patchFindDir } from "./patches/to-investigate/patchFindDir";
import { inlineNextRequire } from "./patches/to-investigate/inlineNextRequire";
import { inlineEvalManifest } from "./patches/to-investigate/inlineEvalManifest";
import { patchWranglerDeps } from "./patches/to-investigate/wranglerDeps";

/**
* Using the Next.js build output in the `.next` directory builds a workerd compatible output
Expand All @@ -33,6 +34,10 @@ export async function buildWorker(
)?.[1] ?? {};

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

patchWranglerDeps(nextjsAppPaths);
updateWebpackChunksFile(nextjsAppPaths);

await build({
entryPoints: [workerEntrypoint],
bundle: true,
Expand All @@ -51,13 +56,6 @@ export async function buildWorker(
// which comes from https://github.com/vercel/edge-runtime/blob/6e96b55f/packages/primitives/src/primitives/load.js#L57-L63
// QUESTION: Why did I encountered this but mhart didn't?
"next/dist/compiled/edge-runtime": `${templateDir}/shims/empty.ts`,
// Note: we need to stub out `@opentelemetry/api` as that is problematic and doesn't get properly bundled...
critters: `${templateDir}/shims/empty.ts`,
// Note: we need to stub out `@opentelemetry/api` as it is problematic
// 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": `${templateDir}/shims/throw.ts`,
// `@next/env` is a library Next.js uses for loading dotenv files, for obvious reasons we need to stub it here
// source: https://github.com/vercel/next.js/tree/0ac10d79720/packages/next-env
"@next/env": `${templateDir}/shims/env.ts`,
Expand Down Expand Up @@ -98,8 +96,6 @@ export async function buildWorker(

await updateWorkerBundledCode(workerOutputFile, nextjsAppPaths);

updateWebpackChunksFile(nextjsAppPaths);

console.log(`\x1b[35m⚙️ Copying asset files...\n\x1b[0m`);
await cp(
`${nextjsAppPaths.dotNextDir}/static`,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import path from "node:path";
import { NextjsAppPaths } from "builder/src/nextjsPaths";
import { cpSync, mkdirSync } from "node:fs";
import { NextjsAppPaths } from "../../../../nextjsPaths";
import { cpSync } from "node:fs";

/**
* Copy templates in the standalone folder.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { globSync } from "glob";
import { NextjsAppPaths } from "builder/src/nextjsPaths";
import { NextjsAppPaths } from "../../../../nextjsPaths";

/**
* `evalManifest` relies on readFileSync so we need to patch the function so that it instead returns the content of the manifest files
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { readFileSync, existsSync } from "node:fs";
import { NextjsAppPaths } from "builder/src/nextjsPaths";
import { NextjsAppPaths } from "../../../../nextjsPaths";

/**
* The following avoid various Next.js specific files `require`d at runtime since we can just read
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { NextjsAppPaths } from "builder/src/nextjsPaths";
import { NextjsAppPaths } from "../../../../nextjsPaths";
import { existsSync } from "node:fs";

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { readFileSync } from "node:fs";
import { globSync } from "glob";
import { NextjsAppPaths } from "builder/src/nextjsPaths";
import { NextjsAppPaths } from "../../../../nextjsPaths";

export function patchReadFile(
code: string,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import path from "node:path";
import fs, { writeFileSync } from "node:fs";
import { NextjsAppPaths } from "../../../../nextjsPaths";

export function patchWranglerDeps(paths: NextjsAppPaths) {
console.log("# patchWranglerDeps");

console.log({ base: paths.standaloneAppDotNextDir });

// Patch .next/standalone/node_modules/next/dist/compiled/next-server/pages.runtime.prod.js
//
// Remove the need for an alias in wrangler.toml:
//
// [alias]
// # critters is `require`d from `pages.runtime.prod.js` when running wrangler dev, so we need to stub it out
// "critters" = "./.next/standalone/node_modules/cf/templates/shims/empty.ts"
const pagesRuntimeFile = path.join(
paths.standaloneAppDir,
"node_modules",
"next",
"dist",
"compiled",
"next-server",
"pages.runtime.prod.js"
);

const patchedPagesRuntime = fs
.readFileSync(pagesRuntimeFile, "utf-8")
.replace(`e.exports=require("critters")`, `e.exports={}`);

fs.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 = path.join(
paths.standaloneAppDir,
"node_modules",
"next",
"dist",
"server",
"lib",
"trace",
"tracer.js"
);

const pacthedTracer = fs
.readFileSync(tracerFile, "utf-8")
.replaceAll(
/\w+\s*=\s*require\([^/]*opentelemetry.*\)/g,
`throw new Error("@opentelemetry/api")`
);

writeFileSync(tracerFile, pacthedTracer);
}
2 changes: 1 addition & 1 deletion next/api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,6 @@
"@playwright/test": "^1.46.1",
"@types/node": "^22.2.0",
"node-url": "npm:url@^0.11.4",
"wrangler": "3.76.0"
"wrangler": "3.77.0"
}
}
81 changes: 42 additions & 39 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading