Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

feat: Node.js Middleware support #3018

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
pieh merged 76 commits into main from feat/node-middleware-support
Sep 2, 2025
Merged

feat: Node.js Middleware support #3018

pieh merged 76 commits into main from feat/node-middleware-support
Sep 2, 2025

Conversation

Copy link
Contributor

@pieh pieh commented Jul 30, 2025
edited
Loading

Description

Adds support for Node.js Middleware support.

Important notes:

  • we run Node.js Middleware in Edge Functions
  • Edge Functions don't support bundling and resolving commonjs natively, so this includes in-memory virtual commonjs support, with needed modules being inlined and using commonjs module loading and resolution patches to support virtual commonjs modules. However we do have some limitations here:
    • we can't support .node modules (C++ Addons) - the only way to load them are from disk, as internally this relies on ~dllopen kind of native functions, so we can't simulate them in Deno/~Node.js runtime
  • Edge Functions don't support FS, so we also can't support FS in Node.js middleware
  • We use Deno's Node.js APIs compatibility, but don't run true Node.js - so far in testing I did not encounter a problem other than known limitations listed above. There is basic test using select Node.js builtins in Node.js middleware (that are not supported in Next.js Edge Runtime) showing them working

Documentation

Tests

  • We now run most of our existing middleware integration and e2e tests against both Edge and Node.js runtimes to make sure common middleware handling works the same with some exceptions (note the test-variants.json files that builds existing fixtures in 2 variants and then integration/e2e tests running both of them):
    • wasm and turbopack ones are skipped for Node.js middleware, because next build was failing with them so that was just Next.js not building them at all for Node.js variant and not the case of just missing support for them
  • New fixture and e2e tests for Node.js middleware specific support - in particular testing few Node.js builtins modules (node:crypto, node:path, node:http(s)) working that was not possible to do with Edge middleware
  • New fixture specifically for explicit message about limitation of .node modules

Copy link
Contributor

github-actions bot commented Jul 30, 2025
edited
Loading

📊 Package size report 0.4%↑

File Before (Size / Gzip) After (Size / Gzip)
dist/build/content/server.js 10.8 kB / 3.5 kB 7%↑11.5 kB / -1.69%↓3.4 kB
dist/build/functions/edge.js 21.1 kB / 5.7 kB 17%↑24.7 kB / 15%↑6.5 kB
dist/build/plugin-context.js 11.3 kB / 3.3 kB 4%↑11.7 kB / 2%↑3.4 kB
dist/run/config.js 1.3 kB / 649 B 1%↑1.4 kB / 0.8%↑654 B
dist/run/handlers/server.js 142.6 kB / 33.5 kB 0.04%↑142.7 kB / 0.05%↑33.5 kB
dist/run/next.cjs 23.9 kB / 5.9 kB 0.1%↑23.9 kB / 0.3%↑5.9 kB
edge-runtime/lib/cjs.ts 10.7 kB / 3.1 kB
edge-runtime/lib/middleware.test.ts 3.3 kB / 645 B
edge-runtime/lib/util.test.ts 1.6 kB / 356 B
edge-runtime/shim/edge.js 1.6 kB / 788 B
edge-runtime/shim/index.js 1.6 kB / 788 B
edge-runtime/shim/node.js 596 B / 347 B
package.json 3.3 kB / 1.2 kB 2%↑3.4 kB / 1%↑1.2 kB
Total (Includes all files) 2.9 MB / 816.1 kB 0.4%↑2.9 MB / 0.4%↑819.5 kB
Tarball size 773.5 kB 0.4%↑776.7 kB
Unchanged files
File Size (Size / Gzip)
dist/build/advanced-api-routes.js 4.3 kB / 1.4 kB
dist/build/cache.js 1.0 kB / 416 B
dist/build/content/next-shims/telemetry-storage.cjs 1.6 kB / 659 B
dist/build/content/prerendered.js 9.9 kB / 2.9 kB
dist/build/content/static.js 4.2 kB / 1.4 kB
dist/build/functions/server.js 4.9 kB / 1.6 kB
dist/build/image-cdn.js 54.0 kB / 11.1 kB
dist/build/templates/handler-monorepo.tmpl.js 1.6 kB / 643 B
dist/build/templates/handler.tmpl.js 1.4 kB / 596 B
dist/build/verification.js 4.5 kB / 1.6 kB
dist/esm-chunks/chunk-5V5HA6YA.js 27.0 kB / 5.4 kB
dist/esm-chunks/chunk-6BT4RYQJ.js 1.9 kB / 862 B
dist/esm-chunks/chunk-TLQCAGE2.js 62.6 kB / 11.2 kB
dist/esm-chunks/chunk-YUXQHOYO.js 187.9 kB / 33.2 kB
dist/index.js 3.9 kB / 1.2 kB
dist/run/constants.js 526 B / 319 B
dist/run/handlers/cache.cjs 15.6 kB / 3.8 kB
dist/run/handlers/request-context.cjs 5.3 kB / 1.7 kB
dist/run/handlers/tags-handler.cjs 7.2 kB / 2.4 kB
dist/run/handlers/tracer.cjs 30.2 kB / 6.3 kB
dist/run/handlers/use-cache-handler.js 48.0 kB / 10.8 kB
dist/run/handlers/wait-until.cjs 1.4 kB / 665 B
dist/run/headers.js 8.2 kB / 2.6 kB
dist/run/revalidate.js 1.0 kB / 479 B
dist/run/storage/regional-blob-store.cjs 21.3 kB / 6.1 kB
dist/run/storage/request-scoped-in-memory-cache.cjs 47.4 kB / 10.9 kB
dist/run/storage/storage.cjs 4.0 kB / 1.3 kB
dist/shared/blob-types.cjs 1.6 kB / 645 B
dist/shared/blobkey.js 742 B / 400 B
dist/shared/cache-types.cjs 1.3 kB / 566 B
edge-runtime/lib/headers.ts 1.9 kB / 841 B
edge-runtime/lib/logging.ts 115 B / 121 B
edge-runtime/lib/middleware.ts 3.6 kB / 1.4 kB
edge-runtime/lib/next-request.ts 3.3 kB / 1.1 kB
edge-runtime/lib/response.ts 10.0 kB / 3.0 kB
edge-runtime/lib/routing.ts 15.3 kB / 4.0 kB
edge-runtime/lib/util.ts 3.7 kB / 1.3 kB
edge-runtime/matchers.json 3 B / 23 B
edge-runtime/middleware.ts 2.4 kB / 1.0 kB
edge-runtime/next.config.json 3 B / 23 B
edge-runtime/README.md 992 B / 509 B
edge-runtime/vendor.ts 1.1 kB / 360 B
edge-runtime/vendor/deno.land/std@0.175.0/_util/asserts.ts 854 B / 461 B
edge-runtime/vendor/deno.land/std@0.175.0/_util/os.ts 644 B / 355 B
edge-runtime/vendor/deno.land/std@0.175.0/async/abortable.ts 4.0 kB / 1.0 kB
edge-runtime/vendor/deno.land/std@0.175.0/async/deadline.ts 974 B / 544 B
edge-runtime/vendor/deno.land/std@0.175.0/async/debounce.ts 2.2 kB / 956 B
edge-runtime/vendor/deno.land/std@0.175.0/async/deferred.ts 1.5 kB / 798 B
edge-runtime/vendor/deno.land/std@0.175.0/async/delay.ts 1.8 kB / 845 B
edge-runtime/vendor/deno.land/std@0.175.0/async/mod.ts 465 B / 241 B
edge-runtime/vendor/deno.land/std@0.175.0/async/mux_async_iterator.ts 2.5 kB / 1.1 kB
edge-runtime/vendor/deno.land/std@0.175.0/async/pool.ts 3.2 kB / 1.4 kB
edge-runtime/vendor/deno.land/std@0.175.0/async/retry.ts 2.4 kB / 1.0 kB
edge-runtime/vendor/deno.land/std@0.175.0/async/tee.ts 2.1 kB / 924 B
edge-runtime/vendor/deno.land/std@0.175.0/bytes/index_of_needle.ts 1.4 kB / 668 B
edge-runtime/vendor/deno.land/std@0.175.0/crypto/timing_safe_equal.ts 875 B / 442 B
edge-runtime/vendor/deno.land/std@0.175.0/datetime/to_imf.ts 1.3 kB / 681 B
edge-runtime/vendor/deno.land/std@0.175.0/encoding/base64.ts 2.5 kB / 1.0 kB
edge-runtime/vendor/deno.land/std@0.175.0/encoding/base64url.ts 2.0 kB / 872 B
edge-runtime/vendor/deno.land/std@0.175.0/flags/mod.ts 22.6 kB / 5.9 kB
edge-runtime/vendor/deno.land/std@0.175.0/fmt/colors.ts 12.4 kB / 2.7 kB
edge-runtime/vendor/deno.land/std@0.175.0/fmt/printf.ts 27.7 kB / 7.7 kB
edge-runtime/vendor/deno.land/std@0.175.0/http/cookie.ts 11.5 kB / 3.6 kB
edge-runtime/vendor/deno.land/std@0.175.0/node/_core.ts 2.3 kB / 716 B
edge-runtime/vendor/deno.land/std@0.175.0/node/_events.d.ts 27.2 kB / 5.8 kB
edge-runtime/vendor/deno.land/std@0.175.0/node/_events.mjs 28.0 kB / 7.4 kB
edge-runtime/vendor/deno.land/std@0.175.0/node/_global.d.ts 1.7 kB / 650 B
edge-runtime/vendor/deno.land/std@0.175.0/node/_next_tick.ts 5.0 kB / 1.4 kB
edge-runtime/vendor/deno.land/std@0.175.0/node/_process/exiting.ts 138 B / 138 B
edge-runtime/vendor/deno.land/std@0.175.0/node/_process/process.ts 3.8 kB / 1.4 kB
edge-runtime/vendor/deno.land/std@0.175.0/node/_process/stdio.mjs 336 B / 233 B
edge-runtime/vendor/deno.land/std@0.175.0/node/_process/streams.mjs 4.0 kB / 1.4 kB
edge-runtime/vendor/deno.land/std@0.175.0/node/_stream.d.ts 53.2 kB / 11.9 kB
edge-runtime/vendor/deno.land/std@0.175.0/node/_stream.mjs 91.2 kB / 25.4 kB
edge-runtime/vendor/deno.land/std@0.175.0/node/_util/_util_callbackify.ts 4.3 kB / 1.7 kB
edge-runtime/vendor/deno.land/std@0.175.0/node/_utils.ts 5.9 kB / 2.0 kB
edge-runtime/vendor/deno.land/std@0.175.0/node/assert.ts 23.1 kB / 4.4 kB
edge-runtime/vendor/deno.land/std@0.175.0/node/assertion_error.ts 19.6 kB / 6.1 kB
edge-runtime/vendor/deno.land/std@0.175.0/node/async_hooks.ts 7.7 kB / 2.1 kB
edge-runtime/vendor/deno.land/std@0.175.0/node/buffer.ts 262 B / 204 B
edge-runtime/vendor/deno.land/std@0.175.0/node/events.ts 303 B / 221 B
edge-runtime/vendor/deno.land/std@0.175.0/node/internal_binding/_libuv_winerror.ts 7.8 kB / 1.9 kB
edge-runtime/vendor/deno.land/std@0.175.0/node/internal_binding/_listen.ts 561 B / 342 B
edge-runtime/vendor/deno.land/std@0.175.0/node/internal_binding/_node.ts 443 B / 335 B
edge-runtime/vendor/deno.land/std@0.175.0/node/internal_binding/_utils.ts 2.4 kB / 938 B
edge-runtime/vendor/deno.land/std@0.175.0/node/internal_binding/_winerror.ts 354.4 kB / 64.4 kB
edge-runtime/vendor/deno.land/std@0.175.0/node/internal_binding/#_timingsafeequal_bd5c8.ts 479 B / 268 B
edge-runtime/vendor/deno.land/std@0.175.0/node/internal_binding/ares.ts 2.4 kB / 1.1 kB
edge-runtime/vendor/deno.land/std@0.175.0/node/internal_binding/async_wrap.ts 4.0 kB / 1.8 kB
edge-runtime/vendor/deno.land/std@0.175.0/node/internal_binding/buffer.ts 3.5 kB / 1.3 kB
edge-runtime/vendor/deno.land/std@0.175.0/node/internal_binding/cares_wrap.ts 15.2 kB / 3.9 kB
edge-runtime/vendor/deno.land/std@0.175.0/node/internal_binding/config.ts 87 B / 104 B
edge-runtime/vendor/deno.land/std@0.175.0/node/internal_binding/connection_wrap.ts 2.6 kB / 1.3 kB
edge-runtime/vendor/deno.land/std@0.175.0/node/internal_binding/constants.ts 21.5 kB / 5.1 kB
edge-runtime/vendor/deno.land/std@0.175.0/node/internal_binding/contextify.ts 87 B / 104 B
edge-runtime/vendor/deno.land/std@0.175.0/node/internal_binding/credentials.ts 87 B / 104 B
edge-runtime/vendor/deno.land/std@0.175.0/node/internal_binding/crypto.ts 448 B / 244 B
edge-runtime/vendor/deno.land/std@0.175.0/node/internal_binding/errors.ts 87 B / 104 B
edge-runtime/vendor/deno.land/std@0.175.0/node/internal_binding/fs_dir.ts 87 B / 104 B
edge-runtime/vendor/deno.land/std@0.175.0/node/internal_binding/fs_event_wrap.ts 87 B / 104 B
edge-runtime/vendor/deno.land/std@0.175.0/node/internal_binding/fs.ts 87 B / 104 B
edge-runtime/vendor/deno.land/std@0.175.0/node/internal_binding/handle_wrap.ts 1.8 kB / 1.0 kB
edge-runtime/vendor/deno.land/std@0.175.0/node/internal_binding/heap_utils.ts 87 B / 104 B
edge-runtime/vendor/deno.land/std@0.175.0/node/internal_binding/http_parser.ts 87 B / 104 B
edge-runtime/vendor/deno.land/std@0.175.0/node/internal_binding/icu.ts 87 B / 104 B
edge-runtime/vendor/deno.land/std@0.175.0/node/internal_binding/inspector.ts 87 B / 104 B
edge-runtime/vendor/deno.land/std@0.175.0/node/internal_binding/js_stream.ts 87 B / 104 B
edge-runtime/vendor/deno.land/std@0.175.0/node/internal_binding/messaging.ts 87 B / 104 B
edge-runtime/vendor/deno.land/std@0.175.0/node/internal_binding/mod.ts 3.1 kB / 955 B
edge-runtime/vendor/deno.land/std@0.175.0/node/internal_binding/module_wrap.ts 87 B / 104 B
edge-runtime/vendor/deno.land/std@0.175.0/node/internal_binding/native_module.ts 87 B / 104 B
edge-runtime/vendor/deno.land/std@0.175.0/node/internal_binding/natives.ts 87 B / 104 B
edge-runtime/vendor/deno.land/std@0.175.0/node/internal_binding/node_file.ts 2.9 kB / 1.5 kB
edge-runtime/vendor/deno.land/std@0.175.0/node/internal_binding/node_options.ts 1.8 kB / 989 B
edge-runtime/vendor/deno.land/std@0.175.0/node/internal_binding/options.ts 87 B / 104 B
edge-runtime/vendor/deno.land/std@0.175.0/node/internal_binding/os.ts 87 B / 104 B
edge-runtime/vendor/deno.land/std@0.175.0/node/internal_binding/performance.ts 87 B / 104 B
edge-runtime/vendor/deno.land/std@0.175.0/node/internal_binding/pipe_wrap.ts 10.4 kB / 3.3 kB
edge-runtime/vendor/deno.land/std@0.175.0/node/internal_binding/process_methods.ts 87 B / 104 B
edge-runtime/vendor/deno.land/std@0.175.0/node/internal_binding/report.ts 87 B / 104 B
edge-runtime/vendor/deno.land/std@0.175.0/node/internal_binding/serdes.ts 87 B / 104 B
edge-runtime/vendor/deno.land/std@0.175.0/node/internal_binding/signal_wrap.ts 87 B / 104 B
edge-runtime/vendor/deno.land/std@0.175.0/node/internal_binding/spawn_sync.ts 87 B / 104 B
edge-runtime/vendor/deno.land/std@0.175.0/node/internal_binding/stream_wrap.ts 9.3 kB / 2.8 kB
edge-runtime/vendor/deno.land/std@0.175.0/node/internal_binding/string_decoder.ts 504 B / 261 B
edge-runtime/vendor/deno.land/std@0.175.0/node/internal_binding/symbols.ts 1.4 kB / 828 B
edge-runtime/vendor/deno.land/std@0.175.0/node/internal_binding/task_queue.ts 87 B / 104 B
edge-runtime/vendor/deno.land/std@0.175.0/node/internal_binding/tcp_wrap.ts 13.1 kB / 3.7 kB
edge-runtime/vendor/deno.land/std@0.175.0/node/internal_binding/timers.ts 87 B / 104 B
edge-runtime/vendor/deno.land/std@0.175.0/node/internal_binding/tls_wrap.ts 87 B / 104 B
edge-runtime/vendor/deno.land/std@0.175.0/node/internal_binding/trace_events.ts 87 B / 104 B
edge-runtime/vendor/deno.land/std@0.175.0/node/internal_binding/tty_wrap.ts 87 B / 104 B
edge-runtime/vendor/deno.land/std@0.175.0/node/internal_binding/types.ts 5.7 kB / 1.4 kB
edge-runtime/vendor/deno.land/std@0.175.0/node/internal_binding/udp_wrap.ts 12.4 kB / 3.6 kB
edge-runtime/vendor/deno.land/std@0.175.0/node/internal_binding/url.ts 87 B / 104 B
edge-runtime/vendor/deno.land/std@0.175.0/node/internal_binding/util.ts 4.0 kB / 1.8 kB
edge-runtime/vendor/deno.land/std@0.175.0/node/internal_binding/uv.ts 20.1 kB / 3.8 kB
edge-runtime/vendor/deno.land/std@0.175.0/node/internal_binding/v8.ts 87 B / 104 B
edge-runtime/vendor/deno.land/std@0.175.0/node/internal_binding/worker.ts 87 B / 104 B
edge-runtime/vendor/deno.land/std@0.175.0/node/internal_binding/zlib.ts 87 B / 104 B
edge-runtime/vendor/deno.land/std@0.175.0/node/internal/buffer.d.ts 73.6 kB / 12.1 kB
edge-runtime/vendor/deno.land/std@0.175.0/node/internal/buffer.mjs 66.1 kB / 10.6 kB
edge-runtime/vendor/deno.land/std@0.175.0/node/internal/crypto/_keys.ts 463 B / 262 B
edge-runtime/vendor/deno.land/std@0.175.0/node/internal/crypto/constants.ts 252 B / 173 B
edge-runtime/vendor/deno.land/std@0.175.0/node/internal/error_codes.ts 322 B / 250 B
edge-runtime/vendor/deno.land/std@0.175.0/node/internal/errors.ts 78.9 kB / 17.4 kB
edge-runtime/vendor/deno.land/std@0.175.0/node/internal/fixed_queue.ts 4.4 kB / 1.2 kB
edge-runtime/vendor/deno.land/std@0.175.0/node/internal/hide_stack_frames.ts 550 B / 377 B
edge-runtime/vendor/deno.land/std@0.175.0/node/internal/net.ts 3.1 kB / 1.5 kB
edge-runtime/vendor/deno.land/std@0.175.0/node/internal/normalize_encoding.mjs 2.1 kB / 500 B
edge-runtime/vendor/deno.land/std@0.175.0/node/internal/options.ts 1.7 kB / 959 B
edge-runtime/vendor/deno.land/std@0.175.0/node/internal/primordials.mjs 1.8 kB / 431 B
edge-runtime/vendor/deno.land/std@0.175.0/node/internal/process/per_thread.mjs 7.8 kB / 2.3 kB
edge-runtime/vendor/deno.land/std@0.175.0/node/internal/readline/callbacks.mjs 3.8 kB / 1.4 kB
edge-runtime/vendor/deno.land/std@0.175.0/node/internal/readline/utils.mjs 14.3 kB / 3.7 kB
edge-runtime/vendor/deno.land/std@0.175.0/node/internal/streams/destroy.mjs 6.9 kB / 1.8 kB
edge-runtime/vendor/deno.land/std@0.175.0/node/internal/streams/end-of-stream.mjs 7.1 kB / 1.9 kB
edge-runtime/vendor/deno.land/std@0.175.0/node/internal/streams/utils.mjs 5.9 kB / 1.2 kB
edge-runtime/vendor/deno.land/std@0.175.0/node/internal/util.mjs 4.0 kB / 1.4 kB
edge-runtime/vendor/deno.land/std@0.175.0/node/internal/util/comparisons.ts 16.6 kB / 3.8 kB
edge-runtime/vendor/deno.land/std@0.175.0/node/internal/util/debuglog.ts 3.2 kB / 1.4 kB
edge-runtime/vendor/deno.land/std@0.175.0/node/internal/util/inspect.mjs 71.5 kB / 19.8 kB
edge-runtime/vendor/deno.land/std@0.175.0/node/internal/util/types.ts 3.7 kB / 1.3 kB
edge-runtime/vendor/deno.land/std@0.175.0/node/internal/validators.mjs 8.0 kB / 2.1 kB
edge-runtime/vendor/deno.land/std@0.175.0/node/process.ts 19.4 kB / 5.2 kB
edge-runtime/vendor/deno.land/std@0.175.0/node/stream.ts 671 B / 346 B
edge-runtime/vendor/deno.land/std@0.175.0/node/string_decoder.ts 10.3 kB / 3.3 kB
edge-runtime/vendor/deno.land/std@0.175.0/node/util.ts 7.8 kB / 2.2 kB
edge-runtime/vendor/deno.land/std@0.175.0/node/util/types.ts 199 B / 153 B
edge-runtime/vendor/deno.land/std@0.175.0/path/_constants.ts 2.0 kB / 727 B
edge-runtime/vendor/deno.land/std@0.175.0/path/_interface.ts 728 B / 369 B
edge-runtime/vendor/deno.land/std@0.175.0/path/_util.ts 5.0 kB / 1.6 kB
edge-runtime/vendor/deno.land/std@0.175.0/path/common.ts 1.2 kB / 607 B
edge-runtime/vendor/deno.land/std@0.175.0/path/glob.ts 12.7 kB / 3.9 kB
edge-runtime/vendor/deno.land/std@0.175.0/path/mod.ts 1.4 kB / 690 B
edge-runtime/vendor/deno.land/std@0.175.0/path/posix.ts 13.9 kB / 3.7 kB
edge-runtime/vendor/deno.land/std@0.175.0/path/separator.ts 259 B / 209 B
edge-runtime/vendor/deno.land/std@0.175.0/path/win32.ts 28.5 kB / 6.4 kB
edge-runtime/vendor/deno.land/std@0.175.0/streams/write_all.ts 2.2 kB / 598 B
edge-runtime/vendor/deno.land/std@0.175.0/testing/_diff.ts 11.6 kB / 3.6 kB
edge-runtime/vendor/deno.land/std@0.175.0/testing/_format.ts 705 B / 462 B
edge-runtime/vendor/deno.land/std@0.175.0/testing/asserts.ts 25.5 kB / 5.7 kB
edge-runtime/vendor/deno.land/std@0.175.0/types.d.ts 4.2 kB / 1.2 kB
edge-runtime/vendor/deno.land/x/htmlrewriter@v1.0.0/pkg/htmlrewriter_bg.wasm 573.2 kB / 262.7 kB
edge-runtime/vendor/deno.land/x/htmlrewriter@v1.0.0/pkg/htmlrewriter.js 31.0 kB / 4.7 kB
edge-runtime/vendor/deno.land/x/htmlrewriter@v1.0.0/src/index.ts 2.6 kB / 989 B
edge-runtime/vendor/deno.land/x/htmlrewriter@v1.0.0/src/types.d.ts 2.1 kB / 446 B
edge-runtime/vendor/deno.land/x/path_to_regexp@v6.2.1/index.ts 15.4 kB / 4.2 kB
edge-runtime/vendor/manifest.json 104 B / 119 B
edge-runtime/vendor/v1-7-0--edge-utils.netlify.app/logger/logger.ts 3.2 kB / 747 B
edge-runtime/vendor/v1-7-0--edge-utils.netlify.app/logger/mod.ts 29 B / 49 B
LICENSE 1.1 kB / 661 B
manifest.yml 31 B / 51 B
README.md 2.8 kB / 1.2 kB

🤖 This report was automatically generated by pkg-size-action

@pieh pieh force-pushed the feat/node-middleware-support branch from 308acfe to 2031077 Compare July 31, 2025 19:08
pieh added 12 commits August 20, 2025 19:09
@@ -101,7 +105,7 @@ export async function getMockedRequestHandler(...args: Parameters<typeof getRequ
// only try to get .html files from the blob store
if (typeof path === 'string' && path.endsWith('.html')) {
const cacheStore = getMemoizedKeyValueStoreBackedByRegionalBlobStore()
const relPath = relative(resolve('.next/server/pages'), path)
const relPath = relative(resolve(nextConfig.distDir, 'server/pages'), path)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not related to Node.js Middleware support, but this fixes serving static files if non-default distDir is used (test setup for Node.js middleware variants is hitting those conditions)

mrstork reacted with thumbs up emoji
@pieh pieh added the test all versions Run e2e tests against old and canary versions of Next.js label Aug 26, 2025
@pieh pieh marked this pull request as ready for review August 26, 2025 12:48
@pieh pieh requested a review from a team as a code owner August 26, 2025 12:48
@@ -14,6 +14,7 @@ import type { PrerenderManifest, RoutesManifest } from 'next/dist/build/index.js
import type { MiddlewareManifest } from 'next/dist/build/webpack/plugins/middleware-plugin.js'
import type { PagesManifest } from 'next/dist/build/webpack/plugins/pages-manifest-plugin.js'
import type { NextConfigComplete } from 'next/dist/server/config-shared.js'
import type { FunctionsConfigManifest } from 'next-with-cache-handler-v2/dist/build/index.js'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No change needed - I continue to be a little worried about this way of getting types, but I still have no better solution to offer.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I don't have really answer for it other than possibly adoption of Adapters API once it become stable could stabilize types situation as this will be public API with proper semver considerations (tho even with Adapters API if we will look to support multiple Next.js major versions with same adapter, we likely would run in similar problem again)

registeredModules.set(target, { source, loaded: false, filepath: target })
}

if (!hookedIn) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Under what conditions does registerCJSModules run multiple times?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't call it in practice today more than once, so this is just defensive check that made sense to me to not to try monkey-patch Module functions multiple times in case something changed in the future

let target = args[0]
let isRelative = args?.[0].startsWith('.')

if (isRelative) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unrelated to this line, just made me wonder - What is the leading prefix when a path is absolute?

Copy link
Contributor Author

@pieh pieh Aug 29, 2025
edited
Loading

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think on posix it would always start with / (main use case for us will be posix when edge function is deployed), but on Windows it can be drive letter (we do run integration tests on windows which would do that and also ntl serve on Windows would also use that, which is why I did spend some time on making sure it works on Windows).

ESM allows also to use file:// protocol, but that doesn't seem allowed with CJS's require

I do want to mention that if target is not relative, the possibilities are

  • node.js builtins (node:fs, fs etc)
  • node_modules package path (package-name, package-name/not-main-export)
  • absolute path

const cache = name.endsWith('middleware') ? undefined : ('manual' as const)
const functionHandlerName = getHandlerName({ name: def.name })
const functionName = 'Next.js Middleware Handler'
const cache = def.name.endsWith('middleware') ? undefined : ('manual' as const)
Copy link
Contributor

@mrstork mrstork Aug 29, 2025
edited
Loading

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps we could move this into def: EdgeOrNodeMiddlewareDefinition i.e. def.cache or similar

Copy link
Contributor Author

@pieh pieh Aug 29, 2025
edited
Loading

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See https://github.com/opennextjs/opennextjs-netlify/pull/3018/files#r2310524071 first

We also should never ever hit condition where name does not end with middleware, so conditional part can be removed and instead cache property will always be undefined. If we ever hit the condition that would set manual cache for actual middleware - this would be a bug to fix anyway

I just did not want to make more changes than necessary here to make review hopefully less involved and maybe do follow up to clean up after, but I guess the fact that I did change for functionName, but not the cache probably resulted in the opposite effect of it being more confusing)

mrstork reacted with thumbs up emoji
Copy link
Contributor

@mrstork mrstork Aug 29, 2025
edited
Loading

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I get it now! Doing the rest in a follow-up makes sense to me.

const functionHandlerName = getHandlerName({ name })
const functionName = name.endsWith('middleware')
? 'Next.js Middleware Handler'
: `Next.js Edge Handler: ${page}`
Copy link
Contributor

@mrstork mrstork Aug 29, 2025
edited
Loading

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was the condition for Next.js Edge Handler: ${page} not ever used?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, we only support middleware with edge functions. Edge Runtime Pages and API routes are being handled in lambda (and we don't do anything special to do so, it's just how standalone mode operate normally).

I'm not sure why we even had this condition here. I did remove it here because the page does not exist in node middleware's function config and it was just making something we don't even hit messy with conditions.

return Array.isArray(definition.matchers)
}

type EdgeOrNodeMiddlewareDefinition = {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thoughts on keeping the two types separate for now and using something like EdgeMiddlewareDefinition | NodeMiddlewareDefinition downstream?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typescript was really unhappy with my attempts to do so for the parts that are shared, so that's why I opted to creating common type with hoisted (duplicated heh) common fields that common handling needs.

mrstork reacted with thumbs up emoji
@pieh pieh merged commit ddfe7f4 into main Sep 2, 2025
158 of 160 checks passed
@pieh pieh deleted the feat/node-middleware-support branch September 2, 2025 15:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Reviewers

@mrstork mrstork mrstork approved these changes

Assignees
No one assigned
Labels
test all versions Run e2e tests against old and canary versions of Next.js
Projects
None yet
Milestone
No milestone
Development

Successfully merging this pull request may close these issues.

2 participants

AltStyle によって変換されたページ (->オリジナル) /