Add support for node middleware in cloudflare - #38
Conversation
commit: |
d1b99ee to
f2de8e2
Compare
7093c5d to
e34ef09
Compare
Independent validation (build + local runtime)I hit this via Next 16 Baseline (released
|
| Route | Result |
|---|---|
HEAD / |
200, middleware cookies (from=middleware, with=love) + response-header: response-header |
HEAD /redirect |
307 → /redirect-destination, Set-Cookie: test=success |
HEAD /cookies |
200, Set-Cookie: foo=bar |
GET /api/middleware |
200 {"hello":"middleware"} |
HEAD /rewrite |
500 SyntaxError: Unexpected end of JSON input (may be HEAD-specific; flagging) |
So the core Node/proxy.ts path works end-to-end for cookies / redirect / direct middleware response. This unblocks Next 16 apps that can no longer opt proxy.ts back to Edge.
Merge blockers I can see
- PR is stacked on
conico/share-build(depends on Make a default overridable adapter in core #35), notmain. - GitHub currently reports
mergeable_state: dirtyvsconico/share-build— needs rebase. - Preview install story is broken for external testers (
@opennextjs/corenot published; shortpkg.pr.newURL points at the wrong repo). Publishing paired@opennextjs/cloudflare+@opennextjs/corepreviews (or documenting monorepo-only testing) would get more validation.
Happy to re-test after rebase, or run a fuller Playwright pass if useful. Real production apps (including mine) are still stuck on the middleware.ts deprecation workaround until this lands.
…y into core adapter feat: enhance build process with additional server bundle customization options chore: update package.json scripts for improved build and testing workflow test: add unit tests for adapter build process and server bundle generation fix: ensure proper handling of external dependencies and edge configuration in server bundle
…ests for resolve plugin
…specific overrides
…udflare specific overrides" This reverts commit 37c4d90.
…ad of throwing - Extract ValidateConfigResult type with success/message/shouldThrow/level - Convert validateFunctionOptions and validateSplittedFunctionOptions to return result objects - Remove logger dependency from validateConfig.ts - Preserve compatibilityMatrix, TODO comment, @ts-expect-error pragmas - Add 5 characterization tests in validateConfig.spec.ts - No caller impact: compileConfig.ts is the sole importer (updated in T3)
- Export OpenNextOutput interface (was internal) - Extract buildOpenNextOutput(buildOpts) for construction-only (no fs write) - Keep legacy generateOutput as thin wrapper (construction + file write) - Preserve all construction logic verbatim, including @ts-expect-error - Add 3 characterization tests in generateOutput.spec.ts - Backward compatible: byte-equivalent output to today
- Replace bare validateConfig(config) call with result-handling block - Throw on shouldThrow:true (bad routes — preserves existing behavior) - Log at appropriate level on shouldThrow:false (level field from T1) - All 3 export signatures and edge-runtime detection block unchanged - Direct callers (aws/build.ts, cloudflare/utils.ts) unaffected
…OpenNextAdapterOptions - Make OpenNextAdapterOptions<T = OpenNextOutput> and buildAdapter<T> generic - Add validateConfig override hook (runs after callback in modifyConfig) - Add generateOutput override hook (returns T, gated by skipGenerateOutput) - buildAdapter serializes override return via fs.writeFileSync (override never touches fs) - Default path uses buildOpenNextOutput (extracted in T2) - Add 5 new tests covering override behaviors + default path + skipGenerateOutput - All 16 existing adapter tests preserved; AWS/Cloudflare adapters compile with default T
When an adapter config specifies full package-specifier paths (e.g., @opennextjs/aws/overrides/wrappers/aws-lambda.js), esbuild cannot resolve them during bundling. Use createRequire(args.path).resolve() in the openNextResolvePlugin to convert package specifiers to filesystem-relative paths at build time, falling back to the original value if resolution fails. This fixes the openbuild:local build error: ERROR: Could not resolve "@opennextjs/aws/overrides/wrappers/aws-lambda.js" ERROR: Could not resolve "@opennextjs/aws/overrides/tagCache/dynamodb.js" Added test I verifying resolution of a mock package in node_modules.
…solution and improve path handling
4e9a367 to
cd8f83e
Compare
e34ef09 to
65cdda7
Compare
…dflare Next.js 16 forces proxy.ts onto the Node.js middleware runtime with no opt-out, and @opennextjs/cloudflare (1.20.2) doesn't support that yet — verified locally, `opennextjs-cloudflare build` fails on a real proxy.ts. middleware.ts + runtime: 'experimental-edge' builds clean on both next build and opennextjs-cloudflare build, same routing logic unchanged. Revert to proxy.ts once opennextjs/adapters-api#38 or opennextjs/opennextjs-cloudflare#1320 (or their successor) ships on npm — see docs/CLOUDFLARE-MIGRATION.md for the full investigation and why those specific PR numbers, not "whenever OpenNext adds support" in general.
# Conflicts: # packages/cloudflare/src/cli/adapter.ts # packages/core/src/build/adapter.spec.ts # packages/core/src/build/adapter.ts # packages/core/src/build/createMiddleware.ts # packages/core/src/build/middleware/buildNodeMiddleware.ts # packages/core/src/build/validateConfig.spec.ts # packages/core/src/build/validateConfig.ts
There was a problem hiding this comment.
Pull request overview
Adds first-class support for Node (non-edge) middleware in the Cloudflare adapter by making the Node middleware handler import path configurable at bundle time and wiring a dedicated middlewareBundle customization surface through the core build pipeline.
Changes:
- Make the Node middleware handler dynamically import the middleware entry via an esbuild-defined constant (
__OPEN_NEXT_NODE_MIDDLEWARE_PATH__). - Extend core build APIs to pass adapter outputs into middleware builds and add
middlewareBundlecustomization (plugins/patches/banner/externals). - Add/adjust Cloudflare build patches (webpack runtime chunk inlining, Turbopack chunk normalization, OpenTelemetry global utils patch) and add unit/e2e coverage.
Reviewed changes
Copilot reviewed 17 out of 17 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| packages/tests-unit/tests/build/copyAdapterFiles.test.ts | Adds unit tests for copyAdapterFiles, including custom destination support. |
| packages/core/src/core/nodeMiddlewareHandler.ts | Switches Node middleware loading to a bundle-time-defined import path. |
| packages/core/src/build/middleware/buildNodeMiddleware.ts | Updates external Node middleware build to copy adapter outputs, apply patches, and define the middleware import path. |
| packages/core/src/build/middleware/buildNodeMiddleware.spec.ts | Adds unit tests for buildExternalNodeMiddleware customization and error handling. |
| packages/core/src/build/createMiddleware.ts | Threads adapter outputs + middlewareBundle options into external Node middleware builds. |
| packages/core/src/build/copyAdapterFiles.ts | Adds optional destination override for copying adapter files. |
| packages/core/src/build/adapter.ts | Introduces middlewareBundle option and forwards outputs/bundle config into middleware creation. |
| packages/core/src/build/adapter.spec.ts | Updates expectations for new createMiddleware call signature and adds forwarding test for middlewareBundle. |
| packages/cloudflare/src/cli/build/patches/plugins/turbopack.ts | Normalizes traced Turbopack chunk paths and hardens generated requires. |
| packages/cloudflare/src/cli/build/patches/plugins/turbopack.spec.ts | Adds tests for Turbopack runtime patch behavior (Windows paths, no chunks). |
| packages/cloudflare/src/cli/build/patches/plugins/opentelemetry.ts | Adds patch to replace OpenTelemetry’s platform global usage with globalThis. |
| packages/cloudflare/src/cli/build/patches/plugins/opentelemetry.spec.ts | Adds tests validating the OpenTelemetry global-utils patch. |
| packages/cloudflare/src/cli/build/patches/ast/webpack-runtime.ts | Adds middleware-focused webpack runtime patch using traced chunk IDs; hardens chunks-dir handling. |
| packages/cloudflare/src/cli/build/patches/ast/webpack-runtime.spec.ts | Adds tests for middleware webpack runtime patching behavior. |
| packages/cloudflare/src/cli/adapter.ts | Configures the new middlewareBundle for Cloudflare (banner/plugins/patches) and adds OpenTelemetry + webpack middleware runtime patches. |
| examples-cloudflare/e2e/app-router/proxy.ts | Updates example middleware export style for the app-router e2e setup. |
| examples-cloudflare/e2e/app-router/e2e/middleware.rewrite.test.ts | Adds an e2e assertion for HEAD requests through middleware rewrite. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| await expect(buildExternalNodeMiddleware(options, undefined, {})).rejects.toThrow( | ||
| /without adapter outputs\.middleware/ | ||
| ); |
Add support for node middleware in cloudflare