Skip to content

Commit

Permalink
Remove the need for aliases in wrangler.toml
Browse files Browse the repository at this point in the history
  • Loading branch information
vicb committed Sep 13, 2024
1 parent 01565e0 commit 72e9a7b
Show file tree
Hide file tree
Showing 8 changed files with 73 additions and 25 deletions.
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);
}

0 comments on commit 72e9a7b

Please sign in to comment.