Skip to content

Add nodejs runtime support for middleware#75624

Merged
ijjk merged 1 commit into
canaryfrom
ijjk/node-middleware
Feb 4, 2025
Merged

Add nodejs runtime support for middleware#75624
ijjk merged 1 commit into
canaryfrom
ijjk/node-middleware

Conversation

@ijjk

@ijjk ijjk commented Feb 3, 2025

Copy link
Copy Markdown
Member

This allows setting runtime: 'nodejs' in middleware, which removes the constraint of only using edge runtime APIs for middleware. This doesn't change the signature of middleware and it still receives (req: NextRequest, event: NextFetchEvent) => Response.

x-ref: #71727
x-ref: #46722

@ijjk ijjk force-pushed the ijjk/node-middleware branch 6 times, most recently from 34f4c5f to 3d02fe6 Compare February 3, 2025 23:00
@thdxr

thdxr commented Feb 3, 2025

Copy link
Copy Markdown

THANK YOU

@ijjk ijjk force-pushed the ijjk/node-middleware branch from 3d02fe6 to b9d5b41 Compare February 4, 2025 01:12
@ijjk

ijjk commented Feb 4, 2025

Copy link
Copy Markdown
Member Author

Stats from current PR

Default Build
General Overall increase ⚠️
vercel/next.js canary vercel/next.js ijjk/node-middleware Change
buildDuration 21.9s 23s ⚠️ +1.1s
buildDurationCached 19.5s 16.4s N/A
nodeModulesSize 391 MB 391 MB ⚠️ +13.4 kB
nextStartRea..uration (ms) 497ms 494ms N/A
Client Bundles (main, webpack)
vercel/next.js canary vercel/next.js ijjk/node-middleware Change
5306-HASH.js gzip 54 kB 53.9 kB N/A
8276.HASH.js gzip 169 B 168 B N/A
8377-HASH.js gzip 5.46 kB 5.46 kB N/A
bccd1874-HASH.js gzip 52.9 kB 52.9 kB N/A
framework-HASH.js gzip 57.5 kB 57.5 kB N/A
main-app-HASH.js gzip 240 B 242 B N/A
main-HASH.js gzip 34.5 kB 34.4 kB N/A
webpack-HASH.js gzip 1.71 kB 1.71 kB N/A
Overall change 0 B 0 B
Legacy Client Bundles (polyfills)
vercel/next.js canary vercel/next.js ijjk/node-middleware Change
polyfills-HASH.js gzip 39.4 kB 39.4 kB
Overall change 39.4 kB 39.4 kB
Client Pages
vercel/next.js canary vercel/next.js ijjk/node-middleware Change
_app-HASH.js gzip 193 B 193 B
_error-HASH.js gzip 193 B 193 B
amp-HASH.js gzip 512 B 510 B N/A
css-HASH.js gzip 343 B 342 B N/A
dynamic-HASH.js gzip 1.84 kB 1.84 kB
edge-ssr-HASH.js gzip 265 B 265 B
head-HASH.js gzip 363 B 362 B N/A
hooks-HASH.js gzip 393 B 392 B N/A
image-HASH.js gzip 4.59 kB 4.58 kB N/A
index-HASH.js gzip 268 B 268 B
link-HASH.js gzip 2.35 kB 2.35 kB N/A
routerDirect..HASH.js gzip 328 B 328 B
script-HASH.js gzip 397 B 397 B
withRouter-HASH.js gzip 323 B 326 B N/A
1afbb74e6ecf..834.css gzip 106 B 106 B
Overall change 3.59 kB 3.59 kB
Client Build Manifests
vercel/next.js canary vercel/next.js ijjk/node-middleware Change
_buildManifest.js gzip 748 B 747 B N/A
Overall change 0 B 0 B
Rendered Page Sizes
vercel/next.js canary vercel/next.js ijjk/node-middleware Change
index.html gzip 524 B 524 B
link.html gzip 539 B 538 B N/A
withRouter.html gzip 520 B 520 B
Overall change 1.04 kB 1.04 kB
Edge SSR bundle Size
vercel/next.js canary vercel/next.js ijjk/node-middleware Change
edge-ssr.js gzip 129 kB 129 kB N/A
page.js gzip 210 kB 210 kB N/A
Overall change 0 B 0 B
Middleware size
vercel/next.js canary vercel/next.js ijjk/node-middleware Change
middleware-b..fest.js gzip 669 B 671 B N/A
middleware-r..fest.js gzip 155 B 156 B N/A
middleware.js gzip 31.3 kB 31.3 kB N/A
edge-runtime..pack.js gzip 844 B 844 B
Overall change 844 B 844 B
Next Runtimes
vercel/next.js canary vercel/next.js ijjk/node-middleware Change
app-page-exp...dev.js gzip 385 kB 385 kB N/A
app-page-exp..prod.js gzip 132 kB 132 kB N/A
app-page-tur..prod.js gzip 145 kB 145 kB N/A
app-page-tur..prod.js gzip 141 kB 141 kB N/A
app-page.run...dev.js gzip 372 kB 372 kB N/A
app-page.run..prod.js gzip 128 kB 128 kB N/A
app-route-ex...dev.js gzip 39.3 kB 39.2 kB N/A
app-route-ex..prod.js gzip 25.6 kB 25.6 kB N/A
app-route-tu..prod.js gzip 25.6 kB 25.6 kB N/A
app-route-tu..prod.js gzip 25.4 kB 25.4 kB N/A
app-route.ru...dev.js gzip 40.8 kB 40.8 kB N/A
app-route.ru..prod.js gzip 25.4 kB 25.4 kB N/A
dist_client_...dev.js gzip 356 B 356 B
dist_client_...dev.js gzip 349 B 349 B
pages-api-tu..prod.js gzip 9.69 kB 9.69 kB
pages-api.ru...dev.js gzip 11.8 kB 11.8 kB
pages-api.ru..prod.js gzip 9.68 kB 9.68 kB
pages-turbo...prod.js gzip 21.9 kB 21.9 kB
pages.runtim...dev.js gzip 31.5 kB 31.5 kB
pages.runtim..prod.js gzip 21.9 kB 21.9 kB
server.runti..prod.js gzip 60.2 kB 60.1 kB N/A
Overall change 107 kB 107 kB
build cache
vercel/next.js canary vercel/next.js ijjk/node-middleware Change
0.pack gzip 2.1 MB 2.1 MB N/A
index.pack gzip 75.3 kB 74.6 kB N/A
Overall change 0 B 0 B
Diff details
Diff for page.js

Diff too large to display

Diff for middleware-b..-manifest.js
@@ -1,105 +1,105 @@
-self.__BUILD_MANIFEST = {
+globalThis.__BUILD_MANIFEST = {
   polyfillFiles: ["static/chunks/polyfills-42372ed130431b0a.js"],
   devFiles: [],
   ampDevFiles: [],
   lowPriorityFiles: [],
   rootMainFiles: [
-    "static/chunks/webpack-49409235d8d4b4b8.js",
-    "static/chunks/bccd1874-71d4fb08dac4a997.js",
-    "static/chunks/5306-5ab535b57bfff0bf.js",
-    "static/chunks/main-app-33eebf03250624aa.js",
+    "static/chunks/webpack-5c07bf7eb84f5597.js",
+    "static/chunks/2e869656-2d97e9d9d53e469e.js",
+    "static/chunks/9920-3904aa2263ad418f.js",
+    "static/chunks/main-app-669e76e43da097d8.js",
   ],
   rootMainFilesTree: {},
   pages: {
     "/": [
-      "static/chunks/webpack-49409235d8d4b4b8.js",
-      "static/chunks/framework-2decaf6d95a02701.js",
-      "static/chunks/main-21d12f8b242e9a98.js",
-      "static/chunks/pages/index-8ddb641e7abbd098.js",
+      "static/chunks/webpack-5c07bf7eb84f5597.js",
+      "static/chunks/framework-9577f7782ec2a388.js",
+      "static/chunks/main-be574188accf9df0.js",
+      "static/chunks/pages/index-cdd429fb8365e9a8.js",
     ],
     "/_app": [
-      "static/chunks/webpack-49409235d8d4b4b8.js",
-      "static/chunks/framework-2decaf6d95a02701.js",
-      "static/chunks/main-21d12f8b242e9a98.js",
-      "static/chunks/pages/_app-fa69b449c419b0c6.js",
+      "static/chunks/webpack-5c07bf7eb84f5597.js",
+      "static/chunks/framework-9577f7782ec2a388.js",
+      "static/chunks/main-be574188accf9df0.js",
+      "static/chunks/pages/_app-7fd9860d39660416.js",
     ],
     "/_error": [
-      "static/chunks/webpack-49409235d8d4b4b8.js",
-      "static/chunks/framework-2decaf6d95a02701.js",
-      "static/chunks/main-21d12f8b242e9a98.js",
-      "static/chunks/pages/_error-84c334cbeba419ae.js",
+      "static/chunks/webpack-5c07bf7eb84f5597.js",
+      "static/chunks/framework-9577f7782ec2a388.js",
+      "static/chunks/main-be574188accf9df0.js",
+      "static/chunks/pages/_error-f7ce2cc7967af745.js",
     ],
     "/amp": [
-      "static/chunks/webpack-49409235d8d4b4b8.js",
-      "static/chunks/framework-2decaf6d95a02701.js",
-      "static/chunks/main-21d12f8b242e9a98.js",
-      "static/chunks/pages/amp-74b464d4f9372170.js",
+      "static/chunks/webpack-5c07bf7eb84f5597.js",
+      "static/chunks/framework-9577f7782ec2a388.js",
+      "static/chunks/main-be574188accf9df0.js",
+      "static/chunks/pages/amp-ca37d23fefdda376.js",
     ],
     "/css": [
-      "static/chunks/webpack-49409235d8d4b4b8.js",
-      "static/chunks/framework-2decaf6d95a02701.js",
-      "static/chunks/main-21d12f8b242e9a98.js",
+      "static/chunks/webpack-5c07bf7eb84f5597.js",
+      "static/chunks/framework-9577f7782ec2a388.js",
+      "static/chunks/main-be574188accf9df0.js",
       "static/css/ded6b86ab9cc0a1f.css",
-      "static/chunks/pages/css-efc17a2f68d7df99.js",
+      "static/chunks/pages/css-ed558eaae0d7c496.js",
     ],
     "/dynamic": [
-      "static/chunks/webpack-49409235d8d4b4b8.js",
-      "static/chunks/framework-2decaf6d95a02701.js",
-      "static/chunks/main-21d12f8b242e9a98.js",
-      "static/chunks/pages/dynamic-b4f934be4d1f87e7.js",
+      "static/chunks/webpack-5c07bf7eb84f5597.js",
+      "static/chunks/framework-9577f7782ec2a388.js",
+      "static/chunks/main-be574188accf9df0.js",
+      "static/chunks/pages/dynamic-55e365045a16536a.js",
     ],
     "/edge-ssr": [
-      "static/chunks/webpack-49409235d8d4b4b8.js",
-      "static/chunks/framework-2decaf6d95a02701.js",
-      "static/chunks/main-21d12f8b242e9a98.js",
-      "static/chunks/pages/edge-ssr-9621763093ab7518.js",
+      "static/chunks/webpack-5c07bf7eb84f5597.js",
+      "static/chunks/framework-9577f7782ec2a388.js",
+      "static/chunks/main-be574188accf9df0.js",
+      "static/chunks/pages/edge-ssr-bb6ac73a343f2268.js",
     ],
     "/head": [
-      "static/chunks/webpack-49409235d8d4b4b8.js",
-      "static/chunks/framework-2decaf6d95a02701.js",
-      "static/chunks/main-21d12f8b242e9a98.js",
-      "static/chunks/pages/head-dce8a9589fb12781.js",
+      "static/chunks/webpack-5c07bf7eb84f5597.js",
+      "static/chunks/framework-9577f7782ec2a388.js",
+      "static/chunks/main-be574188accf9df0.js",
+      "static/chunks/pages/head-f3eefcc535f84847.js",
     ],
     "/hooks": [
-      "static/chunks/webpack-49409235d8d4b4b8.js",
-      "static/chunks/framework-2decaf6d95a02701.js",
-      "static/chunks/main-21d12f8b242e9a98.js",
-      "static/chunks/pages/hooks-be6f83048403d7ee.js",
+      "static/chunks/webpack-5c07bf7eb84f5597.js",
+      "static/chunks/framework-9577f7782ec2a388.js",
+      "static/chunks/main-be574188accf9df0.js",
+      "static/chunks/pages/hooks-dad2f674087fcadb.js",
     ],
     "/image": [
-      "static/chunks/webpack-49409235d8d4b4b8.js",
-      "static/chunks/framework-2decaf6d95a02701.js",
-      "static/chunks/main-21d12f8b242e9a98.js",
-      "static/chunks/pages/image-cd6a5a2d70afc0f6.js",
+      "static/chunks/webpack-5c07bf7eb84f5597.js",
+      "static/chunks/framework-9577f7782ec2a388.js",
+      "static/chunks/main-be574188accf9df0.js",
+      "static/chunks/pages/image-e6d28388ee648a49.js",
     ],
     "/link": [
-      "static/chunks/webpack-49409235d8d4b4b8.js",
-      "static/chunks/framework-2decaf6d95a02701.js",
-      "static/chunks/main-21d12f8b242e9a98.js",
-      "static/chunks/pages/link-b5977fd83b8cad60.js",
+      "static/chunks/webpack-5c07bf7eb84f5597.js",
+      "static/chunks/framework-9577f7782ec2a388.js",
+      "static/chunks/main-be574188accf9df0.js",
+      "static/chunks/pages/link-9c9530df3f94f6e1.js",
     ],
     "/routerDirect": [
-      "static/chunks/webpack-49409235d8d4b4b8.js",
-      "static/chunks/framework-2decaf6d95a02701.js",
-      "static/chunks/main-21d12f8b242e9a98.js",
-      "static/chunks/pages/routerDirect-6d4d4f091e53ea06.js",
+      "static/chunks/webpack-5c07bf7eb84f5597.js",
+      "static/chunks/framework-9577f7782ec2a388.js",
+      "static/chunks/main-be574188accf9df0.js",
+      "static/chunks/pages/routerDirect-573e64eb53dde685.js",
     ],
     "/script": [
-      "static/chunks/webpack-49409235d8d4b4b8.js",
-      "static/chunks/framework-2decaf6d95a02701.js",
-      "static/chunks/main-21d12f8b242e9a98.js",
-      "static/chunks/pages/script-549a633f0e7c51ff.js",
+      "static/chunks/webpack-5c07bf7eb84f5597.js",
+      "static/chunks/framework-9577f7782ec2a388.js",
+      "static/chunks/main-be574188accf9df0.js",
+      "static/chunks/pages/script-7d0e2904f84b1915.js",
     ],
     "/withRouter": [
-      "static/chunks/webpack-49409235d8d4b4b8.js",
-      "static/chunks/framework-2decaf6d95a02701.js",
-      "static/chunks/main-21d12f8b242e9a98.js",
-      "static/chunks/pages/withRouter-ea8f8ca662ba9232.js",
+      "static/chunks/webpack-5c07bf7eb84f5597.js",
+      "static/chunks/framework-9577f7782ec2a388.js",
+      "static/chunks/main-be574188accf9df0.js",
+      "static/chunks/pages/withRouter-eba2e3482d3f4173.js",
     ],
   },
   ampFirstPages: [],
 };
-self.__BUILD_MANIFEST.lowPriorityFiles = [
+globalThis.__BUILD_MANIFEST.lowPriorityFiles = [
   "/static/" + process.env.__NEXT_BUILD_ID + "/_buildManifest.js",
   ,
   "/static/" + process.env.__NEXT_BUILD_ID + "/_ssgManifest.js",
Diff for middleware.js

Diff too large to display

Diff for edge-ssr.js

Diff too large to display

Diff for 5306-HASH.js

Diff too large to display

Diff for bccd1874-HASH.js

Diff too large to display

Diff for main-HASH.js

Diff too large to display

Diff for app-page-exp..ntime.dev.js
failed to diff
Diff for app-page-exp..time.prod.js

Diff too large to display

Diff for app-page-tur..time.prod.js

Diff too large to display

Diff for app-page-tur..time.prod.js

Diff too large to display

Diff for app-page.runtime.dev.js
failed to diff
Diff for app-page.runtime.prod.js

Diff too large to display

Diff for app-route-ex..ntime.dev.js

Diff too large to display

Diff for app-route-ex..time.prod.js

Diff too large to display

Diff for app-route-tu..time.prod.js

Diff too large to display

Diff for app-route-tu..time.prod.js

Diff too large to display

Diff for app-route.runtime.dev.js

Diff too large to display

Diff for app-route.ru..time.prod.js

Diff too large to display

Diff for server.runtime.prod.js

Diff too large to display

Commit: 966d971

@ijjk ijjk marked this pull request as ready for review February 4, 2025 02:26
@ijjk ijjk requested review from feedthejim, huozhi and ztanner February 4, 2025 02:28
Comment thread packages/next/src/server/next-server.ts
Comment thread test/e2e/middleware-general/test/index.test.ts Outdated
@ijjk ijjk force-pushed the ijjk/node-middleware branch from b9d5b41 to 5754f18 Compare February 4, 2025 02:45
@ijjk ijjk force-pushed the ijjk/node-middleware branch from 0bcc348 to 966d971 Compare February 4, 2025 18:35
@ijjk ijjk enabled auto-merge (squash) February 4, 2025 18:44
@ijjk ijjk merged commit c84be73 into canary Feb 4, 2025
@ijjk ijjk deleted the ijjk/node-middleware branch February 4, 2025 18:51
@antonlvovych

Copy link
Copy Markdown

SO PERFECT TIMING! THANK YOU ❤️‍🔥

ijjk added a commit that referenced this pull request Feb 5, 2025
This is a follow-up to #75624
which ensures middleware behaves correctly in the `src/` directory. This
previously wasn't an issue since edge runtime output location isn't
picky since it's just output in the middleware-manifest although with
node runtime it is particular.
@chevsky

chevsky commented Feb 5, 2025

Copy link
Copy Markdown

It should've always been vice versa:

module.exports = {
  experimental: {
    edgeMiddleware: true,
  },
}

Anyway, thank you!

throw new MiddlewareNotFoundError()
}
let middlewareModule
middlewareModule = this.loadNodeMiddleware()

@jamiter jamiter Feb 7, 2025

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

For some reason this returns a promise in my setup. Causing the error adapterFn is not a function. Awaiting the this.loadNodeMiddleware() solves it for me.

I'm using node 22 with the webpack build (not turbo) in case that matters.

It might be because of the dynamic nature of the path being required in loadNodeMiddleware.

Apparently dynamic paths might result in a promise being returned by require... See discussion here: #45125

@bai

bai commented Feb 8, 2025

Copy link
Copy Markdown

Great stuff! @ijjk when do you think this will start working on Vercel (for those who run canary)?

@github-actions github-actions Bot locked as resolved and limited conversation to collaborators Feb 22, 2025
@ijjk

ijjk commented Feb 27, 2025

Copy link
Copy Markdown
Member Author

@bai this is now able to be leveraged if you are running canary do note this is still under development though!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants