Skip to content
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

fix the dynamic routing of middleware #32601

Merged
merged 19 commits into from Mar 28, 2022

Conversation

nkzawa
Copy link
Contributor

@nkzawa nkzawa commented Dec 17, 2021

fixes #31324

Also fixes middleware on dynamic routes like pages/[slug]/_middleware.js match with unintended paths like priority static path, api path.

Bug

  • Related issues linked using fixes #number
  • Integration tests added
  • Errors have helpful link attached, see contributing.md
  • Make sure the linting passes by running yarn lint

@ijjk

This comment has been minimized.

@ijjk

This comment has been minimized.

@ijjk

This comment has been minimized.

javivelasco
javivelasco previously approved these changes Dec 20, 2021
packages/next/server/base-server.ts Outdated Show resolved Hide resolved
packages/next/server/base-server.ts Outdated Show resolved Hide resolved
@ijjk

This comment has been minimized.

@ijjk

This comment has been minimized.

@ijjk

This comment has been minimized.

@nkzawa nkzawa force-pushed the fix-dynamic-middleware-routing.patch branch from cbdfc6e to 9ffbf4a Compare January 31, 2022 13:31
@ijjk

This comment has been minimized.

@nkzawa nkzawa requested a review from padmaia as a code owner February 1, 2022 10:37
@ijjk

This comment has been minimized.

@ijjk

This comment has been minimized.

@ijjk

This comment has been minimized.

@ijjk

This comment has been minimized.

@ijjk

This comment has been minimized.

@ijjk

This comment has been minimized.

@ijjk

This comment has been minimized.

@ijjk

This comment has been minimized.

@nkzawa nkzawa requested a review from ijjk February 3, 2022 13:27
@ijjk

This comment has been minimized.

isMiddleware?: boolean
}

export function* getRoutingItems(
Copy link
Member

Choose a reason for hiding this comment

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

Can we avoid using a generator here? This needs to be transpiled for older browser currently which adds half a KB gzipped to the bundle x-ref: #32601 (comment)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@ijjk changed to return Iterator instead.

Copy link
Member

Choose a reason for hiding this comment

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

Iterators require the same polyfilling as generators unfortunately 😅 can we just return an array here? Note: we can see the size increase here #32601 (comment) which is gzipped so it's quite a bit non-gzipped

Copy link
Contributor Author

@nkzawa nkzawa Feb 10, 2022

Choose a reason for hiding this comment

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

This computation will be relatively high cost but I'm not sure if we can cache the result (maybe not since pages and middleware can change with hot-reloading). I will change it to an array for now. (done)

@ijjk

This comment has been minimized.

@ijjk
Copy link
Member

ijjk commented Mar 22, 2022

Stats from current PR

Default Build (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
buildDuration 15.3s 15.3s -2ms
buildDurationCached 6.1s 6s -52ms
nodeModulesSize 456 MB 456 MB ⚠️ +9.79 kB
Page Load Tests Overall decrease ⚠️
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
/ failed reqs 0 0
/ total time (seconds) 2.974 2.987 ⚠️ +0.01
/ avg req/sec 840.49 836.94 ⚠️ -3.55
/error-in-render failed reqs 0 0
/error-in-render total time (seconds) 1.175 1.213 ⚠️ +0.04
/error-in-render avg req/sec 2126.81 2060.34 ⚠️ -66.47
Client Bundles (main, webpack) Overall increase ⚠️
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
925.HASH.js gzip 179 B 179 B
framework-HASH.js gzip 42 kB 42 kB
main-HASH.js gzip 28 kB 28.4 kB ⚠️ +488 B
webpack-HASH.js gzip 1.44 kB 1.44 kB
Overall change 71.6 kB 72.1 kB ⚠️ +488 B
Legacy Client Bundles (polyfills)
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
polyfills-HASH.js gzip 31 kB 31 kB
Overall change 31 kB 31 kB
Client Pages
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
_app-HASH.js gzip 1.36 kB 1.36 kB
_error-HASH.js gzip 192 B 192 B
amp-HASH.js gzip 309 B 309 B
css-HASH.js gzip 327 B 327 B
dynamic-HASH.js gzip 2.57 kB 2.57 kB
head-HASH.js gzip 351 B 351 B
hooks-HASH.js gzip 920 B 920 B
image-HASH.js gzip 5.48 kB 5.48 kB
index-HASH.js gzip 263 B 263 B
link-HASH.js gzip 2.26 kB 2.26 kB
routerDirect..HASH.js gzip 320 B 320 B
script-HASH.js gzip 387 B 387 B
withRouter-HASH.js gzip 319 B 319 B
85e02e95b279..7e3.css gzip 107 B 107 B
Overall change 15.2 kB 15.2 kB
Client Build Manifests
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
_buildManifest.js gzip 460 B 460 B
Overall change 460 B 460 B
Rendered Page Sizes Overall decrease ✓
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
index.html gzip 531 B 530 B -1 B
link.html gzip 545 B 545 B
withRouter.html gzip 526 B 524 B -2 B
Overall change 1.6 kB 1.6 kB -3 B

Diffs

Diff for main-HASH.js
@@ -473,7 +473,7 @@
       var _routeAnnouncer = __webpack_require__(8483);
       var _router1 = __webpack_require__(880);
       var _isError = __webpack_require__(676);
-      var _vitals = __webpack_require__(7185);
+      var _vitals = __webpack_require__(4564);
       var _refresh = __webpack_require__(2129);
       var _imageConfigContext = __webpack_require__(8730);
       function asyncGeneratorStep(
@@ -3197,7 +3197,7 @@
       /***/
     },
 
-    /***/ 7185: /***/ function(
+    /***/ 4564: /***/ function(
       __unused_webpack_module,
       exports,
       __webpack_require__
@@ -4351,8 +4351,8 @@
       var _resolveRewrites = _interopRequireDefault1(__webpack_require__(2431));
       var _routeMatcher = __webpack_require__(3156);
       var _routeRegex = __webpack_require__(4903);
-      var _getMiddlewareRegex = __webpack_require__(3072);
       var _formatUrl = __webpack_require__(7795);
+      var _routingItems = __webpack_require__(7185);
       function _interopRequireDefault1(obj) {
         return obj && obj.__esModule
           ? obj
@@ -6378,8 +6378,16 @@
                 _runtimeJs.default.mark(function _callee() {
                   var asPathname,
                     cleanedAs,
-                    fns,
+                    middlewareList,
+                    middleware,
+                    routingItems,
                     requiresPreflight,
+                    _iteratorNormalCompletion,
+                    _didIteratorError,
+                    _iteratorError,
+                    _iterator,
+                    _step,
+                    item,
                     preflight,
                     parsed,
                     fsPathname,
@@ -6404,58 +6412,116 @@
                             _ctx.next = 4;
                             return _this.pageLoader.getMiddlewareList();
                           case 4:
-                            fns = _ctx.sent;
-                            requiresPreflight = fns.some(function(param) {
+                            middlewareList = _ctx.sent;
+                            middleware = middlewareList.map(function(param) {
                               var _param = _slicedToArray(param, 2),
-                                middleware = _param[0],
-                                isSSR = _param[1];
-                              return (0, _routeMatcher).getRouteMatcher(
-                                (0, _getMiddlewareRegex).getMiddlewareRegex(
-                                  middleware,
-                                  !isSSR
-                                )
-                              )(cleanedAs);
+                                page = _param[0],
+                                ssr = _param[1];
+                              return {
+                                page: page,
+                                ssr: ssr
+                              };
                             });
+                            routingItems = (0, _routingItems).getRoutingItems(
+                              options.pages,
+                              middleware
+                            );
+                            requiresPreflight = false;
+                            (_iteratorNormalCompletion = true),
+                              (_didIteratorError = false),
+                              (_iteratorError = undefined);
+                            _ctx.prev = 9;
+                            _iterator = routingItems[Symbol.iterator]();
+                          case 11:
+                            if (
+                              (_iteratorNormalCompletion = (_step = _iterator.next())
+                                .done)
+                            ) {
+                              _ctx.next = 19;
+                              break;
+                            }
+                            item = _step.value;
+                            if (!item.match(cleanedAs)) {
+                              _ctx.next = 16;
+                              break;
+                            }
+                            if (item.isMiddleware) {
+                              requiresPreflight = true;
+                            }
+                            return _ctx.abrupt("break", 19);
+                          case 16:
+                            _iteratorNormalCompletion = true;
+                            _ctx.next = 11;
+                            break;
+                          case 19:
+                            _ctx.next = 25;
+                            break;
+                          case 21:
+                            _ctx.prev = 21;
+                            _ctx.t0 = _ctx["catch"](9);
+                            _didIteratorError = true;
+                            _iteratorError = _ctx.t0;
+                          case 25:
+                            _ctx.prev = 25;
+                            _ctx.prev = 26;
+                            if (
+                              !_iteratorNormalCompletion &&
+                              _iterator.return != null
+                            ) {
+                              _iterator.return();
+                            }
+                          case 28:
+                            _ctx.prev = 28;
+                            if (!_didIteratorError) {
+                              _ctx.next = 31;
+                              break;
+                            }
+                            throw _iteratorError;
+                          case 31:
+                            return _ctx.finish(28);
+                          case 32:
+                            return _ctx.finish(25);
+                          case 33:
                             if (requiresPreflight) {
-                              _ctx.next = 8;
+                              _ctx.next = 35;
                               break;
                             }
                             return _ctx.abrupt("return", {
                               type: "next"
                             });
-                          case 8:
-                            _ctx.prev = 9;
-                            _ctx.next = 12;
+                          case 35:
+                            _ctx.prev = 36;
+                            _ctx.next = 39;
                             return _this._getPreflightData({
                               preflightHref: options.as,
                               shouldCache: options.cache,
                               isPreview: options.isPreview
                             });
-                          case 12:
+                          case 39:
                             preflight = _ctx.sent;
-                            _ctx.next = 18;
+                            _ctx.next = 45;
                             break;
-                          case 15:
-                            _ctx.prev = 15;
-                            _ctx.t0 = _ctx["catch"](9);
+                          case 42:
+                            _ctx.prev = 42;
+                            _ctx.t1 = _ctx["catch"](36);
                             return _ctx.abrupt("return", {
                               type: "redirect",
                               destination: options.as
                             });
-                          case 18:
+                          case 45:
                             if (!preflight.rewrite) {
-                              _ctx.next = 27;
+                              _ctx.next = 54;
                               break;
                             }
                             if (preflight.rewrite.startsWith("/")) {
-                              _ctx.next = 21;
+                              _ctx.next = 48;
                               break;
                             }
                             return _ctx.abrupt("return", {
                               type: "redirect",
                               destination: options.as
                             });
-                          case 21:
+                          case 48:
                             parsed = (0, _parseRelativeUrl).parseRelativeUrl(
                               (0, _normalizeLocalePath).normalizeLocalePath(
                                 hasBasePath(preflight.rewrite)
@@ -6490,13 +6556,13 @@
                               matchedPage: matchedPage,
                               resolvedHref: resolvedHref
                             });
-                          case 27:
+                          case 54:
                             if (!preflight.redirect) {
-                              _ctx.next = 33;
+                              _ctx.next = 60;
                               break;
                             }
                             if (!preflight.redirect.startsWith("/")) {
-                              _ctx.next = 32;
+                              _ctx.next = 59;
                               break;
                             }
                             cleanRedirect = (0,
@@ -6520,31 +6586,35 @@
                               newUrl: newUrl,
                               newAs: newAs
                             });
-                          case 32:
+                          case 59:
                             return _ctx.abrupt("return", {
                               type: "redirect",
                               destination: preflight.redirect
                             });
-                          case 33:
+                          case 60:
                             if (!(preflight.refresh && !preflight.ssr)) {
-                              _ctx.next = 35;
+                              _ctx.next = 62;
                               break;
                             }
                             return _ctx.abrupt("return", {
                               type: "refresh"
                             });
-                          case 35:
+                          case 62:
                             return _ctx.abrupt("return", {
                               type: "next"
                             });
-                          case 36:
+                          case 63:
                           case "end":
                             return _ctx.stop();
                         }
                     },
                     _callee,
                     null,
-                    [[9, 15]]
+                    [
+                      [9, 21, 25, 33],
+                      [26, , 28, 32],
+                      [36, 42]
+                    ]
                   );
                 })
               )();
@@ -6816,11 +6886,17 @@
       });
       exports.getMiddlewareRegex = getMiddlewareRegex;
       var _routeRegex = __webpack_require__(4903);
+      // Identify ^/[param]/ in route string
+      var FIRST_SEGMENT_DYNAMIC = /^\/\[[^/]+?\](?=\/|$)/;
+      var NOT_API_ROUTE = "(?!/api(?:/|$))";
       function getMiddlewareRegex(normalizedRoute) {
         var catchAll =
           arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : true;
         var result = (0, _routeRegex).getParametrizedRoute(normalizedRoute);
-        var catchAllRegex = catchAll ? "(?!_next).*" : "";
+        var notApiRegex = FIRST_SEGMENT_DYNAMIC.test(normalizedRoute)
+          ? NOT_API_ROUTE
+          : "";
+        var catchAllRegex = catchAll ? "(?!_next($|/)).*" : "";
         var catchAllGroupedRegex = catchAll ? "(?:(/.*)?)" : "";
         if ("routeKeys" in result) {
           if (result.parameterizedRoute === "/") {
@@ -6834,10 +6910,12 @@
           return {
             groups: result.groups,
             namedRegex: "^"
+              .concat(notApiRegex)
               .concat(result.namedParameterizedRoute)
               .concat(catchAllGroupedRegex, "$"),
             re: new RegExp(
               "^"
+                .concat(notApiRegex)
                 .concat(result.parameterizedRoute)
                 .concat(catchAllGroupedRegex, "$")
             ),
@@ -6854,6 +6932,7 @@
           groups: {},
           re: new RegExp(
             "^"
+              .concat(notApiRegex)
               .concat(result.parameterizedRoute)
               .concat(catchAllGroupedRegex, "$")
           )
@@ -6891,6 +6970,18 @@
           return _routeRegex.getRouteRegex;
         }
       });
+      Object.defineProperty(exports, "getRoutingItems", {
+        enumerable: true,
+        get: function get() {
+          return _routingItems.getRoutingItems;
+        }
+      });
+      Object.defineProperty(exports, "RoutingItem", {
+        enumerable: true,
+        get: function get() {
+          return _routingItems.RoutingItem;
+        }
+      });
       Object.defineProperty(exports, "getSortedRoutes", {
         enumerable: true,
         get: function get() {
@@ -6906,6 +6997,7 @@
       var _getMiddlewareRegex = __webpack_require__(3072);
       var _routeMatcher = __webpack_require__(3156);
       var _routeRegex = __webpack_require__(4903);
+      var _routingItems = __webpack_require__(7185);
       var _sortedRoutes = __webpack_require__(566);
       var _isDynamic = __webpack_require__(6238); //# sourceMappingURL=index.js.map
 
@@ -7237,6 +7329,101 @@
       /***/
     },
 
+    /***/ 7185: /***/ function(
+      __unused_webpack_module,
+      exports,
+      __webpack_require__
+    ) {
+      "use strict";
+
+      function _arrayLikeToArray(arr, len) {
+        if (len == null || len > arr.length) len = arr.length;
+        for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
+        return arr2;
+      }
+      function _arrayWithoutHoles(arr) {
+        if (Array.isArray(arr)) return _arrayLikeToArray(arr);
+      }
+      function _iterableToArray(iter) {
+        if (
+          (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null) ||
+          iter["@@iterator"] != null
+        )
+          return Array.from(iter);
+      }
+      function _nonIterableSpread() {
+        throw new TypeError(
+          "Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."
+        );
+      }
+      function _toConsumableArray(arr) {
+        return (
+          _arrayWithoutHoles(arr) ||
+          _iterableToArray(arr) ||
+          _unsupportedIterableToArray(arr) ||
+          _nonIterableSpread()
+        );
+      }
+      function _unsupportedIterableToArray(o, minLen) {
+        if (!o) return;
+        if (typeof o === "string") return _arrayLikeToArray(o, minLen);
+        var n = Object.prototype.toString.call(o).slice(8, -1);
+        if (n === "Object" && o.constructor) n = o.constructor.name;
+        if (n === "Map" || n === "Set") return Array.from(n);
+        if (
+          n === "Arguments" ||
+          /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)
+        )
+          return _arrayLikeToArray(o, minLen);
+      }
+      Object.defineProperty(exports, "__esModule", {
+        value: true
+      });
+      exports.getRoutingItems = getRoutingItems;
+      var _getMiddlewareRegex = __webpack_require__(3072);
+      var _routeMatcher = __webpack_require__(3156);
+      var _routeRegex = __webpack_require__(4903);
+      var _sortedRoutes = __webpack_require__(566);
+      var MIDDLEWARE_SUFFIX = "/_middleware";
+      function getRoutingItems(pages, middleware) {
+        // append the suffix so that `getSortedRoutes()` can handle middleware properly
+        var middlewarePages = middleware.map(function(m) {
+          return "".concat(m.page).concat(MIDDLEWARE_SUFFIX);
+        });
+        var middlewareMap = new Map(
+          middleware.map(function(m) {
+            return [m.page, m];
+          })
+        );
+        var sortedRoutes = (0, _sortedRoutes).getSortedRoutes(
+          _toConsumableArray(pages).concat(_toConsumableArray(middlewarePages))
+        );
+        return sortedRoutes.map(function(page) {
+          if (page.endsWith(MIDDLEWARE_SUFFIX)) {
+            var p = page.slice(0, -MIDDLEWARE_SUFFIX.length) || "/";
+            var ssr = middlewareMap.get(p).ssr;
+            return {
+              match: (0, _routeMatcher).getRouteMatcher(
+                (0, _getMiddlewareRegex).getMiddlewareRegex(p, !ssr)
+              ),
+              page: p,
+              ssr: ssr,
+              isMiddleware: true
+            };
+          } else {
+            return {
+              match: (0, _routeMatcher).getRouteMatcher(
+                (0, _routeRegex).getRouteRegex(page)
+              ),
+              page: page
+            };
+          }
+        });
+      } //# sourceMappingURL=routing-items.js.map
+
+      /***/
+    },
+
     /***/ 566: /***/ function(__unused_webpack_module, exports) {
       "use strict";
 
@@ -7311,6 +7498,7 @@
           this.slugName = null;
           this.restSlugName = null;
           this.optionalRestSlugName = null;
+          this.isMiddleware = false;
         }
         _createClass(UrlNode, [
           {
@@ -7345,6 +7533,9 @@
               if (this.optionalRestSlugName !== null) {
                 childrenPaths.splice(childrenPaths.indexOf("[[...]]"), 1);
               }
+              if (this.isMiddleware) {
+                childrenPaths.splice(childrenPaths.indexOf("_middleware"), 1);
+              }
               var routes = childrenPaths
                 .map(function(c) {
                   return _this.children
@@ -7381,10 +7572,21 @@
                 }
                 routes.unshift(r);
               }
-              if (this.restSlugName !== null) {
+              if (this.isMiddleware) {
                 var _routes1;
-                (_routes1 = routes).push.apply(
+                (_routes1 = routes).unshift.apply(
                   _routes1,
+                  _toConsumableArray(
+                    this.children
+                      .get("_middleware")
+                      ._smoosh("".concat(prefix, "_middleware/"))
+                  )
+                );
+              }
+              if (this.restSlugName !== null) {
+                var _routes2;
+                (_routes2 = routes).push.apply(
+                  _routes2,
                   _toConsumableArray(
                     this.children
                       .get("[...]")
@@ -7397,9 +7599,9 @@
                 );
               }
               if (this.optionalRestSlugName !== null) {
-                var _routes2;
-                (_routes2 = routes).push.apply(
-                  _routes2,
+                var _routes3;
+                (_routes3 = routes).push.apply(
+                  _routes3,
                   _toConsumableArray(
                     this.children
                       .get("[[...]]")
@@ -7540,6 +7742,11 @@
                   // nextSegment is overwritten to [] so that it can later be sorted specifically
                   nextSegment = "[]";
                 }
+              } else if (
+                nextSegment === "_middleware" &&
+                urlPaths.length === 1
+              ) {
+                this.isMiddleware = true;
               }
               // If this UrlNode doesn't have the nextSegment yet we create a new child UrlNode
               if (!this.children.has(nextSegment)) {
Diff for index.html
@@ -19,7 +19,7 @@
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/main-87f82fb02d84a1d2.js"
+      src="/_next/static/chunks/main-6dde5605bbf08ee3.js"
       defer=""
     ></script>
     <script
Diff for link.html
@@ -19,7 +19,7 @@
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/main-87f82fb02d84a1d2.js"
+      src="/_next/static/chunks/main-6dde5605bbf08ee3.js"
       defer=""
     ></script>
     <script
Diff for withRouter.html
@@ -19,7 +19,7 @@
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/main-87f82fb02d84a1d2.js"
+      src="/_next/static/chunks/main-6dde5605bbf08ee3.js"
       defer=""
     ></script>
     <script

Default Build with SWC (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
buildDuration 18.7s 18.8s ⚠️ +87ms
buildDurationCached 6.1s 6s -16ms
nodeModulesSize 456 MB 456 MB ⚠️ +9.79 kB
Page Load Tests Overall increase ✓
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
/ failed reqs 0 0
/ total time (seconds) 2.92 2.894 -0.03
/ avg req/sec 856.1 863.96 +7.86
/error-in-render failed reqs 0 0
/error-in-render total time (seconds) 1.182 1.178 0
/error-in-render avg req/sec 2114.82 2122.67 +7.85
Client Bundles (main, webpack) Overall increase ⚠️
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
925.HASH.js gzip 178 B 178 B
framework-HASH.js gzip 42.3 kB 42.3 kB
main-HASH.js gzip 28.2 kB 28.8 kB ⚠️ +530 B
webpack-HASH.js gzip 1.45 kB 1.45 kB
Overall change 72.1 kB 72.7 kB ⚠️ +530 B
Legacy Client Bundles (polyfills)
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
polyfills-HASH.js gzip 31 kB 31 kB
Overall change 31 kB 31 kB
Client Pages
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
_app-HASH.js gzip 1.35 kB 1.35 kB
_error-HASH.js gzip 179 B 179 B
amp-HASH.js gzip 313 B 313 B
css-HASH.js gzip 324 B 324 B
dynamic-HASH.js gzip 2.56 kB 2.56 kB
head-HASH.js gzip 351 B 351 B
hooks-HASH.js gzip 921 B 921 B
image-HASH.js gzip 5.59 kB 5.59 kB
index-HASH.js gzip 261 B 261 B
link-HASH.js gzip 2.33 kB 2.33 kB
routerDirect..HASH.js gzip 322 B 322 B
script-HASH.js gzip 388 B 388 B
withRouter-HASH.js gzip 317 B 317 B
85e02e95b279..7e3.css gzip 107 B 107 B
Overall change 15.3 kB 15.3 kB
Client Build Manifests
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
_buildManifest.js gzip 458 B 458 B
Overall change 458 B 458 B
Rendered Page Sizes Overall decrease ✓
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
index.html gzip 531 B 531 B
link.html gzip 546 B 545 B -1 B
withRouter.html gzip 527 B 526 B -1 B
Overall change 1.6 kB 1.6 kB -2 B

Diffs

Diff for main-HASH.js
@@ -473,7 +473,7 @@
       var _routeAnnouncer = __webpack_require__(8483);
       var _router1 = __webpack_require__(880);
       var _isError = __webpack_require__(676);
-      var _vitals = __webpack_require__(7185);
+      var _vitals = __webpack_require__(4564);
       var _refresh = __webpack_require__(2129);
       var _imageConfigContext = __webpack_require__(8730);
       function asyncGeneratorStep(
@@ -3197,7 +3197,7 @@
       /***/
     },
 
-    /***/ 7185: /***/ function(
+    /***/ 4564: /***/ function(
       __unused_webpack_module,
       exports,
       __webpack_require__
@@ -4351,8 +4351,8 @@
       var _resolveRewrites = _interopRequireDefault1(__webpack_require__(2431));
       var _routeMatcher = __webpack_require__(3156);
       var _routeRegex = __webpack_require__(4903);
-      var _getMiddlewareRegex = __webpack_require__(3072);
       var _formatUrl = __webpack_require__(7795);
+      var _routingItems = __webpack_require__(7185);
       function _interopRequireDefault1(obj) {
         return obj && obj.__esModule
           ? obj
@@ -6378,8 +6378,16 @@
                 _runtimeJs.default.mark(function _callee() {
                   var asPathname,
                     cleanedAs,
-                    fns,
+                    middlewareList,
+                    middleware,
+                    routingItems,
                     requiresPreflight,
+                    _iteratorNormalCompletion,
+                    _didIteratorError,
+                    _iteratorError,
+                    _iterator,
+                    _step,
+                    item,
                     preflight,
                     parsed,
                     fsPathname,
@@ -6404,58 +6412,116 @@
                             _ctx.next = 4;
                             return _this.pageLoader.getMiddlewareList();
                           case 4:
-                            fns = _ctx.sent;
-                            requiresPreflight = fns.some(function(param) {
+                            middlewareList = _ctx.sent;
+                            middleware = middlewareList.map(function(param) {
                               var _param = _slicedToArray(param, 2),
-                                middleware = _param[0],
-                                isSSR = _param[1];
-                              return (0, _routeMatcher).getRouteMatcher(
-                                (0, _getMiddlewareRegex).getMiddlewareRegex(
-                                  middleware,
-                                  !isSSR
-                                )
-                              )(cleanedAs);
+                                page = _param[0],
+                                ssr = _param[1];
+                              return {
+                                page: page,
+                                ssr: ssr
+                              };
                             });
+                            routingItems = (0, _routingItems).getRoutingItems(
+                              options.pages,
+                              middleware
+                            );
+                            requiresPreflight = false;
+                            (_iteratorNormalCompletion = true),
+                              (_didIteratorError = false),
+                              (_iteratorError = undefined);
+                            _ctx.prev = 9;
+                            _iterator = routingItems[Symbol.iterator]();
+                          case 11:
+                            if (
+                              (_iteratorNormalCompletion = (_step = _iterator.next())
+                                .done)
+                            ) {
+                              _ctx.next = 19;
+                              break;
+                            }
+                            item = _step.value;
+                            if (!item.match(cleanedAs)) {
+                              _ctx.next = 16;
+                              break;
+                            }
+                            if (item.isMiddleware) {
+                              requiresPreflight = true;
+                            }
+                            return _ctx.abrupt("break", 19);
+                          case 16:
+                            _iteratorNormalCompletion = true;
+                            _ctx.next = 11;
+                            break;
+                          case 19:
+                            _ctx.next = 25;
+                            break;
+                          case 21:
+                            _ctx.prev = 21;
+                            _ctx.t0 = _ctx["catch"](9);
+                            _didIteratorError = true;
+                            _iteratorError = _ctx.t0;
+                          case 25:
+                            _ctx.prev = 25;
+                            _ctx.prev = 26;
+                            if (
+                              !_iteratorNormalCompletion &&
+                              _iterator.return != null
+                            ) {
+                              _iterator.return();
+                            }
+                          case 28:
+                            _ctx.prev = 28;
+                            if (!_didIteratorError) {
+                              _ctx.next = 31;
+                              break;
+                            }
+                            throw _iteratorError;
+                          case 31:
+                            return _ctx.finish(28);
+                          case 32:
+                            return _ctx.finish(25);
+                          case 33:
                             if (requiresPreflight) {
-                              _ctx.next = 8;
+                              _ctx.next = 35;
                               break;
                             }
                             return _ctx.abrupt("return", {
                               type: "next"
                             });
-                          case 8:
-                            _ctx.prev = 9;
-                            _ctx.next = 12;
+                          case 35:
+                            _ctx.prev = 36;
+                            _ctx.next = 39;
                             return _this._getPreflightData({
                               preflightHref: options.as,
                               shouldCache: options.cache,
                               isPreview: options.isPreview
                             });
-                          case 12:
+                          case 39:
                             preflight = _ctx.sent;
-                            _ctx.next = 18;
+                            _ctx.next = 45;
                             break;
-                          case 15:
-                            _ctx.prev = 15;
-                            _ctx.t0 = _ctx["catch"](9);
+                          case 42:
+                            _ctx.prev = 42;
+                            _ctx.t1 = _ctx["catch"](36);
                             return _ctx.abrupt("return", {
                               type: "redirect",
                               destination: options.as
                             });
-                          case 18:
+                          case 45:
                             if (!preflight.rewrite) {
-                              _ctx.next = 27;
+                              _ctx.next = 54;
                               break;
                             }
                             if (preflight.rewrite.startsWith("/")) {
-                              _ctx.next = 21;
+                              _ctx.next = 48;
                               break;
                             }
                             return _ctx.abrupt("return", {
                               type: "redirect",
                               destination: options.as
                             });
-                          case 21:
+                          case 48:
                             parsed = (0, _parseRelativeUrl).parseRelativeUrl(
                               (0, _normalizeLocalePath).normalizeLocalePath(
                                 hasBasePath(preflight.rewrite)
@@ -6490,13 +6556,13 @@
                               matchedPage: matchedPage,
                               resolvedHref: resolvedHref
                             });
-                          case 27:
+                          case 54:
                             if (!preflight.redirect) {
-                              _ctx.next = 33;
+                              _ctx.next = 60;
                               break;
                             }
                             if (!preflight.redirect.startsWith("/")) {
-                              _ctx.next = 32;
+                              _ctx.next = 59;
                               break;
                             }
                             cleanRedirect = (0,
@@ -6520,31 +6586,35 @@
                               newUrl: newUrl,
                               newAs: newAs
                             });
-                          case 32:
+                          case 59:
                             return _ctx.abrupt("return", {
                               type: "redirect",
                               destination: preflight.redirect
                             });
-                          case 33:
+                          case 60:
                             if (!(preflight.refresh && !preflight.ssr)) {
-                              _ctx.next = 35;
+                              _ctx.next = 62;
                               break;
                             }
                             return _ctx.abrupt("return", {
                               type: "refresh"
                             });
-                          case 35:
+                          case 62:
                             return _ctx.abrupt("return", {
                               type: "next"
                             });
-                          case 36:
+                          case 63:
                           case "end":
                             return _ctx.stop();
                         }
                     },
                     _callee,
                     null,
-                    [[9, 15]]
+                    [
+                      [9, 21, 25, 33],
+                      [26, , 28, 32],
+                      [36, 42]
+                    ]
                   );
                 })
               )();
@@ -6816,11 +6886,17 @@
       });
       exports.getMiddlewareRegex = getMiddlewareRegex;
       var _routeRegex = __webpack_require__(4903);
+      // Identify ^/[param]/ in route string
+      var FIRST_SEGMENT_DYNAMIC = /^\/\[[^/]+?\](?=\/|$)/;
+      var NOT_API_ROUTE = "(?!/api(?:/|$))";
       function getMiddlewareRegex(normalizedRoute) {
         var catchAll =
           arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : true;
         var result = (0, _routeRegex).getParametrizedRoute(normalizedRoute);
-        var catchAllRegex = catchAll ? "(?!_next).*" : "";
+        var notApiRegex = FIRST_SEGMENT_DYNAMIC.test(normalizedRoute)
+          ? NOT_API_ROUTE
+          : "";
+        var catchAllRegex = catchAll ? "(?!_next($|/)).*" : "";
         var catchAllGroupedRegex = catchAll ? "(?:(/.*)?)" : "";
         if ("routeKeys" in result) {
           if (result.parameterizedRoute === "/") {
@@ -6834,10 +6910,12 @@
           return {
             groups: result.groups,
             namedRegex: "^"
+              .concat(notApiRegex)
               .concat(result.namedParameterizedRoute)
               .concat(catchAllGroupedRegex, "$"),
             re: new RegExp(
               "^"
+                .concat(notApiRegex)
                 .concat(result.parameterizedRoute)
                 .concat(catchAllGroupedRegex, "$")
             ),
@@ -6854,6 +6932,7 @@
           groups: {},
           re: new RegExp(
             "^"
+              .concat(notApiRegex)
               .concat(result.parameterizedRoute)
               .concat(catchAllGroupedRegex, "$")
           )
@@ -6891,6 +6970,18 @@
           return _routeRegex.getRouteRegex;
         }
       });
+      Object.defineProperty(exports, "getRoutingItems", {
+        enumerable: true,
+        get: function get() {
+          return _routingItems.getRoutingItems;
+        }
+      });
+      Object.defineProperty(exports, "RoutingItem", {
+        enumerable: true,
+        get: function get() {
+          return _routingItems.RoutingItem;
+        }
+      });
       Object.defineProperty(exports, "getSortedRoutes", {
         enumerable: true,
         get: function get() {
@@ -6906,6 +6997,7 @@
       var _getMiddlewareRegex = __webpack_require__(3072);
       var _routeMatcher = __webpack_require__(3156);
       var _routeRegex = __webpack_require__(4903);
+      var _routingItems = __webpack_require__(7185);
       var _sortedRoutes = __webpack_require__(566);
       var _isDynamic = __webpack_require__(6238); //# sourceMappingURL=index.js.map
 
@@ -7237,6 +7329,101 @@
       /***/
     },
 
+    /***/ 7185: /***/ function(
+      __unused_webpack_module,
+      exports,
+      __webpack_require__
+    ) {
+      "use strict";
+
+      function _arrayLikeToArray(arr, len) {
+        if (len == null || len > arr.length) len = arr.length;
+        for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
+        return arr2;
+      }
+      function _arrayWithoutHoles(arr) {
+        if (Array.isArray(arr)) return _arrayLikeToArray(arr);
+      }
+      function _iterableToArray(iter) {
+        if (
+          (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null) ||
+          iter["@@iterator"] != null
+        )
+          return Array.from(iter);
+      }
+      function _nonIterableSpread() {
+        throw new TypeError(
+          "Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."
+        );
+      }
+      function _toConsumableArray(arr) {
+        return (
+          _arrayWithoutHoles(arr) ||
+          _iterableToArray(arr) ||
+          _unsupportedIterableToArray(arr) ||
+          _nonIterableSpread()
+        );
+      }
+      function _unsupportedIterableToArray(o, minLen) {
+        if (!o) return;
+        if (typeof o === "string") return _arrayLikeToArray(o, minLen);
+        var n = Object.prototype.toString.call(o).slice(8, -1);
+        if (n === "Object" && o.constructor) n = o.constructor.name;
+        if (n === "Map" || n === "Set") return Array.from(n);
+        if (
+          n === "Arguments" ||
+          /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)
+        )
+          return _arrayLikeToArray(o, minLen);
+      }
+      Object.defineProperty(exports, "__esModule", {
+        value: true
+      });
+      exports.getRoutingItems = getRoutingItems;
+      var _getMiddlewareRegex = __webpack_require__(3072);
+      var _routeMatcher = __webpack_require__(3156);
+      var _routeRegex = __webpack_require__(4903);
+      var _sortedRoutes = __webpack_require__(566);
+      var MIDDLEWARE_SUFFIX = "/_middleware";
+      function getRoutingItems(pages, middleware) {
+        // append the suffix so that `getSortedRoutes()` can handle middleware properly
+        var middlewarePages = middleware.map(function(m) {
+          return "".concat(m.page).concat(MIDDLEWARE_SUFFIX);
+        });
+        var middlewareMap = new Map(
+          middleware.map(function(m) {
+            return [m.page, m];
+          })
+        );
+        var sortedRoutes = (0, _sortedRoutes).getSortedRoutes(
+          _toConsumableArray(pages).concat(_toConsumableArray(middlewarePages))
+        );
+        return sortedRoutes.map(function(page) {
+          if (page.endsWith(MIDDLEWARE_SUFFIX)) {
+            var p = page.slice(0, -MIDDLEWARE_SUFFIX.length) || "/";
+            var ssr = middlewareMap.get(p).ssr;
+            return {
+              match: (0, _routeMatcher).getRouteMatcher(
+                (0, _getMiddlewareRegex).getMiddlewareRegex(p, !ssr)
+              ),
+              page: p,
+              ssr: ssr,
+              isMiddleware: true
+            };
+          } else {
+            return {
+              match: (0, _routeMatcher).getRouteMatcher(
+                (0, _routeRegex).getRouteRegex(page)
+              ),
+              page: page
+            };
+          }
+        });
+      } //# sourceMappingURL=routing-items.js.map
+
+      /***/
+    },
+
     /***/ 566: /***/ function(__unused_webpack_module, exports) {
       "use strict";
 
@@ -7311,6 +7498,7 @@
           this.slugName = null;
           this.restSlugName = null;
           this.optionalRestSlugName = null;
+          this.isMiddleware = false;
         }
         _createClass(UrlNode, [
           {
@@ -7345,6 +7533,9 @@
               if (this.optionalRestSlugName !== null) {
                 childrenPaths.splice(childrenPaths.indexOf("[[...]]"), 1);
               }
+              if (this.isMiddleware) {
+                childrenPaths.splice(childrenPaths.indexOf("_middleware"), 1);
+              }
               var routes = childrenPaths
                 .map(function(c) {
                   return _this.children
@@ -7381,10 +7572,21 @@
                 }
                 routes.unshift(r);
               }
-              if (this.restSlugName !== null) {
+              if (this.isMiddleware) {
                 var _routes1;
-                (_routes1 = routes).push.apply(
+                (_routes1 = routes).unshift.apply(
                   _routes1,
+                  _toConsumableArray(
+                    this.children
+                      .get("_middleware")
+                      ._smoosh("".concat(prefix, "_middleware/"))
+                  )
+                );
+              }
+              if (this.restSlugName !== null) {
+                var _routes2;
+                (_routes2 = routes).push.apply(
+                  _routes2,
                   _toConsumableArray(
                     this.children
                       .get("[...]")
@@ -7397,9 +7599,9 @@
                 );
               }
               if (this.optionalRestSlugName !== null) {
-                var _routes2;
-                (_routes2 = routes).push.apply(
-                  _routes2,
+                var _routes3;
+                (_routes3 = routes).push.apply(
+                  _routes3,
                   _toConsumableArray(
                     this.children
                       .get("[[...]]")
@@ -7540,6 +7742,11 @@
                   // nextSegment is overwritten to [] so that it can later be sorted specifically
                   nextSegment = "[]";
                 }
+              } else if (
+                nextSegment === "_middleware" &&
+                urlPaths.length === 1
+              ) {
+                this.isMiddleware = true;
               }
               // If this UrlNode doesn't have the nextSegment yet we create a new child UrlNode
               if (!this.children.has(nextSegment)) {
Diff for index.html
@@ -19,7 +19,7 @@
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/main-87f82fb02d84a1d2.js"
+      src="/_next/static/chunks/main-6dde5605bbf08ee3.js"
       defer=""
     ></script>
     <script
Diff for link.html
@@ -19,7 +19,7 @@
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/main-87f82fb02d84a1d2.js"
+      src="/_next/static/chunks/main-6dde5605bbf08ee3.js"
       defer=""
     ></script>
     <script
Diff for withRouter.html
@@ -19,7 +19,7 @@
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/main-87f82fb02d84a1d2.js"
+      src="/_next/static/chunks/main-6dde5605bbf08ee3.js"
       defer=""
     ></script>
     <script
Commit: 1988669

@ijjk
Copy link
Member

ijjk commented Mar 22, 2022

Stats from current PR

Default Build (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
buildDuration 18.5s 19.3s ⚠️ +777ms
buildDurationCached 7.8s 7.5s -222ms
nodeModulesSize 456 MB 456 MB ⚠️ +9.67 kB
Page Load Tests Overall increase ✓
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
/ failed reqs 0 0
/ total time (seconds) 3.783 3.877 ⚠️ +0.09
/ avg req/sec 660.86 644.91 ⚠️ -15.95
/error-in-render failed reqs 0 0
/error-in-render total time (seconds) 1.704 1.651 -0.05
/error-in-render avg req/sec 1467.47 1514.66 +47.19
Client Bundles (main, webpack) Overall increase ⚠️
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
925.HASH.js gzip 179 B 179 B
framework-HASH.js gzip 42 kB 42 kB
main-HASH.js gzip 28 kB 28.4 kB ⚠️ +488 B
webpack-HASH.js gzip 1.44 kB 1.44 kB
Overall change 71.6 kB 72.1 kB ⚠️ +488 B
Legacy Client Bundles (polyfills)
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
polyfills-HASH.js gzip 31 kB 31 kB
Overall change 31 kB 31 kB
Client Pages
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
_app-HASH.js gzip 1.36 kB 1.36 kB
_error-HASH.js gzip 192 B 192 B
amp-HASH.js gzip 309 B 309 B
css-HASH.js gzip 327 B 327 B
dynamic-HASH.js gzip 2.57 kB 2.57 kB
head-HASH.js gzip 351 B 351 B
hooks-HASH.js gzip 920 B 920 B
image-HASH.js gzip 5.48 kB 5.48 kB
index-HASH.js gzip 263 B 263 B
link-HASH.js gzip 2.26 kB 2.26 kB
routerDirect..HASH.js gzip 320 B 320 B
script-HASH.js gzip 387 B 387 B
withRouter-HASH.js gzip 319 B 319 B
85e02e95b279..7e3.css gzip 107 B 107 B
Overall change 15.2 kB 15.2 kB
Client Build Manifests
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
_buildManifest.js gzip 460 B 460 B
Overall change 460 B 460 B
Rendered Page Sizes Overall decrease ✓
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
index.html gzip 531 B 530 B -1 B
link.html gzip 545 B 545 B
withRouter.html gzip 526 B 524 B -2 B
Overall change 1.6 kB 1.6 kB -3 B

Diffs

Diff for main-HASH.js
@@ -473,7 +473,7 @@
       var _routeAnnouncer = __webpack_require__(8483);
       var _router1 = __webpack_require__(880);
       var _isError = __webpack_require__(676);
-      var _vitals = __webpack_require__(7185);
+      var _vitals = __webpack_require__(4564);
       var _refresh = __webpack_require__(2129);
       var _imageConfigContext = __webpack_require__(8730);
       function asyncGeneratorStep(
@@ -3197,7 +3197,7 @@
       /***/
     },
 
-    /***/ 7185: /***/ function(
+    /***/ 4564: /***/ function(
       __unused_webpack_module,
       exports,
       __webpack_require__
@@ -4351,8 +4351,8 @@
       var _resolveRewrites = _interopRequireDefault1(__webpack_require__(2431));
       var _routeMatcher = __webpack_require__(3156);
       var _routeRegex = __webpack_require__(4903);
-      var _getMiddlewareRegex = __webpack_require__(3072);
       var _formatUrl = __webpack_require__(7795);
+      var _routingItems = __webpack_require__(7185);
       function _interopRequireDefault1(obj) {
         return obj && obj.__esModule
           ? obj
@@ -6378,8 +6378,16 @@
                 _runtimeJs.default.mark(function _callee() {
                   var asPathname,
                     cleanedAs,
-                    fns,
+                    middlewareList,
+                    middleware,
+                    routingItems,
                     requiresPreflight,
+                    _iteratorNormalCompletion,
+                    _didIteratorError,
+                    _iteratorError,
+                    _iterator,
+                    _step,
+                    item,
                     preflight,
                     parsed,
                     fsPathname,
@@ -6404,58 +6412,116 @@
                             _ctx.next = 4;
                             return _this.pageLoader.getMiddlewareList();
                           case 4:
-                            fns = _ctx.sent;
-                            requiresPreflight = fns.some(function(param) {
+                            middlewareList = _ctx.sent;
+                            middleware = middlewareList.map(function(param) {
                               var _param = _slicedToArray(param, 2),
-                                middleware = _param[0],
-                                isSSR = _param[1];
-                              return (0, _routeMatcher).getRouteMatcher(
-                                (0, _getMiddlewareRegex).getMiddlewareRegex(
-                                  middleware,
-                                  !isSSR
-                                )
-                              )(cleanedAs);
+                                page = _param[0],
+                                ssr = _param[1];
+                              return {
+                                page: page,
+                                ssr: ssr
+                              };
                             });
+                            routingItems = (0, _routingItems).getRoutingItems(
+                              options.pages,
+                              middleware
+                            );
+                            requiresPreflight = false;
+                            (_iteratorNormalCompletion = true),
+                              (_didIteratorError = false),
+                              (_iteratorError = undefined);
+                            _ctx.prev = 9;
+                            _iterator = routingItems[Symbol.iterator]();
+                          case 11:
+                            if (
+                              (_iteratorNormalCompletion = (_step = _iterator.next())
+                                .done)
+                            ) {
+                              _ctx.next = 19;
+                              break;
+                            }
+                            item = _step.value;
+                            if (!item.match(cleanedAs)) {
+                              _ctx.next = 16;
+                              break;
+                            }
+                            if (item.isMiddleware) {
+                              requiresPreflight = true;
+                            }
+                            return _ctx.abrupt("break", 19);
+                          case 16:
+                            _iteratorNormalCompletion = true;
+                            _ctx.next = 11;
+                            break;
+                          case 19:
+                            _ctx.next = 25;
+                            break;
+                          case 21:
+                            _ctx.prev = 21;
+                            _ctx.t0 = _ctx["catch"](9);
+                            _didIteratorError = true;
+                            _iteratorError = _ctx.t0;
+                          case 25:
+                            _ctx.prev = 25;
+                            _ctx.prev = 26;
+                            if (
+                              !_iteratorNormalCompletion &&
+                              _iterator.return != null
+                            ) {
+                              _iterator.return();
+                            }
+                          case 28:
+                            _ctx.prev = 28;
+                            if (!_didIteratorError) {
+                              _ctx.next = 31;
+                              break;
+                            }
+                            throw _iteratorError;
+                          case 31:
+                            return _ctx.finish(28);
+                          case 32:
+                            return _ctx.finish(25);
+                          case 33:
                             if (requiresPreflight) {
-                              _ctx.next = 8;
+                              _ctx.next = 35;
                               break;
                             }
                             return _ctx.abrupt("return", {
                               type: "next"
                             });
-                          case 8:
-                            _ctx.prev = 9;
-                            _ctx.next = 12;
+                          case 35:
+                            _ctx.prev = 36;
+                            _ctx.next = 39;
                             return _this._getPreflightData({
                               preflightHref: options.as,
                               shouldCache: options.cache,
                               isPreview: options.isPreview
                             });
-                          case 12:
+                          case 39:
                             preflight = _ctx.sent;
-                            _ctx.next = 18;
+                            _ctx.next = 45;
                             break;
-                          case 15:
-                            _ctx.prev = 15;
-                            _ctx.t0 = _ctx["catch"](9);
+                          case 42:
+                            _ctx.prev = 42;
+                            _ctx.t1 = _ctx["catch"](36);
                             return _ctx.abrupt("return", {
                               type: "redirect",
                               destination: options.as
                             });
-                          case 18:
+                          case 45:
                             if (!preflight.rewrite) {
-                              _ctx.next = 27;
+                              _ctx.next = 54;
                               break;
                             }
                             if (preflight.rewrite.startsWith("/")) {
-                              _ctx.next = 21;
+                              _ctx.next = 48;
                               break;
                             }
                             return _ctx.abrupt("return", {
                               type: "redirect",
                               destination: options.as
                             });
-                          case 21:
+                          case 48:
                             parsed = (0, _parseRelativeUrl).parseRelativeUrl(
                               (0, _normalizeLocalePath).normalizeLocalePath(
                                 hasBasePath(preflight.rewrite)
@@ -6490,13 +6556,13 @@
                               matchedPage: matchedPage,
                               resolvedHref: resolvedHref
                             });
-                          case 27:
+                          case 54:
                             if (!preflight.redirect) {
-                              _ctx.next = 33;
+                              _ctx.next = 60;
                               break;
                             }
                             if (!preflight.redirect.startsWith("/")) {
-                              _ctx.next = 32;
+                              _ctx.next = 59;
                               break;
                             }
                             cleanRedirect = (0,
@@ -6520,31 +6586,35 @@
                               newUrl: newUrl,
                               newAs: newAs
                             });
-                          case 32:
+                          case 59:
                             return _ctx.abrupt("return", {
                               type: "redirect",
                               destination: preflight.redirect
                             });
-                          case 33:
+                          case 60:
                             if (!(preflight.refresh && !preflight.ssr)) {
-                              _ctx.next = 35;
+                              _ctx.next = 62;
                               break;
                             }
                             return _ctx.abrupt("return", {
                               type: "refresh"
                             });
-                          case 35:
+                          case 62:
                             return _ctx.abrupt("return", {
                               type: "next"
                             });
-                          case 36:
+                          case 63:
                           case "end":
                             return _ctx.stop();
                         }
                     },
                     _callee,
                     null,
-                    [[9, 15]]
+                    [
+                      [9, 21, 25, 33],
+                      [26, , 28, 32],
+                      [36, 42]
+                    ]
                   );
                 })
               )();
@@ -6816,11 +6886,17 @@
       });
       exports.getMiddlewareRegex = getMiddlewareRegex;
       var _routeRegex = __webpack_require__(4903);
+      // Identify ^/[param]/ in route string
+      var FIRST_SEGMENT_DYNAMIC = /^\/\[[^/]+?\](?=\/|$)/;
+      var NOT_API_ROUTE = "(?!/api(?:/|$))";
       function getMiddlewareRegex(normalizedRoute) {
         var catchAll =
           arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : true;
         var result = (0, _routeRegex).getParametrizedRoute(normalizedRoute);
-        var catchAllRegex = catchAll ? "(?!_next).*" : "";
+        var notApiRegex = FIRST_SEGMENT_DYNAMIC.test(normalizedRoute)
+          ? NOT_API_ROUTE
+          : "";
+        var catchAllRegex = catchAll ? "(?!_next($|/)).*" : "";
         var catchAllGroupedRegex = catchAll ? "(?:(/.*)?)" : "";
         if ("routeKeys" in result) {
           if (result.parameterizedRoute === "/") {
@@ -6834,10 +6910,12 @@
           return {
             groups: result.groups,
             namedRegex: "^"
+              .concat(notApiRegex)
               .concat(result.namedParameterizedRoute)
               .concat(catchAllGroupedRegex, "$"),
             re: new RegExp(
               "^"
+                .concat(notApiRegex)
                 .concat(result.parameterizedRoute)
                 .concat(catchAllGroupedRegex, "$")
             ),
@@ -6854,6 +6932,7 @@
           groups: {},
           re: new RegExp(
             "^"
+              .concat(notApiRegex)
               .concat(result.parameterizedRoute)
               .concat(catchAllGroupedRegex, "$")
           )
@@ -6891,6 +6970,18 @@
           return _routeRegex.getRouteRegex;
         }
       });
+      Object.defineProperty(exports, "getRoutingItems", {
+        enumerable: true,
+        get: function get() {
+          return _routingItems.getRoutingItems;
+        }
+      });
+      Object.defineProperty(exports, "RoutingItem", {
+        enumerable: true,
+        get: function get() {
+          return _routingItems.RoutingItem;
+        }
+      });
       Object.defineProperty(exports, "getSortedRoutes", {
         enumerable: true,
         get: function get() {
@@ -6906,6 +6997,7 @@
       var _getMiddlewareRegex = __webpack_require__(3072);
       var _routeMatcher = __webpack_require__(3156);
       var _routeRegex = __webpack_require__(4903);
+      var _routingItems = __webpack_require__(7185);
       var _sortedRoutes = __webpack_require__(566);
       var _isDynamic = __webpack_require__(6238); //# sourceMappingURL=index.js.map
 
@@ -7237,6 +7329,101 @@
       /***/
     },
 
+    /***/ 7185: /***/ function(
+      __unused_webpack_module,
+      exports,
+      __webpack_require__
+    ) {
+      "use strict";
+
+      function _arrayLikeToArray(arr, len) {
+        if (len == null || len > arr.length) len = arr.length;
+        for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
+        return arr2;
+      }
+      function _arrayWithoutHoles(arr) {
+        if (Array.isArray(arr)) return _arrayLikeToArray(arr);
+      }
+      function _iterableToArray(iter) {
+        if (
+          (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null) ||
+          iter["@@iterator"] != null
+        )
+          return Array.from(iter);
+      }
+      function _nonIterableSpread() {
+        throw new TypeError(
+          "Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."
+        );
+      }
+      function _toConsumableArray(arr) {
+        return (
+          _arrayWithoutHoles(arr) ||
+          _iterableToArray(arr) ||
+          _unsupportedIterableToArray(arr) ||
+          _nonIterableSpread()
+        );
+      }
+      function _unsupportedIterableToArray(o, minLen) {
+        if (!o) return;
+        if (typeof o === "string") return _arrayLikeToArray(o, minLen);
+        var n = Object.prototype.toString.call(o).slice(8, -1);
+        if (n === "Object" && o.constructor) n = o.constructor.name;
+        if (n === "Map" || n === "Set") return Array.from(n);
+        if (
+          n === "Arguments" ||
+          /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)
+        )
+          return _arrayLikeToArray(o, minLen);
+      }
+      Object.defineProperty(exports, "__esModule", {
+        value: true
+      });
+      exports.getRoutingItems = getRoutingItems;
+      var _getMiddlewareRegex = __webpack_require__(3072);
+      var _routeMatcher = __webpack_require__(3156);
+      var _routeRegex = __webpack_require__(4903);
+      var _sortedRoutes = __webpack_require__(566);
+      var MIDDLEWARE_SUFFIX = "/_middleware";
+      function getRoutingItems(pages, middleware) {
+        // append the suffix so that `getSortedRoutes()` can handle middleware properly
+        var middlewarePages = middleware.map(function(m) {
+          return "".concat(m.page).concat(MIDDLEWARE_SUFFIX);
+        });
+        var middlewareMap = new Map(
+          middleware.map(function(m) {
+            return [m.page, m];
+          })
+        );
+        var sortedRoutes = (0, _sortedRoutes).getSortedRoutes(
+          _toConsumableArray(pages).concat(_toConsumableArray(middlewarePages))
+        );
+        return sortedRoutes.map(function(page) {
+          if (page.endsWith(MIDDLEWARE_SUFFIX)) {
+            var p = page.slice(0, -MIDDLEWARE_SUFFIX.length) || "/";
+            var ssr = middlewareMap.get(p).ssr;
+            return {
+              match: (0, _routeMatcher).getRouteMatcher(
+                (0, _getMiddlewareRegex).getMiddlewareRegex(p, !ssr)
+              ),
+              page: p,
+              ssr: ssr,
+              isMiddleware: true
+            };
+          } else {
+            return {
+              match: (0, _routeMatcher).getRouteMatcher(
+                (0, _routeRegex).getRouteRegex(page)
+              ),
+              page: page
+            };
+          }
+        });
+      } //# sourceMappingURL=routing-items.js.map
+
+      /***/
+    },
+
     /***/ 566: /***/ function(__unused_webpack_module, exports) {
       "use strict";
 
@@ -7311,6 +7498,7 @@
           this.slugName = null;
           this.restSlugName = null;
           this.optionalRestSlugName = null;
+          this.isMiddleware = false;
         }
         _createClass(UrlNode, [
           {
@@ -7345,6 +7533,9 @@
               if (this.optionalRestSlugName !== null) {
                 childrenPaths.splice(childrenPaths.indexOf("[[...]]"), 1);
               }
+              if (this.isMiddleware) {
+                childrenPaths.splice(childrenPaths.indexOf("_middleware"), 1);
+              }
               var routes = childrenPaths
                 .map(function(c) {
                   return _this.children
@@ -7381,10 +7572,21 @@
                 }
                 routes.unshift(r);
               }
-              if (this.restSlugName !== null) {
+              if (this.isMiddleware) {
                 var _routes1;
-                (_routes1 = routes).push.apply(
+                (_routes1 = routes).unshift.apply(
                   _routes1,
+                  _toConsumableArray(
+                    this.children
+                      .get("_middleware")
+                      ._smoosh("".concat(prefix, "_middleware/"))
+                  )
+                );
+              }
+              if (this.restSlugName !== null) {
+                var _routes2;
+                (_routes2 = routes).push.apply(
+                  _routes2,
                   _toConsumableArray(
                     this.children
                       .get("[...]")
@@ -7397,9 +7599,9 @@
                 );
               }
               if (this.optionalRestSlugName !== null) {
-                var _routes2;
-                (_routes2 = routes).push.apply(
-                  _routes2,
+                var _routes3;
+                (_routes3 = routes).push.apply(
+                  _routes3,
                   _toConsumableArray(
                     this.children
                       .get("[[...]]")
@@ -7540,6 +7742,11 @@
                   // nextSegment is overwritten to [] so that it can later be sorted specifically
                   nextSegment = "[]";
                 }
+              } else if (
+                nextSegment === "_middleware" &&
+                urlPaths.length === 1
+              ) {
+                this.isMiddleware = true;
               }
               // If this UrlNode doesn't have the nextSegment yet we create a new child UrlNode
               if (!this.children.has(nextSegment)) {
Diff for index.html
@@ -19,7 +19,7 @@
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/main-87f82fb02d84a1d2.js"
+      src="/_next/static/chunks/main-6dde5605bbf08ee3.js"
       defer=""
     ></script>
     <script
Diff for link.html
@@ -19,7 +19,7 @@
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/main-87f82fb02d84a1d2.js"
+      src="/_next/static/chunks/main-6dde5605bbf08ee3.js"
       defer=""
     ></script>
     <script
Diff for withRouter.html
@@ -19,7 +19,7 @@
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/main-87f82fb02d84a1d2.js"
+      src="/_next/static/chunks/main-6dde5605bbf08ee3.js"
       defer=""
     ></script>
     <script

Default Build with SWC (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
buildDuration 22.7s 22.7s -55ms
buildDurationCached 7.6s 7.4s -195ms
nodeModulesSize 456 MB 456 MB ⚠️ +9.67 kB
Page Load Tests Overall decrease ⚠️
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
/ failed reqs 0 0
/ total time (seconds) 3.767 3.909 ⚠️ +0.14
/ avg req/sec 663.63 639.59 ⚠️ -24.04
/error-in-render failed reqs 0 0
/error-in-render total time (seconds) 1.66 1.668 ⚠️ +0.01
/error-in-render avg req/sec 1506.24 1498.94 ⚠️ -7.3
Client Bundles (main, webpack) Overall increase ⚠️
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
925.HASH.js gzip 178 B 178 B
framework-HASH.js gzip 42.3 kB 42.3 kB
main-HASH.js gzip 28.2 kB 28.8 kB ⚠️ +530 B
webpack-HASH.js gzip 1.45 kB 1.45 kB
Overall change 72.1 kB 72.7 kB ⚠️ +530 B
Legacy Client Bundles (polyfills)
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
polyfills-HASH.js gzip 31 kB 31 kB
Overall change 31 kB 31 kB
Client Pages
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
_app-HASH.js gzip 1.35 kB 1.35 kB
_error-HASH.js gzip 179 B 179 B
amp-HASH.js gzip 313 B 313 B
css-HASH.js gzip 324 B 324 B
dynamic-HASH.js gzip 2.56 kB 2.56 kB
head-HASH.js gzip 351 B 351 B
hooks-HASH.js gzip 921 B 921 B
image-HASH.js gzip 5.59 kB 5.59 kB
index-HASH.js gzip 261 B 261 B
link-HASH.js gzip 2.33 kB 2.33 kB
routerDirect..HASH.js gzip 322 B 322 B
script-HASH.js gzip 388 B 388 B
withRouter-HASH.js gzip 317 B 317 B
85e02e95b279..7e3.css gzip 107 B 107 B
Overall change 15.3 kB 15.3 kB
Client Build Manifests
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
_buildManifest.js gzip 458 B 458 B
Overall change 458 B 458 B
Rendered Page Sizes Overall decrease ✓
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
index.html gzip 531 B 531 B
link.html gzip 546 B 545 B -1 B
withRouter.html gzip 527 B 526 B -1 B
Overall change 1.6 kB 1.6 kB -2 B

Diffs

Diff for main-HASH.js
@@ -473,7 +473,7 @@
       var _routeAnnouncer = __webpack_require__(8483);
       var _router1 = __webpack_require__(880);
       var _isError = __webpack_require__(676);
-      var _vitals = __webpack_require__(7185);
+      var _vitals = __webpack_require__(4564);
       var _refresh = __webpack_require__(2129);
       var _imageConfigContext = __webpack_require__(8730);
       function asyncGeneratorStep(
@@ -3197,7 +3197,7 @@
       /***/
     },
 
-    /***/ 7185: /***/ function(
+    /***/ 4564: /***/ function(
       __unused_webpack_module,
       exports,
       __webpack_require__
@@ -4351,8 +4351,8 @@
       var _resolveRewrites = _interopRequireDefault1(__webpack_require__(2431));
       var _routeMatcher = __webpack_require__(3156);
       var _routeRegex = __webpack_require__(4903);
-      var _getMiddlewareRegex = __webpack_require__(3072);
       var _formatUrl = __webpack_require__(7795);
+      var _routingItems = __webpack_require__(7185);
       function _interopRequireDefault1(obj) {
         return obj && obj.__esModule
           ? obj
@@ -6378,8 +6378,16 @@
                 _runtimeJs.default.mark(function _callee() {
                   var asPathname,
                     cleanedAs,
-                    fns,
+                    middlewareList,
+                    middleware,
+                    routingItems,
                     requiresPreflight,
+                    _iteratorNormalCompletion,
+                    _didIteratorError,
+                    _iteratorError,
+                    _iterator,
+                    _step,
+                    item,
                     preflight,
                     parsed,
                     fsPathname,
@@ -6404,58 +6412,116 @@
                             _ctx.next = 4;
                             return _this.pageLoader.getMiddlewareList();
                           case 4:
-                            fns = _ctx.sent;
-                            requiresPreflight = fns.some(function(param) {
+                            middlewareList = _ctx.sent;
+                            middleware = middlewareList.map(function(param) {
                               var _param = _slicedToArray(param, 2),
-                                middleware = _param[0],
-                                isSSR = _param[1];
-                              return (0, _routeMatcher).getRouteMatcher(
-                                (0, _getMiddlewareRegex).getMiddlewareRegex(
-                                  middleware,
-                                  !isSSR
-                                )
-                              )(cleanedAs);
+                                page = _param[0],
+                                ssr = _param[1];
+                              return {
+                                page: page,
+                                ssr: ssr
+                              };
                             });
+                            routingItems = (0, _routingItems).getRoutingItems(
+                              options.pages,
+                              middleware
+                            );
+                            requiresPreflight = false;
+                            (_iteratorNormalCompletion = true),
+                              (_didIteratorError = false),
+                              (_iteratorError = undefined);
+                            _ctx.prev = 9;
+                            _iterator = routingItems[Symbol.iterator]();
+                          case 11:
+                            if (
+                              (_iteratorNormalCompletion = (_step = _iterator.next())
+                                .done)
+                            ) {
+                              _ctx.next = 19;
+                              break;
+                            }
+                            item = _step.value;
+                            if (!item.match(cleanedAs)) {
+                              _ctx.next = 16;
+                              break;
+                            }
+                            if (item.isMiddleware) {
+                              requiresPreflight = true;
+                            }
+                            return _ctx.abrupt("break", 19);
+                          case 16:
+                            _iteratorNormalCompletion = true;
+                            _ctx.next = 11;
+                            break;
+                          case 19:
+                            _ctx.next = 25;
+                            break;
+                          case 21:
+                            _ctx.prev = 21;
+                            _ctx.t0 = _ctx["catch"](9);
+                            _didIteratorError = true;
+                            _iteratorError = _ctx.t0;
+                          case 25:
+                            _ctx.prev = 25;
+                            _ctx.prev = 26;
+                            if (
+                              !_iteratorNormalCompletion &&
+                              _iterator.return != null
+                            ) {
+                              _iterator.return();
+                            }
+                          case 28:
+                            _ctx.prev = 28;
+                            if (!_didIteratorError) {
+                              _ctx.next = 31;
+                              break;
+                            }
+                            throw _iteratorError;
+                          case 31:
+                            return _ctx.finish(28);
+                          case 32:
+                            return _ctx.finish(25);
+                          case 33:
                             if (requiresPreflight) {
-                              _ctx.next = 8;
+                              _ctx.next = 35;
                               break;
                             }
                             return _ctx.abrupt("return", {
                               type: "next"
                             });
-                          case 8:
-                            _ctx.prev = 9;
-                            _ctx.next = 12;
+                          case 35:
+                            _ctx.prev = 36;
+                            _ctx.next = 39;
                             return _this._getPreflightData({
                               preflightHref: options.as,
                               shouldCache: options.cache,
                               isPreview: options.isPreview
                             });
-                          case 12:
+                          case 39:
                             preflight = _ctx.sent;
-                            _ctx.next = 18;
+                            _ctx.next = 45;
                             break;
-                          case 15:
-                            _ctx.prev = 15;
-                            _ctx.t0 = _ctx["catch"](9);
+                          case 42:
+                            _ctx.prev = 42;
+                            _ctx.t1 = _ctx["catch"](36);
                             return _ctx.abrupt("return", {
                               type: "redirect",
                               destination: options.as
                             });
-                          case 18:
+                          case 45:
                             if (!preflight.rewrite) {
-                              _ctx.next = 27;
+                              _ctx.next = 54;
                               break;
                             }
                             if (preflight.rewrite.startsWith("/")) {
-                              _ctx.next = 21;
+                              _ctx.next = 48;
                               break;
                             }
                             return _ctx.abrupt("return", {
                               type: "redirect",
                               destination: options.as
                             });
-                          case 21:
+                          case 48:
                             parsed = (0, _parseRelativeUrl).parseRelativeUrl(
                               (0, _normalizeLocalePath).normalizeLocalePath(
                                 hasBasePath(preflight.rewrite)
@@ -6490,13 +6556,13 @@
                               matchedPage: matchedPage,
                               resolvedHref: resolvedHref
                             });
-                          case 27:
+                          case 54:
                             if (!preflight.redirect) {
-                              _ctx.next = 33;
+                              _ctx.next = 60;
                               break;
                             }
                             if (!preflight.redirect.startsWith("/")) {
-                              _ctx.next = 32;
+                              _ctx.next = 59;
                               break;
                             }
                             cleanRedirect = (0,
@@ -6520,31 +6586,35 @@
                               newUrl: newUrl,
                               newAs: newAs
                             });
-                          case 32:
+                          case 59:
                             return _ctx.abrupt("return", {
                               type: "redirect",
                               destination: preflight.redirect
                             });
-                          case 33:
+                          case 60:
                             if (!(preflight.refresh && !preflight.ssr)) {
-                              _ctx.next = 35;
+                              _ctx.next = 62;
                               break;
                             }
                             return _ctx.abrupt("return", {
                               type: "refresh"
                             });
-                          case 35:
+                          case 62:
                             return _ctx.abrupt("return", {
                               type: "next"
                             });
-                          case 36:
+                          case 63:
                           case "end":
                             return _ctx.stop();
                         }
                     },
                     _callee,
                     null,
-                    [[9, 15]]
+                    [
+                      [9, 21, 25, 33],
+                      [26, , 28, 32],
+                      [36, 42]
+                    ]
                   );
                 })
               )();
@@ -6816,11 +6886,17 @@
       });
       exports.getMiddlewareRegex = getMiddlewareRegex;
       var _routeRegex = __webpack_require__(4903);
+      // Identify ^/[param]/ in route string
+      var FIRST_SEGMENT_DYNAMIC = /^\/\[[^/]+?\](?=\/|$)/;
+      var NOT_API_ROUTE = "(?!/api(?:/|$))";
       function getMiddlewareRegex(normalizedRoute) {
         var catchAll =
           arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : true;
         var result = (0, _routeRegex).getParametrizedRoute(normalizedRoute);
-        var catchAllRegex = catchAll ? "(?!_next).*" : "";
+        var notApiRegex = FIRST_SEGMENT_DYNAMIC.test(normalizedRoute)
+          ? NOT_API_ROUTE
+          : "";
+        var catchAllRegex = catchAll ? "(?!_next($|/)).*" : "";
         var catchAllGroupedRegex = catchAll ? "(?:(/.*)?)" : "";
         if ("routeKeys" in result) {
           if (result.parameterizedRoute === "/") {
@@ -6834,10 +6910,12 @@
           return {
             groups: result.groups,
             namedRegex: "^"
+              .concat(notApiRegex)
               .concat(result.namedParameterizedRoute)
               .concat(catchAllGroupedRegex, "$"),
             re: new RegExp(
               "^"
+                .concat(notApiRegex)
                 .concat(result.parameterizedRoute)
                 .concat(catchAllGroupedRegex, "$")
             ),
@@ -6854,6 +6932,7 @@
           groups: {},
           re: new RegExp(
             "^"
+              .concat(notApiRegex)
               .concat(result.parameterizedRoute)
               .concat(catchAllGroupedRegex, "$")
           )
@@ -6891,6 +6970,18 @@
           return _routeRegex.getRouteRegex;
         }
       });
+      Object.defineProperty(exports, "getRoutingItems", {
+        enumerable: true,
+        get: function get() {
+          return _routingItems.getRoutingItems;
+        }
+      });
+      Object.defineProperty(exports, "RoutingItem", {
+        enumerable: true,
+        get: function get() {
+          return _routingItems.RoutingItem;
+        }
+      });
       Object.defineProperty(exports, "getSortedRoutes", {
         enumerable: true,
         get: function get() {
@@ -6906,6 +6997,7 @@
       var _getMiddlewareRegex = __webpack_require__(3072);
       var _routeMatcher = __webpack_require__(3156);
       var _routeRegex = __webpack_require__(4903);
+      var _routingItems = __webpack_require__(7185);
       var _sortedRoutes = __webpack_require__(566);
       var _isDynamic = __webpack_require__(6238); //# sourceMappingURL=index.js.map
 
@@ -7237,6 +7329,101 @@
       /***/
     },
 
+    /***/ 7185: /***/ function(
+      __unused_webpack_module,
+      exports,
+      __webpack_require__
+    ) {
+      "use strict";
+
+      function _arrayLikeToArray(arr, len) {
+        if (len == null || len > arr.length) len = arr.length;
+        for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
+        return arr2;
+      }
+      function _arrayWithoutHoles(arr) {
+        if (Array.isArray(arr)) return _arrayLikeToArray(arr);
+      }
+      function _iterableToArray(iter) {
+        if (
+          (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null) ||
+          iter["@@iterator"] != null
+        )
+          return Array.from(iter);
+      }
+      function _nonIterableSpread() {
+        throw new TypeError(
+          "Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."
+        );
+      }
+      function _toConsumableArray(arr) {
+        return (
+          _arrayWithoutHoles(arr) ||
+          _iterableToArray(arr) ||
+          _unsupportedIterableToArray(arr) ||
+          _nonIterableSpread()
+        );
+      }
+      function _unsupportedIterableToArray(o, minLen) {
+        if (!o) return;
+        if (typeof o === "string") return _arrayLikeToArray(o, minLen);
+        var n = Object.prototype.toString.call(o).slice(8, -1);
+        if (n === "Object" && o.constructor) n = o.constructor.name;
+        if (n === "Map" || n === "Set") return Array.from(n);
+        if (
+          n === "Arguments" ||
+          /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)
+        )
+          return _arrayLikeToArray(o, minLen);
+      }
+      Object.defineProperty(exports, "__esModule", {
+        value: true
+      });
+      exports.getRoutingItems = getRoutingItems;
+      var _getMiddlewareRegex = __webpack_require__(3072);
+      var _routeMatcher = __webpack_require__(3156);
+      var _routeRegex = __webpack_require__(4903);
+      var _sortedRoutes = __webpack_require__(566);
+      var MIDDLEWARE_SUFFIX = "/_middleware";
+      function getRoutingItems(pages, middleware) {
+        // append the suffix so that `getSortedRoutes()` can handle middleware properly
+        var middlewarePages = middleware.map(function(m) {
+          return "".concat(m.page).concat(MIDDLEWARE_SUFFIX);
+        });
+        var middlewareMap = new Map(
+          middleware.map(function(m) {
+            return [m.page, m];
+          })
+        );
+        var sortedRoutes = (0, _sortedRoutes).getSortedRoutes(
+          _toConsumableArray(pages).concat(_toConsumableArray(middlewarePages))
+        );
+        return sortedRoutes.map(function(page) {
+          if (page.endsWith(MIDDLEWARE_SUFFIX)) {
+            var p = page.slice(0, -MIDDLEWARE_SUFFIX.length) || "/";
+            var ssr = middlewareMap.get(p).ssr;
+            return {
+              match: (0, _routeMatcher).getRouteMatcher(
+                (0, _getMiddlewareRegex).getMiddlewareRegex(p, !ssr)
+              ),
+              page: p,
+              ssr: ssr,
+              isMiddleware: true
+            };
+          } else {
+            return {
+              match: (0, _routeMatcher).getRouteMatcher(
+                (0, _routeRegex).getRouteRegex(page)
+              ),
+              page: page
+            };
+          }
+        });
+      } //# sourceMappingURL=routing-items.js.map
+
+      /***/
+    },
+
     /***/ 566: /***/ function(__unused_webpack_module, exports) {
       "use strict";
 
@@ -7311,6 +7498,7 @@
           this.slugName = null;
           this.restSlugName = null;
           this.optionalRestSlugName = null;
+          this.isMiddleware = false;
         }
         _createClass(UrlNode, [
           {
@@ -7345,6 +7533,9 @@
               if (this.optionalRestSlugName !== null) {
                 childrenPaths.splice(childrenPaths.indexOf("[[...]]"), 1);
               }
+              if (this.isMiddleware) {
+                childrenPaths.splice(childrenPaths.indexOf("_middleware"), 1);
+              }
               var routes = childrenPaths
                 .map(function(c) {
                   return _this.children
@@ -7381,10 +7572,21 @@
                 }
                 routes.unshift(r);
               }
-              if (this.restSlugName !== null) {
+              if (this.isMiddleware) {
                 var _routes1;
-                (_routes1 = routes).push.apply(
+                (_routes1 = routes).unshift.apply(
                   _routes1,
+                  _toConsumableArray(
+                    this.children
+                      .get("_middleware")
+                      ._smoosh("".concat(prefix, "_middleware/"))
+                  )
+                );
+              }
+              if (this.restSlugName !== null) {
+                var _routes2;
+                (_routes2 = routes).push.apply(
+                  _routes2,
                   _toConsumableArray(
                     this.children
                       .get("[...]")
@@ -7397,9 +7599,9 @@
                 );
               }
               if (this.optionalRestSlugName !== null) {
-                var _routes2;
-                (_routes2 = routes).push.apply(
-                  _routes2,
+                var _routes3;
+                (_routes3 = routes).push.apply(
+                  _routes3,
                   _toConsumableArray(
                     this.children
                       .get("[[...]]")
@@ -7540,6 +7742,11 @@
                   // nextSegment is overwritten to [] so that it can later be sorted specifically
                   nextSegment = "[]";
                 }
+              } else if (
+                nextSegment === "_middleware" &&
+                urlPaths.length === 1
+              ) {
+                this.isMiddleware = true;
               }
               // If this UrlNode doesn't have the nextSegment yet we create a new child UrlNode
               if (!this.children.has(nextSegment)) {
Diff for index.html
@@ -19,7 +19,7 @@
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/main-87f82fb02d84a1d2.js"
+      src="/_next/static/chunks/main-6dde5605bbf08ee3.js"
       defer=""
     ></script>
     <script
Diff for link.html
@@ -19,7 +19,7 @@
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/main-87f82fb02d84a1d2.js"
+      src="/_next/static/chunks/main-6dde5605bbf08ee3.js"
       defer=""
     ></script>
     <script
Diff for withRouter.html
@@ -19,7 +19,7 @@
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/main-87f82fb02d84a1d2.js"
+      src="/_next/static/chunks/main-6dde5605bbf08ee3.js"
       defer=""
     ></script>
     <script
Commit: 758a371

@nkzawa nkzawa requested a review from javivelasco March 23, 2022 06:33
@ijjk
Copy link
Member

ijjk commented Mar 23, 2022

Stats from current PR

Default Build (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
buildDuration 22.4s 22.2s -268ms
buildDurationCached 8.3s 8.3s -40ms
nodeModulesSize 467 MB 467 MB ⚠️ +9.67 kB
Page Load Tests Overall decrease ⚠️
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
/ failed reqs 0 0
/ total time (seconds) 4.942 4.98 ⚠️ +0.04
/ avg req/sec 505.83 501.97 ⚠️ -3.86
/error-in-render failed reqs 0 0
/error-in-render total time (seconds) 2.237 2.275 ⚠️ +0.04
/error-in-render avg req/sec 1117.68 1099.14 ⚠️ -18.54
Client Bundles (main, webpack) Overall increase ⚠️
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
925.HASH.js gzip 179 B 179 B
framework-HASH.js gzip 42 kB 42 kB
main-HASH.js gzip 28 kB 28.4 kB ⚠️ +488 B
webpack-HASH.js gzip 1.44 kB 1.44 kB
Overall change 71.6 kB 72.1 kB ⚠️ +488 B
Legacy Client Bundles (polyfills)
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
polyfills-HASH.js gzip 31 kB 31 kB
Overall change 31 kB 31 kB
Client Pages
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
_app-HASH.js gzip 1.36 kB 1.36 kB
_error-HASH.js gzip 192 B 192 B
amp-HASH.js gzip 309 B 309 B
css-HASH.js gzip 327 B 327 B
dynamic-HASH.js gzip 2.57 kB 2.57 kB
head-HASH.js gzip 351 B 351 B
hooks-HASH.js gzip 920 B 920 B
image-HASH.js gzip 5.48 kB 5.48 kB
index-HASH.js gzip 263 B 263 B
link-HASH.js gzip 2.26 kB 2.26 kB
routerDirect..HASH.js gzip 320 B 320 B
script-HASH.js gzip 387 B 387 B
withRouter-HASH.js gzip 319 B 319 B
85e02e95b279..7e3.css gzip 107 B 107 B
Overall change 15.2 kB 15.2 kB
Client Build Manifests
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
_buildManifest.js gzip 460 B 460 B
Overall change 460 B 460 B
Rendered Page Sizes Overall increase ⚠️
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
index.html gzip 531 B 531 B
link.html gzip 544 B 545 B ⚠️ +1 B
withRouter.html gzip 524 B 525 B ⚠️ +1 B
Overall change 1.6 kB 1.6 kB ⚠️ +2 B

Diffs

Diff for main-HASH.js
@@ -473,7 +473,7 @@
       var _routeAnnouncer = __webpack_require__(8483);
       var _router1 = __webpack_require__(880);
       var _isError = __webpack_require__(676);
-      var _vitals = __webpack_require__(7185);
+      var _vitals = __webpack_require__(4564);
       var _refresh = __webpack_require__(2129);
       var _imageConfigContext = __webpack_require__(8730);
       function asyncGeneratorStep(
@@ -3197,7 +3197,7 @@
       /***/
     },
 
-    /***/ 7185: /***/ function(
+    /***/ 4564: /***/ function(
       __unused_webpack_module,
       exports,
       __webpack_require__
@@ -4351,8 +4351,8 @@
       var _resolveRewrites = _interopRequireDefault1(__webpack_require__(2431));
       var _routeMatcher = __webpack_require__(3156);
       var _routeRegex = __webpack_require__(4903);
-      var _getMiddlewareRegex = __webpack_require__(3072);
       var _formatUrl = __webpack_require__(7795);
+      var _routingItems = __webpack_require__(7185);
       function _interopRequireDefault1(obj) {
         return obj && obj.__esModule
           ? obj
@@ -6378,8 +6378,16 @@
                 _runtimeJs.default.mark(function _callee() {
                   var asPathname,
                     cleanedAs,
-                    fns,
+                    middlewareList,
+                    middleware,
+                    routingItems,
                     requiresPreflight,
+                    _iteratorNormalCompletion,
+                    _didIteratorError,
+                    _iteratorError,
+                    _iterator,
+                    _step,
+                    item,
                     preflight,
                     parsed,
                     fsPathname,
@@ -6404,58 +6412,116 @@
                             _ctx.next = 4;
                             return _this.pageLoader.getMiddlewareList();
                           case 4:
-                            fns = _ctx.sent;
-                            requiresPreflight = fns.some(function(param) {
+                            middlewareList = _ctx.sent;
+                            middleware = middlewareList.map(function(param) {
                               var _param = _slicedToArray(param, 2),
-                                middleware = _param[0],
-                                isSSR = _param[1];
-                              return (0, _routeMatcher).getRouteMatcher(
-                                (0, _getMiddlewareRegex).getMiddlewareRegex(
-                                  middleware,
-                                  !isSSR
-                                )
-                              )(cleanedAs);
+                                page = _param[0],
+                                ssr = _param[1];
+                              return {
+                                page: page,
+                                ssr: ssr
+                              };
                             });
+                            routingItems = (0, _routingItems).getRoutingItems(
+                              options.pages,
+                              middleware
+                            );
+                            requiresPreflight = false;
+                            (_iteratorNormalCompletion = true),
+                              (_didIteratorError = false),
+                              (_iteratorError = undefined);
+                            _ctx.prev = 9;
+                            _iterator = routingItems[Symbol.iterator]();
+                          case 11:
+                            if (
+                              (_iteratorNormalCompletion = (_step = _iterator.next())
+                                .done)
+                            ) {
+                              _ctx.next = 19;
+                              break;
+                            }
+                            item = _step.value;
+                            if (!item.match(cleanedAs)) {
+                              _ctx.next = 16;
+                              break;
+                            }
+                            if (item.isMiddleware) {
+                              requiresPreflight = true;
+                            }
+                            return _ctx.abrupt("break", 19);
+                          case 16:
+                            _iteratorNormalCompletion = true;
+                            _ctx.next = 11;
+                            break;
+                          case 19:
+                            _ctx.next = 25;
+                            break;
+                          case 21:
+                            _ctx.prev = 21;
+                            _ctx.t0 = _ctx["catch"](9);
+                            _didIteratorError = true;
+                            _iteratorError = _ctx.t0;
+                          case 25:
+                            _ctx.prev = 25;
+                            _ctx.prev = 26;
+                            if (
+                              !_iteratorNormalCompletion &&
+                              _iterator.return != null
+                            ) {
+                              _iterator.return();
+                            }
+                          case 28:
+                            _ctx.prev = 28;
+                            if (!_didIteratorError) {
+                              _ctx.next = 31;
+                              break;
+                            }
+                            throw _iteratorError;
+                          case 31:
+                            return _ctx.finish(28);
+                          case 32:
+                            return _ctx.finish(25);
+                          case 33:
                             if (requiresPreflight) {
-                              _ctx.next = 8;
+                              _ctx.next = 35;
                               break;
                             }
                             return _ctx.abrupt("return", {
                               type: "next"
                             });
-                          case 8:
-                            _ctx.prev = 9;
-                            _ctx.next = 12;
+                          case 35:
+                            _ctx.prev = 36;
+                            _ctx.next = 39;
                             return _this._getPreflightData({
                               preflightHref: options.as,
                               shouldCache: options.cache,
                               isPreview: options.isPreview
                             });
-                          case 12:
+                          case 39:
                             preflight = _ctx.sent;
-                            _ctx.next = 18;
+                            _ctx.next = 45;
                             break;
-                          case 15:
-                            _ctx.prev = 15;
-                            _ctx.t0 = _ctx["catch"](9);
+                          case 42:
+                            _ctx.prev = 42;
+                            _ctx.t1 = _ctx["catch"](36);
                             return _ctx.abrupt("return", {
                               type: "redirect",
                               destination: options.as
                             });
-                          case 18:
+                          case 45:
                             if (!preflight.rewrite) {
-                              _ctx.next = 27;
+                              _ctx.next = 54;
                               break;
                             }
                             if (preflight.rewrite.startsWith("/")) {
-                              _ctx.next = 21;
+                              _ctx.next = 48;
                               break;
                             }
                             return _ctx.abrupt("return", {
                               type: "redirect",
                               destination: options.as
                             });
-                          case 21:
+                          case 48:
                             parsed = (0, _parseRelativeUrl).parseRelativeUrl(
                               (0, _normalizeLocalePath).normalizeLocalePath(
                                 hasBasePath(preflight.rewrite)
@@ -6490,13 +6556,13 @@
                               matchedPage: matchedPage,
                               resolvedHref: resolvedHref
                             });
-                          case 27:
+                          case 54:
                             if (!preflight.redirect) {
-                              _ctx.next = 33;
+                              _ctx.next = 60;
                               break;
                             }
                             if (!preflight.redirect.startsWith("/")) {
-                              _ctx.next = 32;
+                              _ctx.next = 59;
                               break;
                             }
                             cleanRedirect = (0,
@@ -6520,31 +6586,35 @@
                               newUrl: newUrl,
                               newAs: newAs
                             });
-                          case 32:
+                          case 59:
                             return _ctx.abrupt("return", {
                               type: "redirect",
                               destination: preflight.redirect
                             });
-                          case 33:
+                          case 60:
                             if (!(preflight.refresh && !preflight.ssr)) {
-                              _ctx.next = 35;
+                              _ctx.next = 62;
                               break;
                             }
                             return _ctx.abrupt("return", {
                               type: "refresh"
                             });
-                          case 35:
+                          case 62:
                             return _ctx.abrupt("return", {
                               type: "next"
                             });
-                          case 36:
+                          case 63:
                           case "end":
                             return _ctx.stop();
                         }
                     },
                     _callee,
                     null,
-                    [[9, 15]]
+                    [
+                      [9, 21, 25, 33],
+                      [26, , 28, 32],
+                      [36, 42]
+                    ]
                   );
                 })
               )();
@@ -6816,11 +6886,17 @@
       });
       exports.getMiddlewareRegex = getMiddlewareRegex;
       var _routeRegex = __webpack_require__(4903);
+      // Identify ^/[param]/ in route string
+      var FIRST_SEGMENT_DYNAMIC = /^\/\[[^/]+?\](?=\/|$)/;
+      var NOT_API_ROUTE = "(?!/api(?:/|$))";
       function getMiddlewareRegex(normalizedRoute) {
         var catchAll =
           arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : true;
         var result = (0, _routeRegex).getParametrizedRoute(normalizedRoute);
-        var catchAllRegex = catchAll ? "(?!_next).*" : "";
+        var notApiRegex = FIRST_SEGMENT_DYNAMIC.test(normalizedRoute)
+          ? NOT_API_ROUTE
+          : "";
+        var catchAllRegex = catchAll ? "(?!_next($|/)).*" : "";
         var catchAllGroupedRegex = catchAll ? "(?:(/.*)?)" : "";
         if ("routeKeys" in result) {
           if (result.parameterizedRoute === "/") {
@@ -6834,10 +6910,12 @@
           return {
             groups: result.groups,
             namedRegex: "^"
+              .concat(notApiRegex)
               .concat(result.namedParameterizedRoute)
               .concat(catchAllGroupedRegex, "$"),
             re: new RegExp(
               "^"
+                .concat(notApiRegex)
                 .concat(result.parameterizedRoute)
                 .concat(catchAllGroupedRegex, "$")
             ),
@@ -6854,6 +6932,7 @@
           groups: {},
           re: new RegExp(
             "^"
+              .concat(notApiRegex)
               .concat(result.parameterizedRoute)
               .concat(catchAllGroupedRegex, "$")
           )
@@ -6891,6 +6970,18 @@
           return _routeRegex.getRouteRegex;
         }
       });
+      Object.defineProperty(exports, "getRoutingItems", {
+        enumerable: true,
+        get: function get() {
+          return _routingItems.getRoutingItems;
+        }
+      });
+      Object.defineProperty(exports, "RoutingItem", {
+        enumerable: true,
+        get: function get() {
+          return _routingItems.RoutingItem;
+        }
+      });
       Object.defineProperty(exports, "getSortedRoutes", {
         enumerable: true,
         get: function get() {
@@ -6906,6 +6997,7 @@
       var _getMiddlewareRegex = __webpack_require__(3072);
       var _routeMatcher = __webpack_require__(3156);
       var _routeRegex = __webpack_require__(4903);
+      var _routingItems = __webpack_require__(7185);
       var _sortedRoutes = __webpack_require__(566);
       var _isDynamic = __webpack_require__(6238); //# sourceMappingURL=index.js.map
 
@@ -7237,6 +7329,101 @@
       /***/
     },
 
+    /***/ 7185: /***/ function(
+      __unused_webpack_module,
+      exports,
+      __webpack_require__
+    ) {
+      "use strict";
+
+      function _arrayLikeToArray(arr, len) {
+        if (len == null || len > arr.length) len = arr.length;
+        for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
+        return arr2;
+      }
+      function _arrayWithoutHoles(arr) {
+        if (Array.isArray(arr)) return _arrayLikeToArray(arr);
+      }
+      function _iterableToArray(iter) {
+        if (
+          (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null) ||
+          iter["@@iterator"] != null
+        )
+          return Array.from(iter);
+      }
+      function _nonIterableSpread() {
+        throw new TypeError(
+          "Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."
+        );
+      }
+      function _toConsumableArray(arr) {
+        return (
+          _arrayWithoutHoles(arr) ||
+          _iterableToArray(arr) ||
+          _unsupportedIterableToArray(arr) ||
+          _nonIterableSpread()
+        );
+      }
+      function _unsupportedIterableToArray(o, minLen) {
+        if (!o) return;
+        if (typeof o === "string") return _arrayLikeToArray(o, minLen);
+        var n = Object.prototype.toString.call(o).slice(8, -1);
+        if (n === "Object" && o.constructor) n = o.constructor.name;
+        if (n === "Map" || n === "Set") return Array.from(n);
+        if (
+          n === "Arguments" ||
+          /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)
+        )
+          return _arrayLikeToArray(o, minLen);
+      }
+      Object.defineProperty(exports, "__esModule", {
+        value: true
+      });
+      exports.getRoutingItems = getRoutingItems;
+      var _getMiddlewareRegex = __webpack_require__(3072);
+      var _routeMatcher = __webpack_require__(3156);
+      var _routeRegex = __webpack_require__(4903);
+      var _sortedRoutes = __webpack_require__(566);
+      var MIDDLEWARE_SUFFIX = "/_middleware";
+      function getRoutingItems(pages, middleware) {
+        // append the suffix so that `getSortedRoutes()` can handle middleware properly
+        var middlewarePages = middleware.map(function(m) {
+          return "".concat(m.page).concat(MIDDLEWARE_SUFFIX);
+        });
+        var middlewareMap = new Map(
+          middleware.map(function(m) {
+            return [m.page, m];
+          })
+        );
+        var sortedRoutes = (0, _sortedRoutes).getSortedRoutes(
+          _toConsumableArray(pages).concat(_toConsumableArray(middlewarePages))
+        );
+        return sortedRoutes.map(function(page) {
+          if (page.endsWith(MIDDLEWARE_SUFFIX)) {
+            var p = page.slice(0, -MIDDLEWARE_SUFFIX.length) || "/";
+            var ssr = middlewareMap.get(p).ssr;
+            return {
+              match: (0, _routeMatcher).getRouteMatcher(
+                (0, _getMiddlewareRegex).getMiddlewareRegex(p, !ssr)
+              ),
+              page: p,
+              ssr: ssr,
+              isMiddleware: true
+            };
+          } else {
+            return {
+              match: (0, _routeMatcher).getRouteMatcher(
+                (0, _routeRegex).getRouteRegex(page)
+              ),
+              page: page
+            };
+          }
+        });
+      } //# sourceMappingURL=routing-items.js.map
+
+      /***/
+    },
+
     /***/ 566: /***/ function(__unused_webpack_module, exports) {
       "use strict";
 
@@ -7311,6 +7498,7 @@
           this.slugName = null;
           this.restSlugName = null;
           this.optionalRestSlugName = null;
+          this.isMiddleware = false;
         }
         _createClass(UrlNode, [
           {
@@ -7345,6 +7533,9 @@
               if (this.optionalRestSlugName !== null) {
                 childrenPaths.splice(childrenPaths.indexOf("[[...]]"), 1);
               }
+              if (this.isMiddleware) {
+                childrenPaths.splice(childrenPaths.indexOf("_middleware"), 1);
+              }
               var routes = childrenPaths
                 .map(function(c) {
                   return _this.children
@@ -7381,10 +7572,21 @@
                 }
                 routes.unshift(r);
               }
-              if (this.restSlugName !== null) {
+              if (this.isMiddleware) {
                 var _routes1;
-                (_routes1 = routes).push.apply(
+                (_routes1 = routes).unshift.apply(
                   _routes1,
+                  _toConsumableArray(
+                    this.children
+                      .get("_middleware")
+                      ._smoosh("".concat(prefix, "_middleware/"))
+                  )
+                );
+              }
+              if (this.restSlugName !== null) {
+                var _routes2;
+                (_routes2 = routes).push.apply(
+                  _routes2,
                   _toConsumableArray(
                     this.children
                       .get("[...]")
@@ -7397,9 +7599,9 @@
                 );
               }
               if (this.optionalRestSlugName !== null) {
-                var _routes2;
-                (_routes2 = routes).push.apply(
-                  _routes2,
+                var _routes3;
+                (_routes3 = routes).push.apply(
+                  _routes3,
                   _toConsumableArray(
                     this.children
                       .get("[[...]]")
@@ -7540,6 +7742,11 @@
                   // nextSegment is overwritten to [] so that it can later be sorted specifically
                   nextSegment = "[]";
                 }
+              } else if (
+                nextSegment === "_middleware" &&
+                urlPaths.length === 1
+              ) {
+                this.isMiddleware = true;
               }
               // If this UrlNode doesn't have the nextSegment yet we create a new child UrlNode
               if (!this.children.has(nextSegment)) {
Diff for index.html
@@ -19,7 +19,7 @@
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/main-0bf777b4298ee871.js"
+      src="/_next/static/chunks/main-ffd97caa434c3b21.js"
       defer=""
     ></script>
     <script
Diff for link.html
@@ -19,7 +19,7 @@
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/main-0bf777b4298ee871.js"
+      src="/_next/static/chunks/main-ffd97caa434c3b21.js"
       defer=""
     ></script>
     <script
Diff for withRouter.html
@@ -19,7 +19,7 @@
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/main-0bf777b4298ee871.js"
+      src="/_next/static/chunks/main-ffd97caa434c3b21.js"
       defer=""
     ></script>
     <script

Default Build with SWC (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
buildDuration 27.5s 27.2s -287ms
buildDurationCached 8.4s 6.6s -1.7s
nodeModulesSize 467 MB 467 MB ⚠️ +9.67 kB
Page Load Tests Overall decrease ⚠️
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
/ failed reqs 0 0
/ total time (seconds) 4.996 4.992 0
/ avg req/sec 500.41 500.79 +0.38
/error-in-render failed reqs 0 0
/error-in-render total time (seconds) 2.313 2.324 ⚠️ +0.01
/error-in-render avg req/sec 1080.62 1075.75 ⚠️ -4.87
Client Bundles (main, webpack) Overall increase ⚠️
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
925.HASH.js gzip 178 B 178 B
framework-HASH.js gzip 42.3 kB 42.3 kB
main-HASH.js gzip 28.2 kB 28.8 kB ⚠️ +530 B
webpack-HASH.js gzip 1.45 kB 1.45 kB
Overall change 72.1 kB 72.7 kB ⚠️ +530 B
Legacy Client Bundles (polyfills)
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
polyfills-HASH.js gzip 31 kB 31 kB
Overall change 31 kB 31 kB
Client Pages
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
_app-HASH.js gzip 1.35 kB 1.35 kB
_error-HASH.js gzip 179 B 179 B
amp-HASH.js gzip 313 B 313 B
css-HASH.js gzip 324 B 324 B
dynamic-HASH.js gzip 2.56 kB 2.56 kB
head-HASH.js gzip 351 B 351 B
hooks-HASH.js gzip 921 B 921 B
image-HASH.js gzip 5.59 kB 5.59 kB
index-HASH.js gzip 261 B 261 B
link-HASH.js gzip 2.33 kB 2.33 kB
routerDirect..HASH.js gzip 322 B 322 B
script-HASH.js gzip 388 B 388 B
withRouter-HASH.js gzip 317 B 317 B
85e02e95b279..7e3.css gzip 107 B 107 B
Overall change 15.3 kB 15.3 kB
Client Build Manifests
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
_buildManifest.js gzip 458 B 458 B
Overall change 458 B 458 B
Rendered Page Sizes Overall increase ⚠️
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
index.html gzip 531 B 533 B ⚠️ +2 B
link.html gzip 546 B 547 B ⚠️ +1 B
withRouter.html gzip 527 B 527 B
Overall change 1.6 kB 1.61 kB ⚠️ +3 B

Diffs

Diff for main-HASH.js
@@ -473,7 +473,7 @@
       var _routeAnnouncer = __webpack_require__(8483);
       var _router1 = __webpack_require__(880);
       var _isError = __webpack_require__(676);
-      var _vitals = __webpack_require__(7185);
+      var _vitals = __webpack_require__(4564);
       var _refresh = __webpack_require__(2129);
       var _imageConfigContext = __webpack_require__(8730);
       function asyncGeneratorStep(
@@ -3197,7 +3197,7 @@
       /***/
     },
 
-    /***/ 7185: /***/ function(
+    /***/ 4564: /***/ function(
       __unused_webpack_module,
       exports,
       __webpack_require__
@@ -4351,8 +4351,8 @@
       var _resolveRewrites = _interopRequireDefault1(__webpack_require__(2431));
       var _routeMatcher = __webpack_require__(3156);
       var _routeRegex = __webpack_require__(4903);
-      var _getMiddlewareRegex = __webpack_require__(3072);
       var _formatUrl = __webpack_require__(7795);
+      var _routingItems = __webpack_require__(7185);
       function _interopRequireDefault1(obj) {
         return obj && obj.__esModule
           ? obj
@@ -6378,8 +6378,16 @@
                 _runtimeJs.default.mark(function _callee() {
                   var asPathname,
                     cleanedAs,
-                    fns,
+                    middlewareList,
+                    middleware,
+                    routingItems,
                     requiresPreflight,
+                    _iteratorNormalCompletion,
+                    _didIteratorError,
+                    _iteratorError,
+                    _iterator,
+                    _step,
+                    item,
                     preflight,
                     parsed,
                     fsPathname,
@@ -6404,58 +6412,116 @@
                             _ctx.next = 4;
                             return _this.pageLoader.getMiddlewareList();
                           case 4:
-                            fns = _ctx.sent;
-                            requiresPreflight = fns.some(function(param) {
+                            middlewareList = _ctx.sent;
+                            middleware = middlewareList.map(function(param) {
                               var _param = _slicedToArray(param, 2),
-                                middleware = _param[0],
-                                isSSR = _param[1];
-                              return (0, _routeMatcher).getRouteMatcher(
-                                (0, _getMiddlewareRegex).getMiddlewareRegex(
-                                  middleware,
-                                  !isSSR
-                                )
-                              )(cleanedAs);
+                                page = _param[0],
+                                ssr = _param[1];
+                              return {
+                                page: page,
+                                ssr: ssr
+                              };
                             });
+                            routingItems = (0, _routingItems).getRoutingItems(
+                              options.pages,
+                              middleware
+                            );
+                            requiresPreflight = false;
+                            (_iteratorNormalCompletion = true),
+                              (_didIteratorError = false),
+                              (_iteratorError = undefined);
+                            _ctx.prev = 9;
+                            _iterator = routingItems[Symbol.iterator]();
+                          case 11:
+                            if (
+                              (_iteratorNormalCompletion = (_step = _iterator.next())
+                                .done)
+                            ) {
+                              _ctx.next = 19;
+                              break;
+                            }
+                            item = _step.value;
+                            if (!item.match(cleanedAs)) {
+                              _ctx.next = 16;
+                              break;
+                            }
+                            if (item.isMiddleware) {
+                              requiresPreflight = true;
+                            }
+                            return _ctx.abrupt("break", 19);
+                          case 16:
+                            _iteratorNormalCompletion = true;
+                            _ctx.next = 11;
+                            break;
+                          case 19:
+                            _ctx.next = 25;
+                            break;
+                          case 21:
+                            _ctx.prev = 21;
+                            _ctx.t0 = _ctx["catch"](9);
+                            _didIteratorError = true;
+                            _iteratorError = _ctx.t0;
+                          case 25:
+                            _ctx.prev = 25;
+                            _ctx.prev = 26;
+                            if (
+                              !_iteratorNormalCompletion &&
+                              _iterator.return != null
+                            ) {
+                              _iterator.return();
+                            }
+                          case 28:
+                            _ctx.prev = 28;
+                            if (!_didIteratorError) {
+                              _ctx.next = 31;
+                              break;
+                            }
+                            throw _iteratorError;
+                          case 31:
+                            return _ctx.finish(28);
+                          case 32:
+                            return _ctx.finish(25);
+                          case 33:
                             if (requiresPreflight) {
-                              _ctx.next = 8;
+                              _ctx.next = 35;
                               break;
                             }
                             return _ctx.abrupt("return", {
                               type: "next"
                             });
-                          case 8:
-                            _ctx.prev = 9;
-                            _ctx.next = 12;
+                          case 35:
+                            _ctx.prev = 36;
+                            _ctx.next = 39;
                             return _this._getPreflightData({
                               preflightHref: options.as,
                               shouldCache: options.cache,
                               isPreview: options.isPreview
                             });
-                          case 12:
+                          case 39:
                             preflight = _ctx.sent;
-                            _ctx.next = 18;
+                            _ctx.next = 45;
                             break;
-                          case 15:
-                            _ctx.prev = 15;
-                            _ctx.t0 = _ctx["catch"](9);
+                          case 42:
+                            _ctx.prev = 42;
+                            _ctx.t1 = _ctx["catch"](36);
                             return _ctx.abrupt("return", {
                               type: "redirect",
                               destination: options.as
                             });
-                          case 18:
+                          case 45:
                             if (!preflight.rewrite) {
-                              _ctx.next = 27;
+                              _ctx.next = 54;
                               break;
                             }
                             if (preflight.rewrite.startsWith("/")) {
-                              _ctx.next = 21;
+                              _ctx.next = 48;
                               break;
                             }
                             return _ctx.abrupt("return", {
                               type: "redirect",
                               destination: options.as
                             });
-                          case 21:
+                          case 48:
                             parsed = (0, _parseRelativeUrl).parseRelativeUrl(
                               (0, _normalizeLocalePath).normalizeLocalePath(
                                 hasBasePath(preflight.rewrite)
@@ -6490,13 +6556,13 @@
                               matchedPage: matchedPage,
                               resolvedHref: resolvedHref
                             });
-                          case 27:
+                          case 54:
                             if (!preflight.redirect) {
-                              _ctx.next = 33;
+                              _ctx.next = 60;
                               break;
                             }
                             if (!preflight.redirect.startsWith("/")) {
-                              _ctx.next = 32;
+                              _ctx.next = 59;
                               break;
                             }
                             cleanRedirect = (0,
@@ -6520,31 +6586,35 @@
                               newUrl: newUrl,
                               newAs: newAs
                             });
-                          case 32:
+                          case 59:
                             return _ctx.abrupt("return", {
                               type: "redirect",
                               destination: preflight.redirect
                             });
-                          case 33:
+                          case 60:
                             if (!(preflight.refresh && !preflight.ssr)) {
-                              _ctx.next = 35;
+                              _ctx.next = 62;
                               break;
                             }
                             return _ctx.abrupt("return", {
                               type: "refresh"
                             });
-                          case 35:
+                          case 62:
                             return _ctx.abrupt("return", {
                               type: "next"
                             });
-                          case 36:
+                          case 63:
                           case "end":
                             return _ctx.stop();
                         }
                     },
                     _callee,
                     null,
-                    [[9, 15]]
+                    [
+                      [9, 21, 25, 33],
+                      [26, , 28, 32],
+                      [36, 42]
+                    ]
                   );
                 })
               )();
@@ -6816,11 +6886,17 @@
       });
       exports.getMiddlewareRegex = getMiddlewareRegex;
       var _routeRegex = __webpack_require__(4903);
+      // Identify ^/[param]/ in route string
+      var FIRST_SEGMENT_DYNAMIC = /^\/\[[^/]+?\](?=\/|$)/;
+      var NOT_API_ROUTE = "(?!/api(?:/|$))";
       function getMiddlewareRegex(normalizedRoute) {
         var catchAll =
           arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : true;
         var result = (0, _routeRegex).getParametrizedRoute(normalizedRoute);
-        var catchAllRegex = catchAll ? "(?!_next).*" : "";
+        var notApiRegex = FIRST_SEGMENT_DYNAMIC.test(normalizedRoute)
+          ? NOT_API_ROUTE
+          : "";
+        var catchAllRegex = catchAll ? "(?!_next($|/)).*" : "";
         var catchAllGroupedRegex = catchAll ? "(?:(/.*)?)" : "";
         if ("routeKeys" in result) {
           if (result.parameterizedRoute === "/") {
@@ -6834,10 +6910,12 @@
           return {
             groups: result.groups,
             namedRegex: "^"
+              .concat(notApiRegex)
               .concat(result.namedParameterizedRoute)
               .concat(catchAllGroupedRegex, "$"),
             re: new RegExp(
               "^"
+                .concat(notApiRegex)
                 .concat(result.parameterizedRoute)
                 .concat(catchAllGroupedRegex, "$")
             ),
@@ -6854,6 +6932,7 @@
           groups: {},
           re: new RegExp(
             "^"
+              .concat(notApiRegex)
               .concat(result.parameterizedRoute)
               .concat(catchAllGroupedRegex, "$")
           )
@@ -6891,6 +6970,18 @@
           return _routeRegex.getRouteRegex;
         }
       });
+      Object.defineProperty(exports, "getRoutingItems", {
+        enumerable: true,
+        get: function get() {
+          return _routingItems.getRoutingItems;
+        }
+      });
+      Object.defineProperty(exports, "RoutingItem", {
+        enumerable: true,
+        get: function get() {
+          return _routingItems.RoutingItem;
+        }
+      });
       Object.defineProperty(exports, "getSortedRoutes", {
         enumerable: true,
         get: function get() {
@@ -6906,6 +6997,7 @@
       var _getMiddlewareRegex = __webpack_require__(3072);
       var _routeMatcher = __webpack_require__(3156);
       var _routeRegex = __webpack_require__(4903);
+      var _routingItems = __webpack_require__(7185);
       var _sortedRoutes = __webpack_require__(566);
       var _isDynamic = __webpack_require__(6238); //# sourceMappingURL=index.js.map
 
@@ -7237,6 +7329,101 @@
       /***/
     },
 
+    /***/ 7185: /***/ function(
+      __unused_webpack_module,
+      exports,
+      __webpack_require__
+    ) {
+      "use strict";
+
+      function _arrayLikeToArray(arr, len) {
+        if (len == null || len > arr.length) len = arr.length;
+        for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
+        return arr2;
+      }
+      function _arrayWithoutHoles(arr) {
+        if (Array.isArray(arr)) return _arrayLikeToArray(arr);
+      }
+      function _iterableToArray(iter) {
+        if (
+          (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null) ||
+          iter["@@iterator"] != null
+        )
+          return Array.from(iter);
+      }
+      function _nonIterableSpread() {
+        throw new TypeError(
+          "Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."
+        );
+      }
+      function _toConsumableArray(arr) {
+        return (
+          _arrayWithoutHoles(arr) ||
+          _iterableToArray(arr) ||
+          _unsupportedIterableToArray(arr) ||
+          _nonIterableSpread()
+        );
+      }
+      function _unsupportedIterableToArray(o, minLen) {
+        if (!o) return;
+        if (typeof o === "string") return _arrayLikeToArray(o, minLen);
+        var n = Object.prototype.toString.call(o).slice(8, -1);
+        if (n === "Object" && o.constructor) n = o.constructor.name;
+        if (n === "Map" || n === "Set") return Array.from(n);
+        if (
+          n === "Arguments" ||
+          /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)
+        )
+          return _arrayLikeToArray(o, minLen);
+      }
+      Object.defineProperty(exports, "__esModule", {
+        value: true
+      });
+      exports.getRoutingItems = getRoutingItems;
+      var _getMiddlewareRegex = __webpack_require__(3072);
+      var _routeMatcher = __webpack_require__(3156);
+      var _routeRegex = __webpack_require__(4903);
+      var _sortedRoutes = __webpack_require__(566);
+      var MIDDLEWARE_SUFFIX = "/_middleware";
+      function getRoutingItems(pages, middleware) {
+        // append the suffix so that `getSortedRoutes()` can handle middleware properly
+        var middlewarePages = middleware.map(function(m) {
+          return "".concat(m.page).concat(MIDDLEWARE_SUFFIX);
+        });
+        var middlewareMap = new Map(
+          middleware.map(function(m) {
+            return [m.page, m];
+          })
+        );
+        var sortedRoutes = (0, _sortedRoutes).getSortedRoutes(
+          _toConsumableArray(pages).concat(_toConsumableArray(middlewarePages))
+        );
+        return sortedRoutes.map(function(page) {
+          if (page.endsWith(MIDDLEWARE_SUFFIX)) {
+            var p = page.slice(0, -MIDDLEWARE_SUFFIX.length) || "/";
+            var ssr = middlewareMap.get(p).ssr;
+            return {
+              match: (0, _routeMatcher).getRouteMatcher(
+                (0, _getMiddlewareRegex).getMiddlewareRegex(p, !ssr)
+              ),
+              page: p,
+              ssr: ssr,
+              isMiddleware: true
+            };
+          } else {
+            return {
+              match: (0, _routeMatcher).getRouteMatcher(
+                (0, _routeRegex).getRouteRegex(page)
+              ),
+              page: page
+            };
+          }
+        });
+      } //# sourceMappingURL=routing-items.js.map
+
+      /***/
+    },
+
     /***/ 566: /***/ function(__unused_webpack_module, exports) {
       "use strict";
 
@@ -7311,6 +7498,7 @@
           this.slugName = null;
           this.restSlugName = null;
           this.optionalRestSlugName = null;
+          this.isMiddleware = false;
         }
         _createClass(UrlNode, [
           {
@@ -7345,6 +7533,9 @@
               if (this.optionalRestSlugName !== null) {
                 childrenPaths.splice(childrenPaths.indexOf("[[...]]"), 1);
               }
+              if (this.isMiddleware) {
+                childrenPaths.splice(childrenPaths.indexOf("_middleware"), 1);
+              }
               var routes = childrenPaths
                 .map(function(c) {
                   return _this.children
@@ -7381,10 +7572,21 @@
                 }
                 routes.unshift(r);
               }
-              if (this.restSlugName !== null) {
+              if (this.isMiddleware) {
                 var _routes1;
-                (_routes1 = routes).push.apply(
+                (_routes1 = routes).unshift.apply(
                   _routes1,
+                  _toConsumableArray(
+                    this.children
+                      .get("_middleware")
+                      ._smoosh("".concat(prefix, "_middleware/"))
+                  )
+                );
+              }
+              if (this.restSlugName !== null) {
+                var _routes2;
+                (_routes2 = routes).push.apply(
+                  _routes2,
                   _toConsumableArray(
                     this.children
                       .get("[...]")
@@ -7397,9 +7599,9 @@
                 );
               }
               if (this.optionalRestSlugName !== null) {
-                var _routes2;
-                (_routes2 = routes).push.apply(
-                  _routes2,
+                var _routes3;
+                (_routes3 = routes).push.apply(
+                  _routes3,
                   _toConsumableArray(
                     this.children
                       .get("[[...]]")
@@ -7540,6 +7742,11 @@
                   // nextSegment is overwritten to [] so that it can later be sorted specifically
                   nextSegment = "[]";
                 }
+              } else if (
+                nextSegment === "_middleware" &&
+                urlPaths.length === 1
+              ) {
+                this.isMiddleware = true;
               }
               // If this UrlNode doesn't have the nextSegment yet we create a new child UrlNode
               if (!this.children.has(nextSegment)) {
Diff for index.html
@@ -19,7 +19,7 @@
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/main-0bf777b4298ee871.js"
+      src="/_next/static/chunks/main-ffd97caa434c3b21.js"
       defer=""
     ></script>
     <script
Diff for link.html
@@ -19,7 +19,7 @@
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/main-0bf777b4298ee871.js"
+      src="/_next/static/chunks/main-ffd97caa434c3b21.js"
       defer=""
     ></script>
     <script
Diff for withRouter.html
@@ -19,7 +19,7 @@
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/main-0bf777b4298ee871.js"
+      src="/_next/static/chunks/main-ffd97caa434c3b21.js"
       defer=""
     ></script>
     <script
Commit: 7514e55

@huozhi huozhi linked an issue Mar 23, 2022 that may be closed by this pull request
1 task
@ijjk
Copy link
Member

ijjk commented Mar 24, 2022

Stats from current PR

Default Build (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
buildDuration 15.4s 15.2s -211ms
buildDurationCached 6.1s 6.1s -83ms
nodeModulesSize 467 MB 467 MB ⚠️ +9.67 kB
Page Load Tests Overall decrease ⚠️
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
/ failed reqs 0 0
/ total time (seconds) 2.955 2.986 ⚠️ +0.03
/ avg req/sec 846.11 837.33 ⚠️ -8.78
/error-in-render failed reqs 0 0
/error-in-render total time (seconds) 1.167 1.257 ⚠️ +0.09
/error-in-render avg req/sec 2142.22 1988.26 ⚠️ -153.96
Client Bundles (main, webpack) Overall increase ⚠️
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
925.HASH.js gzip 179 B 179 B
framework-HASH.js gzip 42 kB 42 kB
main-HASH.js gzip 28 kB 28.4 kB ⚠️ +488 B
webpack-HASH.js gzip 1.44 kB 1.44 kB
Overall change 71.6 kB 72.1 kB ⚠️ +488 B
Legacy Client Bundles (polyfills)
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
polyfills-HASH.js gzip 31 kB 31 kB
Overall change 31 kB 31 kB
Client Pages
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
_app-HASH.js gzip 1.36 kB 1.36 kB
_error-HASH.js gzip 192 B 192 B
amp-HASH.js gzip 309 B 309 B
css-HASH.js gzip 327 B 327 B
dynamic-HASH.js gzip 2.57 kB 2.57 kB
head-HASH.js gzip 351 B 351 B
hooks-HASH.js gzip 920 B 920 B
image-HASH.js gzip 5.48 kB 5.48 kB
index-HASH.js gzip 263 B 263 B
link-HASH.js gzip 2.26 kB 2.26 kB
routerDirect..HASH.js gzip 320 B 320 B
script-HASH.js gzip 387 B 387 B
withRouter-HASH.js gzip 319 B 319 B
85e02e95b279..7e3.css gzip 107 B 107 B
Overall change 15.2 kB 15.2 kB
Client Build Manifests
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
_buildManifest.js gzip 460 B 460 B
Overall change 460 B 460 B
Rendered Page Sizes Overall increase ⚠️
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
index.html gzip 531 B 531 B
link.html gzip 544 B 545 B ⚠️ +1 B
withRouter.html gzip 524 B 525 B ⚠️ +1 B
Overall change 1.6 kB 1.6 kB ⚠️ +2 B

Diffs

Diff for main-HASH.js
@@ -473,7 +473,7 @@
       var _routeAnnouncer = __webpack_require__(8483);
       var _router1 = __webpack_require__(880);
       var _isError = __webpack_require__(676);
-      var _vitals = __webpack_require__(7185);
+      var _vitals = __webpack_require__(4564);
       var _refresh = __webpack_require__(2129);
       var _imageConfigContext = __webpack_require__(8730);
       function asyncGeneratorStep(
@@ -3197,7 +3197,7 @@
       /***/
     },
 
-    /***/ 7185: /***/ function(
+    /***/ 4564: /***/ function(
       __unused_webpack_module,
       exports,
       __webpack_require__
@@ -4351,8 +4351,8 @@
       var _resolveRewrites = _interopRequireDefault1(__webpack_require__(2431));
       var _routeMatcher = __webpack_require__(3156);
       var _routeRegex = __webpack_require__(4903);
-      var _getMiddlewareRegex = __webpack_require__(3072);
       var _formatUrl = __webpack_require__(7795);
+      var _routingItems = __webpack_require__(7185);
       function _interopRequireDefault1(obj) {
         return obj && obj.__esModule
           ? obj
@@ -6378,8 +6378,16 @@
                 _runtimeJs.default.mark(function _callee() {
                   var asPathname,
                     cleanedAs,
-                    fns,
+                    middlewareList,
+                    middleware,
+                    routingItems,
                     requiresPreflight,
+                    _iteratorNormalCompletion,
+                    _didIteratorError,
+                    _iteratorError,
+                    _iterator,
+                    _step,
+                    item,
                     preflight,
                     parsed,
                     fsPathname,
@@ -6404,58 +6412,116 @@
                             _ctx.next = 4;
                             return _this.pageLoader.getMiddlewareList();
                           case 4:
-                            fns = _ctx.sent;
-                            requiresPreflight = fns.some(function(param) {
+                            middlewareList = _ctx.sent;
+                            middleware = middlewareList.map(function(param) {
                               var _param = _slicedToArray(param, 2),
-                                middleware = _param[0],
-                                isSSR = _param[1];
-                              return (0, _routeMatcher).getRouteMatcher(
-                                (0, _getMiddlewareRegex).getMiddlewareRegex(
-                                  middleware,
-                                  !isSSR
-                                )
-                              )(cleanedAs);
+                                page = _param[0],
+                                ssr = _param[1];
+                              return {
+                                page: page,
+                                ssr: ssr
+                              };
                             });
+                            routingItems = (0, _routingItems).getRoutingItems(
+                              options.pages,
+                              middleware
+                            );
+                            requiresPreflight = false;
+                            (_iteratorNormalCompletion = true),
+                              (_didIteratorError = false),
+                              (_iteratorError = undefined);
+                            _ctx.prev = 9;
+                            _iterator = routingItems[Symbol.iterator]();
+                          case 11:
+                            if (
+                              (_iteratorNormalCompletion = (_step = _iterator.next())
+                                .done)
+                            ) {
+                              _ctx.next = 19;
+                              break;
+                            }
+                            item = _step.value;
+                            if (!item.match(cleanedAs)) {
+                              _ctx.next = 16;
+                              break;
+                            }
+                            if (item.isMiddleware) {
+                              requiresPreflight = true;
+                            }
+                            return _ctx.abrupt("break", 19);
+                          case 16:
+                            _iteratorNormalCompletion = true;
+                            _ctx.next = 11;
+                            break;
+                          case 19:
+                            _ctx.next = 25;
+                            break;
+                          case 21:
+                            _ctx.prev = 21;
+                            _ctx.t0 = _ctx["catch"](9);
+                            _didIteratorError = true;
+                            _iteratorError = _ctx.t0;
+                          case 25:
+                            _ctx.prev = 25;
+                            _ctx.prev = 26;
+                            if (
+                              !_iteratorNormalCompletion &&
+                              _iterator.return != null
+                            ) {
+                              _iterator.return();
+                            }
+                          case 28:
+                            _ctx.prev = 28;
+                            if (!_didIteratorError) {
+                              _ctx.next = 31;
+                              break;
+                            }
+                            throw _iteratorError;
+                          case 31:
+                            return _ctx.finish(28);
+                          case 32:
+                            return _ctx.finish(25);
+                          case 33:
                             if (requiresPreflight) {
-                              _ctx.next = 8;
+                              _ctx.next = 35;
                               break;
                             }
                             return _ctx.abrupt("return", {
                               type: "next"
                             });
-                          case 8:
-                            _ctx.prev = 9;
-                            _ctx.next = 12;
+                          case 35:
+                            _ctx.prev = 36;
+                            _ctx.next = 39;
                             return _this._getPreflightData({
                               preflightHref: options.as,
                               shouldCache: options.cache,
                               isPreview: options.isPreview
                             });
-                          case 12:
+                          case 39:
                             preflight = _ctx.sent;
-                            _ctx.next = 18;
+                            _ctx.next = 45;
                             break;
-                          case 15:
-                            _ctx.prev = 15;
-                            _ctx.t0 = _ctx["catch"](9);
+                          case 42:
+                            _ctx.prev = 42;
+                            _ctx.t1 = _ctx["catch"](36);
                             return _ctx.abrupt("return", {
                               type: "redirect",
                               destination: options.as
                             });
-                          case 18:
+                          case 45:
                             if (!preflight.rewrite) {
-                              _ctx.next = 27;
+                              _ctx.next = 54;
                               break;
                             }
                             if (preflight.rewrite.startsWith("/")) {
-                              _ctx.next = 21;
+                              _ctx.next = 48;
                               break;
                             }
                             return _ctx.abrupt("return", {
                               type: "redirect",
                               destination: options.as
                             });
-                          case 21:
+                          case 48:
                             parsed = (0, _parseRelativeUrl).parseRelativeUrl(
                               (0, _normalizeLocalePath).normalizeLocalePath(
                                 hasBasePath(preflight.rewrite)
@@ -6490,13 +6556,13 @@
                               matchedPage: matchedPage,
                               resolvedHref: resolvedHref
                             });
-                          case 27:
+                          case 54:
                             if (!preflight.redirect) {
-                              _ctx.next = 33;
+                              _ctx.next = 60;
                               break;
                             }
                             if (!preflight.redirect.startsWith("/")) {
-                              _ctx.next = 32;
+                              _ctx.next = 59;
                               break;
                             }
                             cleanRedirect = (0,
@@ -6520,31 +6586,35 @@
                               newUrl: newUrl,
                               newAs: newAs
                             });
-                          case 32:
+                          case 59:
                             return _ctx.abrupt("return", {
                               type: "redirect",
                               destination: preflight.redirect
                             });
-                          case 33:
+                          case 60:
                             if (!(preflight.refresh && !preflight.ssr)) {
-                              _ctx.next = 35;
+                              _ctx.next = 62;
                               break;
                             }
                             return _ctx.abrupt("return", {
                               type: "refresh"
                             });
-                          case 35:
+                          case 62:
                             return _ctx.abrupt("return", {
                               type: "next"
                             });
-                          case 36:
+                          case 63:
                           case "end":
                             return _ctx.stop();
                         }
                     },
                     _callee,
                     null,
-                    [[9, 15]]
+                    [
+                      [9, 21, 25, 33],
+                      [26, , 28, 32],
+                      [36, 42]
+                    ]
                   );
                 })
               )();
@@ -6816,11 +6886,17 @@
       });
       exports.getMiddlewareRegex = getMiddlewareRegex;
       var _routeRegex = __webpack_require__(4903);
+      // Identify ^/[param]/ in route string
+      var FIRST_SEGMENT_DYNAMIC = /^\/\[[^/]+?\](?=\/|$)/;
+      var NOT_API_ROUTE = "(?!/api(?:/|$))";
       function getMiddlewareRegex(normalizedRoute) {
         var catchAll =
           arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : true;
         var result = (0, _routeRegex).getParametrizedRoute(normalizedRoute);
-        var catchAllRegex = catchAll ? "(?!_next).*" : "";
+        var notApiRegex = FIRST_SEGMENT_DYNAMIC.test(normalizedRoute)
+          ? NOT_API_ROUTE
+          : "";
+        var catchAllRegex = catchAll ? "(?!_next($|/)).*" : "";
         var catchAllGroupedRegex = catchAll ? "(?:(/.*)?)" : "";
         if ("routeKeys" in result) {
           if (result.parameterizedRoute === "/") {
@@ -6834,10 +6910,12 @@
           return {
             groups: result.groups,
             namedRegex: "^"
+              .concat(notApiRegex)
               .concat(result.namedParameterizedRoute)
               .concat(catchAllGroupedRegex, "$"),
             re: new RegExp(
               "^"
+                .concat(notApiRegex)
                 .concat(result.parameterizedRoute)
                 .concat(catchAllGroupedRegex, "$")
             ),
@@ -6854,6 +6932,7 @@
           groups: {},
           re: new RegExp(
             "^"
+              .concat(notApiRegex)
               .concat(result.parameterizedRoute)
               .concat(catchAllGroupedRegex, "$")
           )
@@ -6891,6 +6970,18 @@
           return _routeRegex.getRouteRegex;
         }
       });
+      Object.defineProperty(exports, "getRoutingItems", {
+        enumerable: true,
+        get: function get() {
+          return _routingItems.getRoutingItems;
+        }
+      });
+      Object.defineProperty(exports, "RoutingItem", {
+        enumerable: true,
+        get: function get() {
+          return _routingItems.RoutingItem;
+        }
+      });
       Object.defineProperty(exports, "getSortedRoutes", {
         enumerable: true,
         get: function get() {
@@ -6906,6 +6997,7 @@
       var _getMiddlewareRegex = __webpack_require__(3072);
       var _routeMatcher = __webpack_require__(3156);
       var _routeRegex = __webpack_require__(4903);
+      var _routingItems = __webpack_require__(7185);
       var _sortedRoutes = __webpack_require__(566);
       var _isDynamic = __webpack_require__(6238); //# sourceMappingURL=index.js.map
 
@@ -7237,6 +7329,101 @@
       /***/
     },
 
+    /***/ 7185: /***/ function(
+      __unused_webpack_module,
+      exports,
+      __webpack_require__
+    ) {
+      "use strict";
+
+      function _arrayLikeToArray(arr, len) {
+        if (len == null || len > arr.length) len = arr.length;
+        for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
+        return arr2;
+      }
+      function _arrayWithoutHoles(arr) {
+        if (Array.isArray(arr)) return _arrayLikeToArray(arr);
+      }
+      function _iterableToArray(iter) {
+        if (
+          (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null) ||
+          iter["@@iterator"] != null
+        )
+          return Array.from(iter);
+      }
+      function _nonIterableSpread() {
+        throw new TypeError(
+          "Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."
+        );
+      }
+      function _toConsumableArray(arr) {
+        return (
+          _arrayWithoutHoles(arr) ||
+          _iterableToArray(arr) ||
+          _unsupportedIterableToArray(arr) ||
+          _nonIterableSpread()
+        );
+      }
+      function _unsupportedIterableToArray(o, minLen) {
+        if (!o) return;
+        if (typeof o === "string") return _arrayLikeToArray(o, minLen);
+        var n = Object.prototype.toString.call(o).slice(8, -1);
+        if (n === "Object" && o.constructor) n = o.constructor.name;
+        if (n === "Map" || n === "Set") return Array.from(n);
+        if (
+          n === "Arguments" ||
+          /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)
+        )
+          return _arrayLikeToArray(o, minLen);
+      }
+      Object.defineProperty(exports, "__esModule", {
+        value: true
+      });
+      exports.getRoutingItems = getRoutingItems;
+      var _getMiddlewareRegex = __webpack_require__(3072);
+      var _routeMatcher = __webpack_require__(3156);
+      var _routeRegex = __webpack_require__(4903);
+      var _sortedRoutes = __webpack_require__(566);
+      var MIDDLEWARE_SUFFIX = "/_middleware";
+      function getRoutingItems(pages, middleware) {
+        // append the suffix so that `getSortedRoutes()` can handle middleware properly
+        var middlewarePages = middleware.map(function(m) {
+          return "".concat(m.page).concat(MIDDLEWARE_SUFFIX);
+        });
+        var middlewareMap = new Map(
+          middleware.map(function(m) {
+            return [m.page, m];
+          })
+        );
+        var sortedRoutes = (0, _sortedRoutes).getSortedRoutes(
+          _toConsumableArray(pages).concat(_toConsumableArray(middlewarePages))
+        );
+        return sortedRoutes.map(function(page) {
+          if (page.endsWith(MIDDLEWARE_SUFFIX)) {
+            var p = page.slice(0, -MIDDLEWARE_SUFFIX.length) || "/";
+            var ssr = middlewareMap.get(p).ssr;
+            return {
+              match: (0, _routeMatcher).getRouteMatcher(
+                (0, _getMiddlewareRegex).getMiddlewareRegex(p, !ssr)
+              ),
+              page: p,
+              ssr: ssr,
+              isMiddleware: true
+            };
+          } else {
+            return {
+              match: (0, _routeMatcher).getRouteMatcher(
+                (0, _routeRegex).getRouteRegex(page)
+              ),
+              page: page
+            };
+          }
+        });
+      } //# sourceMappingURL=routing-items.js.map
+
+      /***/
+    },
+
     /***/ 566: /***/ function(__unused_webpack_module, exports) {
       "use strict";
 
@@ -7311,6 +7498,7 @@
           this.slugName = null;
           this.restSlugName = null;
           this.optionalRestSlugName = null;
+          this.isMiddleware = false;
         }
         _createClass(UrlNode, [
           {
@@ -7345,6 +7533,9 @@
               if (this.optionalRestSlugName !== null) {
                 childrenPaths.splice(childrenPaths.indexOf("[[...]]"), 1);
               }
+              if (this.isMiddleware) {
+                childrenPaths.splice(childrenPaths.indexOf("_middleware"), 1);
+              }
               var routes = childrenPaths
                 .map(function(c) {
                   return _this.children
@@ -7381,10 +7572,21 @@
                 }
                 routes.unshift(r);
               }
-              if (this.restSlugName !== null) {
+              if (this.isMiddleware) {
                 var _routes1;
-                (_routes1 = routes).push.apply(
+                (_routes1 = routes).unshift.apply(
                   _routes1,
+                  _toConsumableArray(
+                    this.children
+                      .get("_middleware")
+                      ._smoosh("".concat(prefix, "_middleware/"))
+                  )
+                );
+              }
+              if (this.restSlugName !== null) {
+                var _routes2;
+                (_routes2 = routes).push.apply(
+                  _routes2,
                   _toConsumableArray(
                     this.children
                       .get("[...]")
@@ -7397,9 +7599,9 @@
                 );
               }
               if (this.optionalRestSlugName !== null) {
-                var _routes2;
-                (_routes2 = routes).push.apply(
-                  _routes2,
+                var _routes3;
+                (_routes3 = routes).push.apply(
+                  _routes3,
                   _toConsumableArray(
                     this.children
                       .get("[[...]]")
@@ -7540,6 +7742,11 @@
                   // nextSegment is overwritten to [] so that it can later be sorted specifically
                   nextSegment = "[]";
                 }
+              } else if (
+                nextSegment === "_middleware" &&
+                urlPaths.length === 1
+              ) {
+                this.isMiddleware = true;
               }
               // If this UrlNode doesn't have the nextSegment yet we create a new child UrlNode
               if (!this.children.has(nextSegment)) {
Diff for index.html
@@ -19,7 +19,7 @@
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/main-0bf777b4298ee871.js"
+      src="/_next/static/chunks/main-ffd97caa434c3b21.js"
       defer=""
     ></script>
     <script
Diff for link.html
@@ -19,7 +19,7 @@
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/main-0bf777b4298ee871.js"
+      src="/_next/static/chunks/main-ffd97caa434c3b21.js"
       defer=""
     ></script>
     <script
Diff for withRouter.html
@@ -19,7 +19,7 @@
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/main-0bf777b4298ee871.js"
+      src="/_next/static/chunks/main-ffd97caa434c3b21.js"
       defer=""
     ></script>
     <script

Default Build with SWC (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
buildDuration 19.1s 19.1s -25ms
buildDurationCached 6.1s 6.2s ⚠️ +95ms
nodeModulesSize 467 MB 467 MB ⚠️ +9.67 kB
Page Load Tests Overall increase ✓
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
/ failed reqs 0 0
/ total time (seconds) 2.951 3.006 ⚠️ +0.05
/ avg req/sec 847.04 831.62 ⚠️ -15.42
/error-in-render failed reqs 0 0
/error-in-render total time (seconds) 1.219 1.202 -0.02
/error-in-render avg req/sec 2050.38 2080.09 +29.71
Client Bundles (main, webpack) Overall increase ⚠️
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
925.HASH.js gzip 178 B 178 B
framework-HASH.js gzip 42.3 kB 42.3 kB
main-HASH.js gzip 28.2 kB 28.8 kB ⚠️ +530 B
webpack-HASH.js gzip 1.45 kB 1.45 kB
Overall change 72.1 kB 72.7 kB ⚠️ +530 B
Legacy Client Bundles (polyfills)
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
polyfills-HASH.js gzip 31 kB 31 kB
Overall change 31 kB 31 kB
Client Pages
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
_app-HASH.js gzip 1.35 kB 1.35 kB
_error-HASH.js gzip 179 B 179 B
amp-HASH.js gzip 313 B 313 B
css-HASH.js gzip 324 B 324 B
dynamic-HASH.js gzip 2.56 kB 2.56 kB
head-HASH.js gzip 351 B 351 B
hooks-HASH.js gzip 921 B 921 B
image-HASH.js gzip 5.59 kB 5.59 kB
index-HASH.js gzip 261 B 261 B
link-HASH.js gzip 2.33 kB 2.33 kB
routerDirect..HASH.js gzip 322 B 322 B
script-HASH.js gzip 388 B 388 B
withRouter-HASH.js gzip 317 B 317 B
85e02e95b279..7e3.css gzip 107 B 107 B
Overall change 15.3 kB 15.3 kB
Client Build Manifests
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
_buildManifest.js gzip 458 B 458 B
Overall change 458 B 458 B
Rendered Page Sizes Overall increase ⚠️
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
index.html gzip 531 B 533 B ⚠️ +2 B
link.html gzip 546 B 547 B ⚠️ +1 B
withRouter.html gzip 527 B 527 B
Overall change 1.6 kB 1.61 kB ⚠️ +3 B

Diffs

Diff for main-HASH.js
@@ -473,7 +473,7 @@
       var _routeAnnouncer = __webpack_require__(8483);
       var _router1 = __webpack_require__(880);
       var _isError = __webpack_require__(676);
-      var _vitals = __webpack_require__(7185);
+      var _vitals = __webpack_require__(4564);
       var _refresh = __webpack_require__(2129);
       var _imageConfigContext = __webpack_require__(8730);
       function asyncGeneratorStep(
@@ -3197,7 +3197,7 @@
       /***/
     },
 
-    /***/ 7185: /***/ function(
+    /***/ 4564: /***/ function(
       __unused_webpack_module,
       exports,
       __webpack_require__
@@ -4351,8 +4351,8 @@
       var _resolveRewrites = _interopRequireDefault1(__webpack_require__(2431));
       var _routeMatcher = __webpack_require__(3156);
       var _routeRegex = __webpack_require__(4903);
-      var _getMiddlewareRegex = __webpack_require__(3072);
       var _formatUrl = __webpack_require__(7795);
+      var _routingItems = __webpack_require__(7185);
       function _interopRequireDefault1(obj) {
         return obj && obj.__esModule
           ? obj
@@ -6378,8 +6378,16 @@
                 _runtimeJs.default.mark(function _callee() {
                   var asPathname,
                     cleanedAs,
-                    fns,
+                    middlewareList,
+                    middleware,
+                    routingItems,
                     requiresPreflight,
+                    _iteratorNormalCompletion,
+                    _didIteratorError,
+                    _iteratorError,
+                    _iterator,
+                    _step,
+                    item,
                     preflight,
                     parsed,
                     fsPathname,
@@ -6404,58 +6412,116 @@
                             _ctx.next = 4;
                             return _this.pageLoader.getMiddlewareList();
                           case 4:
-                            fns = _ctx.sent;
-                            requiresPreflight = fns.some(function(param) {
+                            middlewareList = _ctx.sent;
+                            middleware = middlewareList.map(function(param) {
                               var _param = _slicedToArray(param, 2),
-                                middleware = _param[0],
-                                isSSR = _param[1];
-                              return (0, _routeMatcher).getRouteMatcher(
-                                (0, _getMiddlewareRegex).getMiddlewareRegex(
-                                  middleware,
-                                  !isSSR
-                                )
-                              )(cleanedAs);
+                                page = _param[0],
+                                ssr = _param[1];
+                              return {
+                                page: page,
+                                ssr: ssr
+                              };
                             });
+                            routingItems = (0, _routingItems).getRoutingItems(
+                              options.pages,
+                              middleware
+                            );
+                            requiresPreflight = false;
+                            (_iteratorNormalCompletion = true),
+                              (_didIteratorError = false),
+                              (_iteratorError = undefined);
+                            _ctx.prev = 9;
+                            _iterator = routingItems[Symbol.iterator]();
+                          case 11:
+                            if (
+                              (_iteratorNormalCompletion = (_step = _iterator.next())
+                                .done)
+                            ) {
+                              _ctx.next = 19;
+                              break;
+                            }
+                            item = _step.value;
+                            if (!item.match(cleanedAs)) {
+                              _ctx.next = 16;
+                              break;
+                            }
+                            if (item.isMiddleware) {
+                              requiresPreflight = true;
+                            }
+                            return _ctx.abrupt("break", 19);
+                          case 16:
+                            _iteratorNormalCompletion = true;
+                            _ctx.next = 11;
+                            break;
+                          case 19:
+                            _ctx.next = 25;
+                            break;
+                          case 21:
+                            _ctx.prev = 21;
+                            _ctx.t0 = _ctx["catch"](9);
+                            _didIteratorError = true;
+                            _iteratorError = _ctx.t0;
+                          case 25:
+                            _ctx.prev = 25;
+                            _ctx.prev = 26;
+                            if (
+                              !_iteratorNormalCompletion &&
+                              _iterator.return != null
+                            ) {
+                              _iterator.return();
+                            }
+                          case 28:
+                            _ctx.prev = 28;
+                            if (!_didIteratorError) {
+                              _ctx.next = 31;
+                              break;
+                            }
+                            throw _iteratorError;
+                          case 31:
+                            return _ctx.finish(28);
+                          case 32:
+                            return _ctx.finish(25);
+                          case 33:
                             if (requiresPreflight) {
-                              _ctx.next = 8;
+                              _ctx.next = 35;
                               break;
                             }
                             return _ctx.abrupt("return", {
                               type: "next"
                             });
-                          case 8:
-                            _ctx.prev = 9;
-                            _ctx.next = 12;
+                          case 35:
+                            _ctx.prev = 36;
+                            _ctx.next = 39;
                             return _this._getPreflightData({
                               preflightHref: options.as,
                               shouldCache: options.cache,
                               isPreview: options.isPreview
                             });
-                          case 12:
+                          case 39:
                             preflight = _ctx.sent;
-                            _ctx.next = 18;
+                            _ctx.next = 45;
                             break;
-                          case 15:
-                            _ctx.prev = 15;
-                            _ctx.t0 = _ctx["catch"](9);
+                          case 42:
+                            _ctx.prev = 42;
+                            _ctx.t1 = _ctx["catch"](36);
                             return _ctx.abrupt("return", {
                               type: "redirect",
                               destination: options.as
                             });
-                          case 18:
+                          case 45:
                             if (!preflight.rewrite) {
-                              _ctx.next = 27;
+                              _ctx.next = 54;
                               break;
                             }
                             if (preflight.rewrite.startsWith("/")) {
-                              _ctx.next = 21;
+                              _ctx.next = 48;
                               break;
                             }
                             return _ctx.abrupt("return", {
                               type: "redirect",
                               destination: options.as
                             });
-                          case 21:
+                          case 48:
                             parsed = (0, _parseRelativeUrl).parseRelativeUrl(
                               (0, _normalizeLocalePath).normalizeLocalePath(
                                 hasBasePath(preflight.rewrite)
@@ -6490,13 +6556,13 @@
                               matchedPage: matchedPage,
                               resolvedHref: resolvedHref
                             });
-                          case 27:
+                          case 54:
                             if (!preflight.redirect) {
-                              _ctx.next = 33;
+                              _ctx.next = 60;
                               break;
                             }
                             if (!preflight.redirect.startsWith("/")) {
-                              _ctx.next = 32;
+                              _ctx.next = 59;
                               break;
                             }
                             cleanRedirect = (0,
@@ -6520,31 +6586,35 @@
                               newUrl: newUrl,
                               newAs: newAs
                             });
-                          case 32:
+                          case 59:
                             return _ctx.abrupt("return", {
                               type: "redirect",
                               destination: preflight.redirect
                             });
-                          case 33:
+                          case 60:
                             if (!(preflight.refresh && !preflight.ssr)) {
-                              _ctx.next = 35;
+                              _ctx.next = 62;
                               break;
                             }
                             return _ctx.abrupt("return", {
                               type: "refresh"
                             });
-                          case 35:
+                          case 62:
                             return _ctx.abrupt("return", {
                               type: "next"
                             });
-                          case 36:
+                          case 63:
                           case "end":
                             return _ctx.stop();
                         }
                     },
                     _callee,
                     null,
-                    [[9, 15]]
+                    [
+                      [9, 21, 25, 33],
+                      [26, , 28, 32],
+                      [36, 42]
+                    ]
                   );
                 })
               )();
@@ -6816,11 +6886,17 @@
       });
       exports.getMiddlewareRegex = getMiddlewareRegex;
       var _routeRegex = __webpack_require__(4903);
+      // Identify ^/[param]/ in route string
+      var FIRST_SEGMENT_DYNAMIC = /^\/\[[^/]+?\](?=\/|$)/;
+      var NOT_API_ROUTE = "(?!/api(?:/|$))";
       function getMiddlewareRegex(normalizedRoute) {
         var catchAll =
           arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : true;
         var result = (0, _routeRegex).getParametrizedRoute(normalizedRoute);
-        var catchAllRegex = catchAll ? "(?!_next).*" : "";
+        var notApiRegex = FIRST_SEGMENT_DYNAMIC.test(normalizedRoute)
+          ? NOT_API_ROUTE
+          : "";
+        var catchAllRegex = catchAll ? "(?!_next($|/)).*" : "";
         var catchAllGroupedRegex = catchAll ? "(?:(/.*)?)" : "";
         if ("routeKeys" in result) {
           if (result.parameterizedRoute === "/") {
@@ -6834,10 +6910,12 @@
           return {
             groups: result.groups,
             namedRegex: "^"
+              .concat(notApiRegex)
               .concat(result.namedParameterizedRoute)
               .concat(catchAllGroupedRegex, "$"),
             re: new RegExp(
               "^"
+                .concat(notApiRegex)
                 .concat(result.parameterizedRoute)
                 .concat(catchAllGroupedRegex, "$")
             ),
@@ -6854,6 +6932,7 @@
           groups: {},
           re: new RegExp(
             "^"
+              .concat(notApiRegex)
               .concat(result.parameterizedRoute)
               .concat(catchAllGroupedRegex, "$")
           )
@@ -6891,6 +6970,18 @@
           return _routeRegex.getRouteRegex;
         }
       });
+      Object.defineProperty(exports, "getRoutingItems", {
+        enumerable: true,
+        get: function get() {
+          return _routingItems.getRoutingItems;
+        }
+      });
+      Object.defineProperty(exports, "RoutingItem", {
+        enumerable: true,
+        get: function get() {
+          return _routingItems.RoutingItem;
+        }
+      });
       Object.defineProperty(exports, "getSortedRoutes", {
         enumerable: true,
         get: function get() {
@@ -6906,6 +6997,7 @@
       var _getMiddlewareRegex = __webpack_require__(3072);
       var _routeMatcher = __webpack_require__(3156);
       var _routeRegex = __webpack_require__(4903);
+      var _routingItems = __webpack_require__(7185);
       var _sortedRoutes = __webpack_require__(566);
       var _isDynamic = __webpack_require__(6238); //# sourceMappingURL=index.js.map
 
@@ -7237,6 +7329,101 @@
       /***/
     },
 
+    /***/ 7185: /***/ function(
+      __unused_webpack_module,
+      exports,
+      __webpack_require__
+    ) {
+      "use strict";
+
+      function _arrayLikeToArray(arr, len) {
+        if (len == null || len > arr.length) len = arr.length;
+        for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
+        return arr2;
+      }
+      function _arrayWithoutHoles(arr) {
+        if (Array.isArray(arr)) return _arrayLikeToArray(arr);
+      }
+      function _iterableToArray(iter) {
+        if (
+          (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null) ||
+          iter["@@iterator"] != null
+        )
+          return Array.from(iter);
+      }
+      function _nonIterableSpread() {
+        throw new TypeError(
+          "Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."
+        );
+      }
+      function _toConsumableArray(arr) {
+        return (
+          _arrayWithoutHoles(arr) ||
+          _iterableToArray(arr) ||
+          _unsupportedIterableToArray(arr) ||
+          _nonIterableSpread()
+        );
+      }
+      function _unsupportedIterableToArray(o, minLen) {
+        if (!o) return;
+        if (typeof o === "string") return _arrayLikeToArray(o, minLen);
+        var n = Object.prototype.toString.call(o).slice(8, -1);
+        if (n === "Object" && o.constructor) n = o.constructor.name;
+        if (n === "Map" || n === "Set") return Array.from(n);
+        if (
+          n === "Arguments" ||
+          /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)
+        )
+          return _arrayLikeToArray(o, minLen);
+      }
+      Object.defineProperty(exports, "__esModule", {
+        value: true
+      });
+      exports.getRoutingItems = getRoutingItems;
+      var _getMiddlewareRegex = __webpack_require__(3072);
+      var _routeMatcher = __webpack_require__(3156);
+      var _routeRegex = __webpack_require__(4903);
+      var _sortedRoutes = __webpack_require__(566);
+      var MIDDLEWARE_SUFFIX = "/_middleware";
+      function getRoutingItems(pages, middleware) {
+        // append the suffix so that `getSortedRoutes()` can handle middleware properly
+        var middlewarePages = middleware.map(function(m) {
+          return "".concat(m.page).concat(MIDDLEWARE_SUFFIX);
+        });
+        var middlewareMap = new Map(
+          middleware.map(function(m) {
+            return [m.page, m];
+          })
+        );
+        var sortedRoutes = (0, _sortedRoutes).getSortedRoutes(
+          _toConsumableArray(pages).concat(_toConsumableArray(middlewarePages))
+        );
+        return sortedRoutes.map(function(page) {
+          if (page.endsWith(MIDDLEWARE_SUFFIX)) {
+            var p = page.slice(0, -MIDDLEWARE_SUFFIX.length) || "/";
+            var ssr = middlewareMap.get(p).ssr;
+            return {
+              match: (0, _routeMatcher).getRouteMatcher(
+                (0, _getMiddlewareRegex).getMiddlewareRegex(p, !ssr)
+              ),
+              page: p,
+              ssr: ssr,
+              isMiddleware: true
+            };
+          } else {
+            return {
+              match: (0, _routeMatcher).getRouteMatcher(
+                (0, _routeRegex).getRouteRegex(page)
+              ),
+              page: page
+            };
+          }
+        });
+      } //# sourceMappingURL=routing-items.js.map
+
+      /***/
+    },
+
     /***/ 566: /***/ function(__unused_webpack_module, exports) {
       "use strict";
 
@@ -7311,6 +7498,7 @@
           this.slugName = null;
           this.restSlugName = null;
           this.optionalRestSlugName = null;
+          this.isMiddleware = false;
         }
         _createClass(UrlNode, [
           {
@@ -7345,6 +7533,9 @@
               if (this.optionalRestSlugName !== null) {
                 childrenPaths.splice(childrenPaths.indexOf("[[...]]"), 1);
               }
+              if (this.isMiddleware) {
+                childrenPaths.splice(childrenPaths.indexOf("_middleware"), 1);
+              }
               var routes = childrenPaths
                 .map(function(c) {
                   return _this.children
@@ -7381,10 +7572,21 @@
                 }
                 routes.unshift(r);
               }
-              if (this.restSlugName !== null) {
+              if (this.isMiddleware) {
                 var _routes1;
-                (_routes1 = routes).push.apply(
+                (_routes1 = routes).unshift.apply(
                   _routes1,
+                  _toConsumableArray(
+                    this.children
+                      .get("_middleware")
+                      ._smoosh("".concat(prefix, "_middleware/"))
+                  )
+                );
+              }
+              if (this.restSlugName !== null) {
+                var _routes2;
+                (_routes2 = routes).push.apply(
+                  _routes2,
                   _toConsumableArray(
                     this.children
                       .get("[...]")
@@ -7397,9 +7599,9 @@
                 );
               }
               if (this.optionalRestSlugName !== null) {
-                var _routes2;
-                (_routes2 = routes).push.apply(
-                  _routes2,
+                var _routes3;
+                (_routes3 = routes).push.apply(
+                  _routes3,
                   _toConsumableArray(
                     this.children
                       .get("[[...]]")
@@ -7540,6 +7742,11 @@
                   // nextSegment is overwritten to [] so that it can later be sorted specifically
                   nextSegment = "[]";
                 }
+              } else if (
+                nextSegment === "_middleware" &&
+                urlPaths.length === 1
+              ) {
+                this.isMiddleware = true;
               }
               // If this UrlNode doesn't have the nextSegment yet we create a new child UrlNode
               if (!this.children.has(nextSegment)) {
Diff for index.html
@@ -19,7 +19,7 @@
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/main-0bf777b4298ee871.js"
+      src="/_next/static/chunks/main-ffd97caa434c3b21.js"
       defer=""
     ></script>
     <script
Diff for link.html
@@ -19,7 +19,7 @@
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/main-0bf777b4298ee871.js"
+      src="/_next/static/chunks/main-ffd97caa434c3b21.js"
       defer=""
     ></script>
     <script
Diff for withRouter.html
@@ -19,7 +19,7 @@
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/main-0bf777b4298ee871.js"
+      src="/_next/static/chunks/main-ffd97caa434c3b21.js"
       defer=""
     ></script>
     <script
Commit: c3a0769

@ijjk
Copy link
Member

ijjk commented Mar 25, 2022

Stats from current PR

Default Build (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
buildDuration 15.2s 15.5s ⚠️ +306ms
buildDurationCached 6.2s 6s -181ms
nodeModulesSize 467 MB 467 MB ⚠️ +9.67 kB
Page Load Tests Overall decrease ⚠️
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
/ failed reqs 0 0
/ total time (seconds) 2.973 2.984 ⚠️ +0.01
/ avg req/sec 841 837.87 ⚠️ -3.13
/error-in-render failed reqs 0 0
/error-in-render total time (seconds) 1.182 1.219 ⚠️ +0.04
/error-in-render avg req/sec 2115.34 2051.45 ⚠️ -63.89
Client Bundles (main, webpack) Overall increase ⚠️
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
925.HASH.js gzip 179 B 179 B
framework-HASH.js gzip 42 kB 42 kB
main-HASH.js gzip 28 kB 28.4 kB ⚠️ +489 B
webpack-HASH.js gzip 1.44 kB 1.44 kB
Overall change 71.6 kB 72.1 kB ⚠️ +489 B
Legacy Client Bundles (polyfills)
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
polyfills-HASH.js gzip 31 kB 31 kB
Overall change 31 kB 31 kB
Client Pages
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
_app-HASH.js gzip 1.36 kB 1.36 kB
_error-HASH.js gzip 192 B 192 B
amp-HASH.js gzip 309 B 309 B
css-HASH.js gzip 327 B 327 B
dynamic-HASH.js gzip 2.57 kB 2.57 kB
head-HASH.js gzip 351 B 351 B
hooks-HASH.js gzip 920 B 920 B
image-HASH.js gzip 5.48 kB 5.48 kB
index-HASH.js gzip 263 B 263 B
link-HASH.js gzip 2.26 kB 2.26 kB
routerDirect..HASH.js gzip 320 B 320 B
script-HASH.js gzip 387 B 387 B
withRouter-HASH.js gzip 319 B 319 B
85e02e95b279..7e3.css gzip 107 B 107 B
Overall change 15.2 kB 15.2 kB
Client Build Manifests
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
_buildManifest.js gzip 460 B 460 B
Overall change 460 B 460 B
Rendered Page Sizes Overall increase ⚠️
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
index.html gzip 531 B 532 B ⚠️ +1 B
link.html gzip 545 B 546 B ⚠️ +1 B
withRouter.html gzip 525 B 526 B ⚠️ +1 B
Overall change 1.6 kB 1.6 kB ⚠️ +3 B

Diffs

Diff for main-HASH.js
@@ -473,7 +473,7 @@
       var _routeAnnouncer = __webpack_require__(8483);
       var _router1 = __webpack_require__(880);
       var _isError = __webpack_require__(676);
-      var _vitals = __webpack_require__(7185);
+      var _vitals = __webpack_require__(4564);
       var _refresh = __webpack_require__(2129);
       var _imageConfigContext = __webpack_require__(8730);
       function asyncGeneratorStep(
@@ -3197,7 +3197,7 @@
       /***/
     },
 
-    /***/ 7185: /***/ function(
+    /***/ 4564: /***/ function(
       __unused_webpack_module,
       exports,
       __webpack_require__
@@ -4351,8 +4351,8 @@
       var _resolveRewrites = _interopRequireDefault1(__webpack_require__(2431));
       var _routeMatcher = __webpack_require__(3156);
       var _routeRegex = __webpack_require__(4903);
-      var _getMiddlewareRegex = __webpack_require__(3072);
       var _formatUrl = __webpack_require__(7795);
+      var _routingItems = __webpack_require__(7185);
       function _interopRequireDefault1(obj) {
         return obj && obj.__esModule
           ? obj
@@ -6378,8 +6378,16 @@
                 _runtimeJs.default.mark(function _callee() {
                   var asPathname,
                     cleanedAs,
-                    fns,
+                    middlewareList,
+                    middleware,
+                    routingItems,
                     requiresPreflight,
+                    _iteratorNormalCompletion,
+                    _didIteratorError,
+                    _iteratorError,
+                    _iterator,
+                    _step,
+                    item,
                     preflight,
                     parsed,
                     fsPathname,
@@ -6404,58 +6412,116 @@
                             _ctx.next = 4;
                             return _this.pageLoader.getMiddlewareList();
                           case 4:
-                            fns = _ctx.sent;
-                            requiresPreflight = fns.some(function(param) {
+                            middlewareList = _ctx.sent;
+                            middleware = middlewareList.map(function(param) {
                               var _param = _slicedToArray(param, 2),
-                                middleware = _param[0],
-                                isSSR = _param[1];
-                              return (0, _routeMatcher).getRouteMatcher(
-                                (0, _getMiddlewareRegex).getMiddlewareRegex(
-                                  middleware,
-                                  !isSSR
-                                )
-                              )(cleanedAs);
+                                page = _param[0],
+                                ssr = _param[1];
+                              return {
+                                page: page,
+                                ssr: ssr
+                              };
                             });
+                            routingItems = (0, _routingItems).getRoutingItems(
+                              options.pages,
+                              middleware
+                            );
+                            requiresPreflight = false;
+                            (_iteratorNormalCompletion = true),
+                              (_didIteratorError = false),
+                              (_iteratorError = undefined);
+                            _ctx.prev = 9;
+                            _iterator = routingItems[Symbol.iterator]();
+                          case 11:
+                            if (
+                              (_iteratorNormalCompletion = (_step = _iterator.next())
+                                .done)
+                            ) {
+                              _ctx.next = 19;
+                              break;
+                            }
+                            item = _step.value;
+                            if (!item.match(cleanedAs)) {
+                              _ctx.next = 16;
+                              break;
+                            }
+                            if (item.isMiddleware) {
+                              requiresPreflight = true;
+                            }
+                            return _ctx.abrupt("break", 19);
+                          case 16:
+                            _iteratorNormalCompletion = true;
+                            _ctx.next = 11;
+                            break;
+                          case 19:
+                            _ctx.next = 25;
+                            break;
+                          case 21:
+                            _ctx.prev = 21;
+                            _ctx.t0 = _ctx["catch"](9);
+                            _didIteratorError = true;
+                            _iteratorError = _ctx.t0;
+                          case 25:
+                            _ctx.prev = 25;
+                            _ctx.prev = 26;
+                            if (
+                              !_iteratorNormalCompletion &&
+                              _iterator.return != null
+                            ) {
+                              _iterator.return();
+                            }
+                          case 28:
+                            _ctx.prev = 28;
+                            if (!_didIteratorError) {
+                              _ctx.next = 31;
+                              break;
+                            }
+                            throw _iteratorError;
+                          case 31:
+                            return _ctx.finish(28);
+                          case 32:
+                            return _ctx.finish(25);
+                          case 33:
                             if (requiresPreflight) {
-                              _ctx.next = 8;
+                              _ctx.next = 35;
                               break;
                             }
                             return _ctx.abrupt("return", {
                               type: "next"
                             });
-                          case 8:
-                            _ctx.prev = 9;
-                            _ctx.next = 12;
+                          case 35:
+                            _ctx.prev = 36;
+                            _ctx.next = 39;
                             return _this._getPreflightData({
                               preflightHref: options.as,
                               shouldCache: options.cache,
                               isPreview: options.isPreview
                             });
-                          case 12:
+                          case 39:
                             preflight = _ctx.sent;
-                            _ctx.next = 18;
+                            _ctx.next = 45;
                             break;
-                          case 15:
-                            _ctx.prev = 15;
-                            _ctx.t0 = _ctx["catch"](9);
+                          case 42:
+                            _ctx.prev = 42;
+                            _ctx.t1 = _ctx["catch"](36);
                             return _ctx.abrupt("return", {
                               type: "redirect",
                               destination: options.as
                             });
-                          case 18:
+                          case 45:
                             if (!preflight.rewrite) {
-                              _ctx.next = 27;
+                              _ctx.next = 54;
                               break;
                             }
                             if (preflight.rewrite.startsWith("/")) {
-                              _ctx.next = 21;
+                              _ctx.next = 48;
                               break;
                             }
                             return _ctx.abrupt("return", {
                               type: "redirect",
                               destination: options.as
                             });
-                          case 21:
+                          case 48:
                             parsed = (0, _parseRelativeUrl).parseRelativeUrl(
                               (0, _normalizeLocalePath).normalizeLocalePath(
                                 hasBasePath(preflight.rewrite)
@@ -6490,13 +6556,13 @@
                               matchedPage: matchedPage,
                               resolvedHref: resolvedHref
                             });
-                          case 27:
+                          case 54:
                             if (!preflight.redirect) {
-                              _ctx.next = 33;
+                              _ctx.next = 60;
                               break;
                             }
                             if (!preflight.redirect.startsWith("/")) {
-                              _ctx.next = 32;
+                              _ctx.next = 59;
                               break;
                             }
                             cleanRedirect = (0,
@@ -6520,31 +6586,35 @@
                               newUrl: newUrl,
                               newAs: newAs
                             });
-                          case 32:
+                          case 59:
                             return _ctx.abrupt("return", {
                               type: "redirect",
                               destination: preflight.redirect
                             });
-                          case 33:
+                          case 60:
                             if (!(preflight.refresh && !preflight.ssr)) {
-                              _ctx.next = 35;
+                              _ctx.next = 62;
                               break;
                             }
                             return _ctx.abrupt("return", {
                               type: "refresh"
                             });
-                          case 35:
+                          case 62:
                             return _ctx.abrupt("return", {
                               type: "next"
                             });
-                          case 36:
+                          case 63:
                           case "end":
                             return _ctx.stop();
                         }
                     },
                     _callee,
                     null,
-                    [[9, 15]]
+                    [
+                      [9, 21, 25, 33],
+                      [26, , 28, 32],
+                      [36, 42]
+                    ]
                   );
                 })
               )();
@@ -6816,11 +6886,17 @@
       });
       exports.getMiddlewareRegex = getMiddlewareRegex;
       var _routeRegex = __webpack_require__(4903);
+      // Identify ^/[param]/ in route string
+      var FIRST_SEGMENT_DYNAMIC = /^\/\[[^/]+?\](?=\/|$)/;
+      var NOT_API_ROUTE = "(?!/api(?:/|$))";
       function getMiddlewareRegex(normalizedRoute) {
         var catchAll =
           arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : true;
         var result = (0, _routeRegex).getParametrizedRoute(normalizedRoute);
-        var catchAllRegex = catchAll ? "(?!_next).*" : "";
+        var notApiRegex = FIRST_SEGMENT_DYNAMIC.test(normalizedRoute)
+          ? NOT_API_ROUTE
+          : "";
+        var catchAllRegex = catchAll ? "(?!_next($|/)).*" : "";
         var catchAllGroupedRegex = catchAll ? "(?:(/.*)?)" : "";
         if ("routeKeys" in result) {
           if (result.parameterizedRoute === "/") {
@@ -6834,10 +6910,12 @@
           return {
             groups: result.groups,
             namedRegex: "^"
+              .concat(notApiRegex)
               .concat(result.namedParameterizedRoute)
               .concat(catchAllGroupedRegex, "$"),
             re: new RegExp(
               "^"
+                .concat(notApiRegex)
                 .concat(result.parameterizedRoute)
                 .concat(catchAllGroupedRegex, "$")
             ),
@@ -6854,6 +6932,7 @@
           groups: {},
           re: new RegExp(
             "^"
+              .concat(notApiRegex)
               .concat(result.parameterizedRoute)
               .concat(catchAllGroupedRegex, "$")
           )
@@ -6891,6 +6970,18 @@
           return _routeRegex.getRouteRegex;
         }
       });
+      Object.defineProperty(exports, "getRoutingItems", {
+        enumerable: true,
+        get: function get() {
+          return _routingItems.getRoutingItems;
+        }
+      });
+      Object.defineProperty(exports, "RoutingItem", {
+        enumerable: true,
+        get: function get() {
+          return _routingItems.RoutingItem;
+        }
+      });
       Object.defineProperty(exports, "getSortedRoutes", {
         enumerable: true,
         get: function get() {
@@ -6906,6 +6997,7 @@
       var _getMiddlewareRegex = __webpack_require__(3072);
       var _routeMatcher = __webpack_require__(3156);
       var _routeRegex = __webpack_require__(4903);
+      var _routingItems = __webpack_require__(7185);
       var _sortedRoutes = __webpack_require__(566);
       var _isDynamic = __webpack_require__(6238); //# sourceMappingURL=index.js.map
 
@@ -7237,6 +7329,101 @@
       /***/
     },
 
+    /***/ 7185: /***/ function(
+      __unused_webpack_module,
+      exports,
+      __webpack_require__
+    ) {
+      "use strict";
+
+      function _arrayLikeToArray(arr, len) {
+        if (len == null || len > arr.length) len = arr.length;
+        for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
+        return arr2;
+      }
+      function _arrayWithoutHoles(arr) {
+        if (Array.isArray(arr)) return _arrayLikeToArray(arr);
+      }
+      function _iterableToArray(iter) {
+        if (
+          (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null) ||
+          iter["@@iterator"] != null
+        )
+          return Array.from(iter);
+      }
+      function _nonIterableSpread() {
+        throw new TypeError(
+          "Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."
+        );
+      }
+      function _toConsumableArray(arr) {
+        return (
+          _arrayWithoutHoles(arr) ||
+          _iterableToArray(arr) ||
+          _unsupportedIterableToArray(arr) ||
+          _nonIterableSpread()
+        );
+      }
+      function _unsupportedIterableToArray(o, minLen) {
+        if (!o) return;
+        if (typeof o === "string") return _arrayLikeToArray(o, minLen);
+        var n = Object.prototype.toString.call(o).slice(8, -1);
+        if (n === "Object" && o.constructor) n = o.constructor.name;
+        if (n === "Map" || n === "Set") return Array.from(n);
+        if (
+          n === "Arguments" ||
+          /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)
+        )
+          return _arrayLikeToArray(o, minLen);
+      }
+      Object.defineProperty(exports, "__esModule", {
+        value: true
+      });
+      exports.getRoutingItems = getRoutingItems;
+      var _getMiddlewareRegex = __webpack_require__(3072);
+      var _routeMatcher = __webpack_require__(3156);
+      var _routeRegex = __webpack_require__(4903);
+      var _sortedRoutes = __webpack_require__(566);
+      var MIDDLEWARE_SUFFIX = "/_middleware";
+      function getRoutingItems(pages, middleware) {
+        // append the suffix so that `getSortedRoutes()` can handle middleware properly
+        var middlewarePages = middleware.map(function(m) {
+          return "".concat(m.page).concat(MIDDLEWARE_SUFFIX);
+        });
+        var middlewareMap = new Map(
+          middleware.map(function(m) {
+            return [m.page, m];
+          })
+        );
+        var sortedRoutes = (0, _sortedRoutes).getSortedRoutes(
+          _toConsumableArray(pages).concat(_toConsumableArray(middlewarePages))
+        );
+        return sortedRoutes.map(function(page) {
+          if (page.endsWith(MIDDLEWARE_SUFFIX)) {
+            var p = page.slice(0, -MIDDLEWARE_SUFFIX.length) || "/";
+            var ssr = middlewareMap.get(p).ssr;
+            return {
+              match: (0, _routeMatcher).getRouteMatcher(
+                (0, _getMiddlewareRegex).getMiddlewareRegex(p, !ssr)
+              ),
+              page: p,
+              ssr: ssr,
+              isMiddleware: true
+            };
+          } else {
+            return {
+              match: (0, _routeMatcher).getRouteMatcher(
+                (0, _routeRegex).getRouteRegex(page)
+              ),
+              page: page
+            };
+          }
+        });
+      } //# sourceMappingURL=routing-items.js.map
+
+      /***/
+    },
+
     /***/ 566: /***/ function(__unused_webpack_module, exports) {
       "use strict";
 
@@ -7311,6 +7498,7 @@
           this.slugName = null;
           this.restSlugName = null;
           this.optionalRestSlugName = null;
+          this.isMiddleware = false;
         }
         _createClass(UrlNode, [
           {
@@ -7345,6 +7533,9 @@
               if (this.optionalRestSlugName !== null) {
                 childrenPaths.splice(childrenPaths.indexOf("[[...]]"), 1);
               }
+              if (this.isMiddleware) {
+                childrenPaths.splice(childrenPaths.indexOf("_middleware"), 1);
+              }
               var routes = childrenPaths
                 .map(function(c) {
                   return _this.children
@@ -7381,10 +7572,21 @@
                 }
                 routes.unshift(r);
               }
-              if (this.restSlugName !== null) {
+              if (this.isMiddleware) {
                 var _routes1;
-                (_routes1 = routes).push.apply(
+                (_routes1 = routes).unshift.apply(
                   _routes1,
+                  _toConsumableArray(
+                    this.children
+                      .get("_middleware")
+                      ._smoosh("".concat(prefix, "_middleware/"))
+                  )
+                );
+              }
+              if (this.restSlugName !== null) {
+                var _routes2;
+                (_routes2 = routes).push.apply(
+                  _routes2,
                   _toConsumableArray(
                     this.children
                       .get("[...]")
@@ -7397,9 +7599,9 @@
                 );
               }
               if (this.optionalRestSlugName !== null) {
-                var _routes2;
-                (_routes2 = routes).push.apply(
-                  _routes2,
+                var _routes3;
+                (_routes3 = routes).push.apply(
+                  _routes3,
                   _toConsumableArray(
                     this.children
                       .get("[[...]]")
@@ -7540,6 +7742,11 @@
                   // nextSegment is overwritten to [] so that it can later be sorted specifically
                   nextSegment = "[]";
                 }
+              } else if (
+                nextSegment === "_middleware" &&
+                urlPaths.length === 1
+              ) {
+                this.isMiddleware = true;
               }
               // If this UrlNode doesn't have the nextSegment yet we create a new child UrlNode
               if (!this.children.has(nextSegment)) {
Diff for index.html
@@ -19,7 +19,7 @@
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/main-356143d159a72188.js"
+      src="/_next/static/chunks/main-cfeed0cee0b9b860.js"
       defer=""
     ></script>
     <script
Diff for link.html
@@ -19,7 +19,7 @@
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/main-356143d159a72188.js"
+      src="/_next/static/chunks/main-cfeed0cee0b9b860.js"
       defer=""
     ></script>
     <script
Diff for withRouter.html
@@ -19,7 +19,7 @@
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/main-356143d159a72188.js"
+      src="/_next/static/chunks/main-cfeed0cee0b9b860.js"
       defer=""
     ></script>
     <script

Default Build with SWC (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
buildDuration 18.9s 18.9s -53ms
buildDurationCached 6.2s 6.1s -69ms
nodeModulesSize 467 MB 467 MB ⚠️ +9.67 kB
Page Load Tests Overall decrease ⚠️
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
/ failed reqs 0 0
/ total time (seconds) 2.969 2.977 ⚠️ +0.01
/ avg req/sec 842.13 839.66 ⚠️ -2.47
/error-in-render failed reqs 0 0
/error-in-render total time (seconds) 1.198 1.2 0
/error-in-render avg req/sec 2086.37 2083.16 ⚠️ -3.21
Client Bundles (main, webpack) Overall increase ⚠️
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
925.HASH.js gzip 178 B 178 B
framework-HASH.js gzip 42.3 kB 42.3 kB
main-HASH.js gzip 28.2 kB 28.8 kB ⚠️ +529 B
webpack-HASH.js gzip 1.45 kB 1.45 kB
Overall change 72.1 kB 72.7 kB ⚠️ +529 B
Legacy Client Bundles (polyfills)
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
polyfills-HASH.js gzip 31 kB 31 kB
Overall change 31 kB 31 kB
Client Pages
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
_app-HASH.js gzip 1.35 kB 1.35 kB
_error-HASH.js gzip 179 B 179 B
amp-HASH.js gzip 313 B 313 B
css-HASH.js gzip 324 B 324 B
dynamic-HASH.js gzip 2.56 kB 2.56 kB
head-HASH.js gzip 351 B 351 B
hooks-HASH.js gzip 921 B 921 B
image-HASH.js gzip 5.59 kB 5.59 kB
index-HASH.js gzip 261 B 261 B
link-HASH.js gzip 2.33 kB 2.33 kB
routerDirect..HASH.js gzip 322 B 322 B
script-HASH.js gzip 388 B 388 B
withRouter-HASH.js gzip 317 B 317 B
85e02e95b279..7e3.css gzip 107 B 107 B
Overall change 15.3 kB 15.3 kB
Client Build Manifests
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
_buildManifest.js gzip 458 B 458 B
Overall change 458 B 458 B
Rendered Page Sizes Overall increase ⚠️
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
index.html gzip 531 B 532 B ⚠️ +1 B
link.html gzip 546 B 546 B
withRouter.html gzip 527 B 527 B
Overall change 1.6 kB 1.6 kB ⚠️ +1 B

Diffs

Diff for main-HASH.js
@@ -473,7 +473,7 @@
       var _routeAnnouncer = __webpack_require__(8483);
       var _router1 = __webpack_require__(880);
       var _isError = __webpack_require__(676);
-      var _vitals = __webpack_require__(7185);
+      var _vitals = __webpack_require__(4564);
       var _refresh = __webpack_require__(2129);
       var _imageConfigContext = __webpack_require__(8730);
       function asyncGeneratorStep(
@@ -3197,7 +3197,7 @@
       /***/
     },
 
-    /***/ 7185: /***/ function(
+    /***/ 4564: /***/ function(
       __unused_webpack_module,
       exports,
       __webpack_require__
@@ -4351,8 +4351,8 @@
       var _resolveRewrites = _interopRequireDefault1(__webpack_require__(2431));
       var _routeMatcher = __webpack_require__(3156);
       var _routeRegex = __webpack_require__(4903);
-      var _getMiddlewareRegex = __webpack_require__(3072);
       var _formatUrl = __webpack_require__(7795);
+      var _routingItems = __webpack_require__(7185);
       function _interopRequireDefault1(obj) {
         return obj && obj.__esModule
           ? obj
@@ -6378,8 +6378,16 @@
                 _runtimeJs.default.mark(function _callee() {
                   var asPathname,
                     cleanedAs,
-                    fns,
+                    middlewareList,
+                    middleware,
+                    routingItems,
                     requiresPreflight,
+                    _iteratorNormalCompletion,
+                    _didIteratorError,
+                    _iteratorError,
+                    _iterator,
+                    _step,
+                    item,
                     preflight,
                     parsed,
                     fsPathname,
@@ -6404,58 +6412,116 @@
                             _ctx.next = 4;
                             return _this.pageLoader.getMiddlewareList();
                           case 4:
-                            fns = _ctx.sent;
-                            requiresPreflight = fns.some(function(param) {
+                            middlewareList = _ctx.sent;
+                            middleware = middlewareList.map(function(param) {
                               var _param = _slicedToArray(param, 2),
-                                middleware = _param[0],
-                                isSSR = _param[1];
-                              return (0, _routeMatcher).getRouteMatcher(
-                                (0, _getMiddlewareRegex).getMiddlewareRegex(
-                                  middleware,
-                                  !isSSR
-                                )
-                              )(cleanedAs);
+                                page = _param[0],
+                                ssr = _param[1];
+                              return {
+                                page: page,
+                                ssr: ssr
+                              };
                             });
+                            routingItems = (0, _routingItems).getRoutingItems(
+                              options.pages,
+                              middleware
+                            );
+                            requiresPreflight = false;
+                            (_iteratorNormalCompletion = true),
+                              (_didIteratorError = false),
+                              (_iteratorError = undefined);
+                            _ctx.prev = 9;
+                            _iterator = routingItems[Symbol.iterator]();
+                          case 11:
+                            if (
+                              (_iteratorNormalCompletion = (_step = _iterator.next())
+                                .done)
+                            ) {
+                              _ctx.next = 19;
+                              break;
+                            }
+                            item = _step.value;
+                            if (!item.match(cleanedAs)) {
+                              _ctx.next = 16;
+                              break;
+                            }
+                            if (item.isMiddleware) {
+                              requiresPreflight = true;
+                            }
+                            return _ctx.abrupt("break", 19);
+                          case 16:
+                            _iteratorNormalCompletion = true;
+                            _ctx.next = 11;
+                            break;
+                          case 19:
+                            _ctx.next = 25;
+                            break;
+                          case 21:
+                            _ctx.prev = 21;
+                            _ctx.t0 = _ctx["catch"](9);
+                            _didIteratorError = true;
+                            _iteratorError = _ctx.t0;
+                          case 25:
+                            _ctx.prev = 25;
+                            _ctx.prev = 26;
+                            if (
+                              !_iteratorNormalCompletion &&
+                              _iterator.return != null
+                            ) {
+                              _iterator.return();
+                            }
+                          case 28:
+                            _ctx.prev = 28;
+                            if (!_didIteratorError) {
+                              _ctx.next = 31;
+                              break;
+                            }
+                            throw _iteratorError;
+                          case 31:
+                            return _ctx.finish(28);
+                          case 32:
+                            return _ctx.finish(25);
+                          case 33:
                             if (requiresPreflight) {
-                              _ctx.next = 8;
+                              _ctx.next = 35;
                               break;
                             }
                             return _ctx.abrupt("return", {
                               type: "next"
                             });
-                          case 8:
-                            _ctx.prev = 9;
-                            _ctx.next = 12;
+                          case 35:
+                            _ctx.prev = 36;
+                            _ctx.next = 39;
                             return _this._getPreflightData({
                               preflightHref: options.as,
                               shouldCache: options.cache,
                               isPreview: options.isPreview
                             });
-                          case 12:
+                          case 39:
                             preflight = _ctx.sent;
-                            _ctx.next = 18;
+                            _ctx.next = 45;
                             break;
-                          case 15:
-                            _ctx.prev = 15;
-                            _ctx.t0 = _ctx["catch"](9);
+                          case 42:
+                            _ctx.prev = 42;
+                            _ctx.t1 = _ctx["catch"](36);
                             return _ctx.abrupt("return", {
                               type: "redirect",
                               destination: options.as
                             });
-                          case 18:
+                          case 45:
                             if (!preflight.rewrite) {
-                              _ctx.next = 27;
+                              _ctx.next = 54;
                               break;
                             }
                             if (preflight.rewrite.startsWith("/")) {
-                              _ctx.next = 21;
+                              _ctx.next = 48;
                               break;
                             }
                             return _ctx.abrupt("return", {
                               type: "redirect",
                               destination: options.as
                             });
-                          case 21:
+                          case 48:
                             parsed = (0, _parseRelativeUrl).parseRelativeUrl(
                               (0, _normalizeLocalePath).normalizeLocalePath(
                                 hasBasePath(preflight.rewrite)
@@ -6490,13 +6556,13 @@
                               matchedPage: matchedPage,
                               resolvedHref: resolvedHref
                             });
-                          case 27:
+                          case 54:
                             if (!preflight.redirect) {
-                              _ctx.next = 33;
+                              _ctx.next = 60;
                               break;
                             }
                             if (!preflight.redirect.startsWith("/")) {
-                              _ctx.next = 32;
+                              _ctx.next = 59;
                               break;
                             }
                             cleanRedirect = (0,
@@ -6520,31 +6586,35 @@
                               newUrl: newUrl,
                               newAs: newAs
                             });
-                          case 32:
+                          case 59:
                             return _ctx.abrupt("return", {
                               type: "redirect",
                               destination: preflight.redirect
                             });
-                          case 33:
+                          case 60:
                             if (!(preflight.refresh && !preflight.ssr)) {
-                              _ctx.next = 35;
+                              _ctx.next = 62;
                               break;
                             }
                             return _ctx.abrupt("return", {
                               type: "refresh"
                             });
-                          case 35:
+                          case 62:
                             return _ctx.abrupt("return", {
                               type: "next"
                             });
-                          case 36:
+                          case 63:
                           case "end":
                             return _ctx.stop();
                         }
                     },
                     _callee,
                     null,
-                    [[9, 15]]
+                    [
+                      [9, 21, 25, 33],
+                      [26, , 28, 32],
+                      [36, 42]
+                    ]
                   );
                 })
               )();
@@ -6816,11 +6886,17 @@
       });
       exports.getMiddlewareRegex = getMiddlewareRegex;
       var _routeRegex = __webpack_require__(4903);
+      // Identify ^/[param]/ in route string
+      var FIRST_SEGMENT_DYNAMIC = /^\/\[[^/]+?\](?=\/|$)/;
+      var NOT_API_ROUTE = "(?!/api(?:/|$))";
       function getMiddlewareRegex(normalizedRoute) {
         var catchAll =
           arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : true;
         var result = (0, _routeRegex).getParametrizedRoute(normalizedRoute);
-        var catchAllRegex = catchAll ? "(?!_next).*" : "";
+        var notApiRegex = FIRST_SEGMENT_DYNAMIC.test(normalizedRoute)
+          ? NOT_API_ROUTE
+          : "";
+        var catchAllRegex = catchAll ? "(?!_next($|/)).*" : "";
         var catchAllGroupedRegex = catchAll ? "(?:(/.*)?)" : "";
         if ("routeKeys" in result) {
           if (result.parameterizedRoute === "/") {
@@ -6834,10 +6910,12 @@
           return {
             groups: result.groups,
             namedRegex: "^"
+              .concat(notApiRegex)
               .concat(result.namedParameterizedRoute)
               .concat(catchAllGroupedRegex, "$"),
             re: new RegExp(
               "^"
+                .concat(notApiRegex)
                 .concat(result.parameterizedRoute)
                 .concat(catchAllGroupedRegex, "$")
             ),
@@ -6854,6 +6932,7 @@
           groups: {},
           re: new RegExp(
             "^"
+              .concat(notApiRegex)
               .concat(result.parameterizedRoute)
               .concat(catchAllGroupedRegex, "$")
           )
@@ -6891,6 +6970,18 @@
           return _routeRegex.getRouteRegex;
         }
       });
+      Object.defineProperty(exports, "getRoutingItems", {
+        enumerable: true,
+        get: function get() {
+          return _routingItems.getRoutingItems;
+        }
+      });
+      Object.defineProperty(exports, "RoutingItem", {
+        enumerable: true,
+        get: function get() {
+          return _routingItems.RoutingItem;
+        }
+      });
       Object.defineProperty(exports, "getSortedRoutes", {
         enumerable: true,
         get: function get() {
@@ -6906,6 +6997,7 @@
       var _getMiddlewareRegex = __webpack_require__(3072);
       var _routeMatcher = __webpack_require__(3156);
       var _routeRegex = __webpack_require__(4903);
+      var _routingItems = __webpack_require__(7185);
       var _sortedRoutes = __webpack_require__(566);
       var _isDynamic = __webpack_require__(6238); //# sourceMappingURL=index.js.map
 
@@ -7237,6 +7329,101 @@
       /***/
     },
 
+    /***/ 7185: /***/ function(
+      __unused_webpack_module,
+      exports,
+      __webpack_require__
+    ) {
+      "use strict";
+
+      function _arrayLikeToArray(arr, len) {
+        if (len == null || len > arr.length) len = arr.length;
+        for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
+        return arr2;
+      }
+      function _arrayWithoutHoles(arr) {
+        if (Array.isArray(arr)) return _arrayLikeToArray(arr);
+      }
+      function _iterableToArray(iter) {
+        if (
+          (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null) ||
+          iter["@@iterator"] != null
+        )
+          return Array.from(iter);
+      }
+      function _nonIterableSpread() {
+        throw new TypeError(
+          "Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."
+        );
+      }
+      function _toConsumableArray(arr) {
+        return (
+          _arrayWithoutHoles(arr) ||
+          _iterableToArray(arr) ||
+          _unsupportedIterableToArray(arr) ||
+          _nonIterableSpread()
+        );
+      }
+      function _unsupportedIterableToArray(o, minLen) {
+        if (!o) return;
+        if (typeof o === "string") return _arrayLikeToArray(o, minLen);
+        var n = Object.prototype.toString.call(o).slice(8, -1);
+        if (n === "Object" && o.constructor) n = o.constructor.name;
+        if (n === "Map" || n === "Set") return Array.from(n);
+        if (
+          n === "Arguments" ||
+          /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)
+        )
+          return _arrayLikeToArray(o, minLen);
+      }
+      Object.defineProperty(exports, "__esModule", {
+        value: true
+      });
+      exports.getRoutingItems = getRoutingItems;
+      var _getMiddlewareRegex = __webpack_require__(3072);
+      var _routeMatcher = __webpack_require__(3156);
+      var _routeRegex = __webpack_require__(4903);
+      var _sortedRoutes = __webpack_require__(566);
+      var MIDDLEWARE_SUFFIX = "/_middleware";
+      function getRoutingItems(pages, middleware) {
+        // append the suffix so that `getSortedRoutes()` can handle middleware properly
+        var middlewarePages = middleware.map(function(m) {
+          return "".concat(m.page).concat(MIDDLEWARE_SUFFIX);
+        });
+        var middlewareMap = new Map(
+          middleware.map(function(m) {
+            return [m.page, m];
+          })
+        );
+        var sortedRoutes = (0, _sortedRoutes).getSortedRoutes(
+          _toConsumableArray(pages).concat(_toConsumableArray(middlewarePages))
+        );
+        return sortedRoutes.map(function(page) {
+          if (page.endsWith(MIDDLEWARE_SUFFIX)) {
+            var p = page.slice(0, -MIDDLEWARE_SUFFIX.length) || "/";
+            var ssr = middlewareMap.get(p).ssr;
+            return {
+              match: (0, _routeMatcher).getRouteMatcher(
+                (0, _getMiddlewareRegex).getMiddlewareRegex(p, !ssr)
+              ),
+              page: p,
+              ssr: ssr,
+              isMiddleware: true
+            };
+          } else {
+            return {
+              match: (0, _routeMatcher).getRouteMatcher(
+                (0, _routeRegex).getRouteRegex(page)
+              ),
+              page: page
+            };
+          }
+        });
+      } //# sourceMappingURL=routing-items.js.map
+
+      /***/
+    },
+
     /***/ 566: /***/ function(__unused_webpack_module, exports) {
       "use strict";
 
@@ -7311,6 +7498,7 @@
           this.slugName = null;
           this.restSlugName = null;
           this.optionalRestSlugName = null;
+          this.isMiddleware = false;
         }
         _createClass(UrlNode, [
           {
@@ -7345,6 +7533,9 @@
               if (this.optionalRestSlugName !== null) {
                 childrenPaths.splice(childrenPaths.indexOf("[[...]]"), 1);
               }
+              if (this.isMiddleware) {
+                childrenPaths.splice(childrenPaths.indexOf("_middleware"), 1);
+              }
               var routes = childrenPaths
                 .map(function(c) {
                   return _this.children
@@ -7381,10 +7572,21 @@
                 }
                 routes.unshift(r);
               }
-              if (this.restSlugName !== null) {
+              if (this.isMiddleware) {
                 var _routes1;
-                (_routes1 = routes).push.apply(
+                (_routes1 = routes).unshift.apply(
                   _routes1,
+                  _toConsumableArray(
+                    this.children
+                      .get("_middleware")
+                      ._smoosh("".concat(prefix, "_middleware/"))
+                  )
+                );
+              }
+              if (this.restSlugName !== null) {
+                var _routes2;
+                (_routes2 = routes).push.apply(
+                  _routes2,
                   _toConsumableArray(
                     this.children
                       .get("[...]")
@@ -7397,9 +7599,9 @@
                 );
               }
               if (this.optionalRestSlugName !== null) {
-                var _routes2;
-                (_routes2 = routes).push.apply(
-                  _routes2,
+                var _routes3;
+                (_routes3 = routes).push.apply(
+                  _routes3,
                   _toConsumableArray(
                     this.children
                       .get("[[...]]")
@@ -7540,6 +7742,11 @@
                   // nextSegment is overwritten to [] so that it can later be sorted specifically
                   nextSegment = "[]";
                 }
+              } else if (
+                nextSegment === "_middleware" &&
+                urlPaths.length === 1
+              ) {
+                this.isMiddleware = true;
               }
               // If this UrlNode doesn't have the nextSegment yet we create a new child UrlNode
               if (!this.children.has(nextSegment)) {
Diff for index.html
@@ -19,7 +19,7 @@
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/main-356143d159a72188.js"
+      src="/_next/static/chunks/main-cfeed0cee0b9b860.js"
       defer=""
     ></script>
     <script
Diff for link.html
@@ -19,7 +19,7 @@
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/main-356143d159a72188.js"
+      src="/_next/static/chunks/main-cfeed0cee0b9b860.js"
       defer=""
     ></script>
     <script
Diff for withRouter.html
@@ -19,7 +19,7 @@
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/main-356143d159a72188.js"
+      src="/_next/static/chunks/main-cfeed0cee0b9b860.js"
       defer=""
     ></script>
     <script
Commit: 4900888

@ijjk
Copy link
Member

ijjk commented Mar 28, 2022

Stats from current PR

Default Build (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
buildDuration 17s 16.6s -413ms
buildDurationCached 6.5s 6.5s ⚠️ +50ms
nodeModulesSize 467 MB 467 MB ⚠️ +9.67 kB
Page Load Tests Overall decrease ⚠️
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
/ failed reqs 0 0
/ total time (seconds) 3.402 3.417 ⚠️ +0.01
/ avg req/sec 734.87 731.57 ⚠️ -3.3
/error-in-render failed reqs 0 0
/error-in-render total time (seconds) 1.438 1.58 ⚠️ +0.14
/error-in-render avg req/sec 1738.13 1581.8 ⚠️ -156.33
Client Bundles (main, webpack) Overall increase ⚠️
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
925.HASH.js gzip 179 B 179 B
framework-HASH.js gzip 42 kB 42 kB
main-HASH.js gzip 28 kB 28.4 kB ⚠️ +489 B
webpack-HASH.js gzip 1.44 kB 1.44 kB
Overall change 71.6 kB 72.1 kB ⚠️ +489 B
Legacy Client Bundles (polyfills)
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
polyfills-HASH.js gzip 31 kB 31 kB
Overall change 31 kB 31 kB
Client Pages
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
_app-HASH.js gzip 1.36 kB 1.36 kB
_error-HASH.js gzip 192 B 192 B
amp-HASH.js gzip 309 B 309 B
css-HASH.js gzip 327 B 327 B
dynamic-HASH.js gzip 2.57 kB 2.57 kB
head-HASH.js gzip 351 B 351 B
hooks-HASH.js gzip 920 B 920 B
image-HASH.js gzip 5.48 kB 5.48 kB
index-HASH.js gzip 263 B 263 B
link-HASH.js gzip 2.26 kB 2.26 kB
routerDirect..HASH.js gzip 320 B 320 B
script-HASH.js gzip 387 B 387 B
withRouter-HASH.js gzip 319 B 319 B
85e02e95b279..7e3.css gzip 107 B 107 B
Overall change 15.2 kB 15.2 kB
Client Build Manifests
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
_buildManifest.js gzip 460 B 460 B
Overall change 460 B 460 B
Rendered Page Sizes
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
index.html gzip 531 B 530 B -1 B
link.html gzip 544 B 545 B ⚠️ +1 B
withRouter.html gzip 525 B 525 B
Overall change 1.6 kB 1.6 kB

Diffs

Diff for main-HASH.js
@@ -473,7 +473,7 @@
       var _routeAnnouncer = __webpack_require__(8483);
       var _router1 = __webpack_require__(880);
       var _isError = __webpack_require__(676);
-      var _vitals = __webpack_require__(7185);
+      var _vitals = __webpack_require__(4564);
       var _refresh = __webpack_require__(2129);
       var _imageConfigContext = __webpack_require__(8730);
       function asyncGeneratorStep(
@@ -3197,7 +3197,7 @@
       /***/
     },
 
-    /***/ 7185: /***/ function(
+    /***/ 4564: /***/ function(
       __unused_webpack_module,
       exports,
       __webpack_require__
@@ -4351,8 +4351,8 @@
       var _resolveRewrites = _interopRequireDefault1(__webpack_require__(2431));
       var _routeMatcher = __webpack_require__(3156);
       var _routeRegex = __webpack_require__(4903);
-      var _getMiddlewareRegex = __webpack_require__(3072);
       var _formatUrl = __webpack_require__(7795);
+      var _routingItems = __webpack_require__(7185);
       function _interopRequireDefault1(obj) {
         return obj && obj.__esModule
           ? obj
@@ -6378,8 +6378,16 @@
                 _runtimeJs.default.mark(function _callee() {
                   var asPathname,
                     cleanedAs,
-                    fns,
+                    middlewareList,
+                    middleware,
+                    routingItems,
                     requiresPreflight,
+                    _iteratorNormalCompletion,
+                    _didIteratorError,
+                    _iteratorError,
+                    _iterator,
+                    _step,
+                    item,
                     preflight,
                     parsed,
                     fsPathname,
@@ -6404,58 +6412,116 @@
                             _ctx.next = 4;
                             return _this.pageLoader.getMiddlewareList();
                           case 4:
-                            fns = _ctx.sent;
-                            requiresPreflight = fns.some(function(param) {
+                            middlewareList = _ctx.sent;
+                            middleware = middlewareList.map(function(param) {
                               var _param = _slicedToArray(param, 2),
-                                middleware = _param[0],
-                                isSSR = _param[1];
-                              return (0, _routeMatcher).getRouteMatcher(
-                                (0, _getMiddlewareRegex).getMiddlewareRegex(
-                                  middleware,
-                                  !isSSR
-                                )
-                              )(cleanedAs);
+                                page = _param[0],
+                                ssr = _param[1];
+                              return {
+                                page: page,
+                                ssr: ssr
+                              };
                             });
+                            routingItems = (0, _routingItems).getRoutingItems(
+                              options.pages,
+                              middleware
+                            );
+                            requiresPreflight = false;
+                            (_iteratorNormalCompletion = true),
+                              (_didIteratorError = false),
+                              (_iteratorError = undefined);
+                            _ctx.prev = 9;
+                            _iterator = routingItems[Symbol.iterator]();
+                          case 11:
+                            if (
+                              (_iteratorNormalCompletion = (_step = _iterator.next())
+                                .done)
+                            ) {
+                              _ctx.next = 19;
+                              break;
+                            }
+                            item = _step.value;
+                            if (!item.match(cleanedAs)) {
+                              _ctx.next = 16;
+                              break;
+                            }
+                            if (item.isMiddleware) {
+                              requiresPreflight = true;
+                            }
+                            return _ctx.abrupt("break", 19);
+                          case 16:
+                            _iteratorNormalCompletion = true;
+                            _ctx.next = 11;
+                            break;
+                          case 19:
+                            _ctx.next = 25;
+                            break;
+                          case 21:
+                            _ctx.prev = 21;
+                            _ctx.t0 = _ctx["catch"](9);
+                            _didIteratorError = true;
+                            _iteratorError = _ctx.t0;
+                          case 25:
+                            _ctx.prev = 25;
+                            _ctx.prev = 26;
+                            if (
+                              !_iteratorNormalCompletion &&
+                              _iterator.return != null
+                            ) {
+                              _iterator.return();
+                            }
+                          case 28:
+                            _ctx.prev = 28;
+                            if (!_didIteratorError) {
+                              _ctx.next = 31;
+                              break;
+                            }
+                            throw _iteratorError;
+                          case 31:
+                            return _ctx.finish(28);
+                          case 32:
+                            return _ctx.finish(25);
+                          case 33:
                             if (requiresPreflight) {
-                              _ctx.next = 8;
+                              _ctx.next = 35;
                               break;
                             }
                             return _ctx.abrupt("return", {
                               type: "next"
                             });
-                          case 8:
-                            _ctx.prev = 9;
-                            _ctx.next = 12;
+                          case 35:
+                            _ctx.prev = 36;
+                            _ctx.next = 39;
                             return _this._getPreflightData({
                               preflightHref: options.as,
                               shouldCache: options.cache,
                               isPreview: options.isPreview
                             });
-                          case 12:
+                          case 39:
                             preflight = _ctx.sent;
-                            _ctx.next = 18;
+                            _ctx.next = 45;
                             break;
-                          case 15:
-                            _ctx.prev = 15;
-                            _ctx.t0 = _ctx["catch"](9);
+                          case 42:
+                            _ctx.prev = 42;
+                            _ctx.t1 = _ctx["catch"](36);
                             return _ctx.abrupt("return", {
                               type: "redirect",
                               destination: options.as
                             });
-                          case 18:
+                          case 45:
                             if (!preflight.rewrite) {
-                              _ctx.next = 27;
+                              _ctx.next = 54;
                               break;
                             }
                             if (preflight.rewrite.startsWith("/")) {
-                              _ctx.next = 21;
+                              _ctx.next = 48;
                               break;
                             }
                             return _ctx.abrupt("return", {
                               type: "redirect",
                               destination: options.as
                             });
-                          case 21:
+                          case 48:
                             parsed = (0, _parseRelativeUrl).parseRelativeUrl(
                               (0, _normalizeLocalePath).normalizeLocalePath(
                                 hasBasePath(preflight.rewrite)
@@ -6490,13 +6556,13 @@
                               matchedPage: matchedPage,
                               resolvedHref: resolvedHref
                             });
-                          case 27:
+                          case 54:
                             if (!preflight.redirect) {
-                              _ctx.next = 33;
+                              _ctx.next = 60;
                               break;
                             }
                             if (!preflight.redirect.startsWith("/")) {
-                              _ctx.next = 32;
+                              _ctx.next = 59;
                               break;
                             }
                             cleanRedirect = (0,
@@ -6520,31 +6586,35 @@
                               newUrl: newUrl,
                               newAs: newAs
                             });
-                          case 32:
+                          case 59:
                             return _ctx.abrupt("return", {
                               type: "redirect",
                               destination: preflight.redirect
                             });
-                          case 33:
+                          case 60:
                             if (!(preflight.refresh && !preflight.ssr)) {
-                              _ctx.next = 35;
+                              _ctx.next = 62;
                               break;
                             }
                             return _ctx.abrupt("return", {
                               type: "refresh"
                             });
-                          case 35:
+                          case 62:
                             return _ctx.abrupt("return", {
                               type: "next"
                             });
-                          case 36:
+                          case 63:
                           case "end":
                             return _ctx.stop();
                         }
                     },
                     _callee,
                     null,
-                    [[9, 15]]
+                    [
+                      [9, 21, 25, 33],
+                      [26, , 28, 32],
+                      [36, 42]
+                    ]
                   );
                 })
               )();
@@ -6816,11 +6886,17 @@
       });
       exports.getMiddlewareRegex = getMiddlewareRegex;
       var _routeRegex = __webpack_require__(4903);
+      // Identify ^/[param]/ in route string
+      var FIRST_SEGMENT_DYNAMIC = /^\/\[[^/]+?\](?=\/|$)/;
+      var NOT_API_ROUTE = "(?!/api(?:/|$))";
       function getMiddlewareRegex(normalizedRoute) {
         var catchAll =
           arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : true;
         var result = (0, _routeRegex).getParametrizedRoute(normalizedRoute);
-        var catchAllRegex = catchAll ? "(?!_next).*" : "";
+        var notApiRegex = FIRST_SEGMENT_DYNAMIC.test(normalizedRoute)
+          ? NOT_API_ROUTE
+          : "";
+        var catchAllRegex = catchAll ? "(?!_next($|/)).*" : "";
         var catchAllGroupedRegex = catchAll ? "(?:(/.*)?)" : "";
         if ("routeKeys" in result) {
           if (result.parameterizedRoute === "/") {
@@ -6834,10 +6910,12 @@
           return {
             groups: result.groups,
             namedRegex: "^"
+              .concat(notApiRegex)
               .concat(result.namedParameterizedRoute)
               .concat(catchAllGroupedRegex, "$"),
             re: new RegExp(
               "^"
+                .concat(notApiRegex)
                 .concat(result.parameterizedRoute)
                 .concat(catchAllGroupedRegex, "$")
             ),
@@ -6854,6 +6932,7 @@
           groups: {},
           re: new RegExp(
             "^"
+              .concat(notApiRegex)
               .concat(result.parameterizedRoute)
               .concat(catchAllGroupedRegex, "$")
           )
@@ -6891,6 +6970,18 @@
           return _routeRegex.getRouteRegex;
         }
       });
+      Object.defineProperty(exports, "getRoutingItems", {
+        enumerable: true,
+        get: function get() {
+          return _routingItems.getRoutingItems;
+        }
+      });
+      Object.defineProperty(exports, "RoutingItem", {
+        enumerable: true,
+        get: function get() {
+          return _routingItems.RoutingItem;
+        }
+      });
       Object.defineProperty(exports, "getSortedRoutes", {
         enumerable: true,
         get: function get() {
@@ -6906,6 +6997,7 @@
       var _getMiddlewareRegex = __webpack_require__(3072);
       var _routeMatcher = __webpack_require__(3156);
       var _routeRegex = __webpack_require__(4903);
+      var _routingItems = __webpack_require__(7185);
       var _sortedRoutes = __webpack_require__(566);
       var _isDynamic = __webpack_require__(6238); //# sourceMappingURL=index.js.map
 
@@ -7237,6 +7329,101 @@
       /***/
     },
 
+    /***/ 7185: /***/ function(
+      __unused_webpack_module,
+      exports,
+      __webpack_require__
+    ) {
+      "use strict";
+
+      function _arrayLikeToArray(arr, len) {
+        if (len == null || len > arr.length) len = arr.length;
+        for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
+        return arr2;
+      }
+      function _arrayWithoutHoles(arr) {
+        if (Array.isArray(arr)) return _arrayLikeToArray(arr);
+      }
+      function _iterableToArray(iter) {
+        if (
+          (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null) ||
+          iter["@@iterator"] != null
+        )
+          return Array.from(iter);
+      }
+      function _nonIterableSpread() {
+        throw new TypeError(
+          "Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."
+        );
+      }
+      function _toConsumableArray(arr) {
+        return (
+          _arrayWithoutHoles(arr) ||
+          _iterableToArray(arr) ||
+          _unsupportedIterableToArray(arr) ||
+          _nonIterableSpread()
+        );
+      }
+      function _unsupportedIterableToArray(o, minLen) {
+        if (!o) return;
+        if (typeof o === "string") return _arrayLikeToArray(o, minLen);
+        var n = Object.prototype.toString.call(o).slice(8, -1);
+        if (n === "Object" && o.constructor) n = o.constructor.name;
+        if (n === "Map" || n === "Set") return Array.from(n);
+        if (
+          n === "Arguments" ||
+          /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)
+        )
+          return _arrayLikeToArray(o, minLen);
+      }
+      Object.defineProperty(exports, "__esModule", {
+        value: true
+      });
+      exports.getRoutingItems = getRoutingItems;
+      var _getMiddlewareRegex = __webpack_require__(3072);
+      var _routeMatcher = __webpack_require__(3156);
+      var _routeRegex = __webpack_require__(4903);
+      var _sortedRoutes = __webpack_require__(566);
+      var MIDDLEWARE_SUFFIX = "/_middleware";
+      function getRoutingItems(pages, middleware) {
+        // append the suffix so that `getSortedRoutes()` can handle middleware properly
+        var middlewarePages = middleware.map(function(m) {
+          return "".concat(m.page).concat(MIDDLEWARE_SUFFIX);
+        });
+        var middlewareMap = new Map(
+          middleware.map(function(m) {
+            return [m.page, m];
+          })
+        );
+        var sortedRoutes = (0, _sortedRoutes).getSortedRoutes(
+          _toConsumableArray(pages).concat(_toConsumableArray(middlewarePages))
+        );
+        return sortedRoutes.map(function(page) {
+          if (page.endsWith(MIDDLEWARE_SUFFIX)) {
+            var p = page.slice(0, -MIDDLEWARE_SUFFIX.length) || "/";
+            var ssr = middlewareMap.get(p).ssr;
+            return {
+              match: (0, _routeMatcher).getRouteMatcher(
+                (0, _getMiddlewareRegex).getMiddlewareRegex(p, !ssr)
+              ),
+              page: p,
+              ssr: ssr,
+              isMiddleware: true
+            };
+          } else {
+            return {
+              match: (0, _routeMatcher).getRouteMatcher(
+                (0, _routeRegex).getRouteRegex(page)
+              ),
+              page: page
+            };
+          }
+        });
+      } //# sourceMappingURL=routing-items.js.map
+
+      /***/
+    },
+
     /***/ 566: /***/ function(__unused_webpack_module, exports) {
       "use strict";
 
@@ -7311,6 +7498,7 @@
           this.slugName = null;
           this.restSlugName = null;
           this.optionalRestSlugName = null;
+          this.isMiddleware = false;
         }
         _createClass(UrlNode, [
           {
@@ -7345,6 +7533,9 @@
               if (this.optionalRestSlugName !== null) {
                 childrenPaths.splice(childrenPaths.indexOf("[[...]]"), 1);
               }
+              if (this.isMiddleware) {
+                childrenPaths.splice(childrenPaths.indexOf("_middleware"), 1);
+              }
               var routes = childrenPaths
                 .map(function(c) {
                   return _this.children
@@ -7381,10 +7572,21 @@
                 }
                 routes.unshift(r);
               }
-              if (this.restSlugName !== null) {
+              if (this.isMiddleware) {
                 var _routes1;
-                (_routes1 = routes).push.apply(
+                (_routes1 = routes).unshift.apply(
                   _routes1,
+                  _toConsumableArray(
+                    this.children
+                      .get("_middleware")
+                      ._smoosh("".concat(prefix, "_middleware/"))
+                  )
+                );
+              }
+              if (this.restSlugName !== null) {
+                var _routes2;
+                (_routes2 = routes).push.apply(
+                  _routes2,
                   _toConsumableArray(
                     this.children
                       .get("[...]")
@@ -7397,9 +7599,9 @@
                 );
               }
               if (this.optionalRestSlugName !== null) {
-                var _routes2;
-                (_routes2 = routes).push.apply(
-                  _routes2,
+                var _routes3;
+                (_routes3 = routes).push.apply(
+                  _routes3,
                   _toConsumableArray(
                     this.children
                       .get("[[...]]")
@@ -7540,6 +7742,11 @@
                   // nextSegment is overwritten to [] so that it can later be sorted specifically
                   nextSegment = "[]";
                 }
+              } else if (
+                nextSegment === "_middleware" &&
+                urlPaths.length === 1
+              ) {
+                this.isMiddleware = true;
               }
               // If this UrlNode doesn't have the nextSegment yet we create a new child UrlNode
               if (!this.children.has(nextSegment)) {
Diff for index.html
@@ -19,7 +19,7 @@
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/main-4519db47b727e3b6.js"
+      src="/_next/static/chunks/main-24bf6d59775add36.js"
       defer=""
     ></script>
     <script
Diff for link.html
@@ -19,7 +19,7 @@
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/main-4519db47b727e3b6.js"
+      src="/_next/static/chunks/main-24bf6d59775add36.js"
       defer=""
     ></script>
     <script
Diff for withRouter.html
@@ -19,7 +19,7 @@
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/main-4519db47b727e3b6.js"
+      src="/_next/static/chunks/main-24bf6d59775add36.js"
       defer=""
     ></script>
     <script

Default Build with SWC (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
buildDuration 19.8s 19.5s -310ms
buildDurationCached 6.6s 6.5s -130ms
nodeModulesSize 467 MB 467 MB ⚠️ +9.67 kB
Page Load Tests Overall decrease ⚠️
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
/ failed reqs 0 0
/ total time (seconds) 3.378 3.375 0
/ avg req/sec 740.12 740.69 +0.57
/error-in-render failed reqs 0 0
/error-in-render total time (seconds) 1.497 1.527 ⚠️ +0.03
/error-in-render avg req/sec 1670.06 1637.72 ⚠️ -32.34
Client Bundles (main, webpack) Overall increase ⚠️
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
925.HASH.js gzip 178 B 178 B
framework-HASH.js gzip 42.3 kB 42.3 kB
main-HASH.js gzip 28.2 kB 28.8 kB ⚠️ +530 B
webpack-HASH.js gzip 1.45 kB 1.45 kB
Overall change 72.1 kB 72.7 kB ⚠️ +530 B
Legacy Client Bundles (polyfills)
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
polyfills-HASH.js gzip 31 kB 31 kB
Overall change 31 kB 31 kB
Client Pages
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
_app-HASH.js gzip 1.35 kB 1.35 kB
_error-HASH.js gzip 179 B 179 B
amp-HASH.js gzip 313 B 313 B
css-HASH.js gzip 324 B 324 B
dynamic-HASH.js gzip 2.56 kB 2.56 kB
head-HASH.js gzip 351 B 351 B
hooks-HASH.js gzip 921 B 921 B
image-HASH.js gzip 5.59 kB 5.59 kB
index-HASH.js gzip 261 B 261 B
link-HASH.js gzip 2.33 kB 2.33 kB
routerDirect..HASH.js gzip 322 B 322 B
script-HASH.js gzip 388 B 388 B
withRouter-HASH.js gzip 317 B 317 B
85e02e95b279..7e3.css gzip 107 B 107 B
Overall change 15.3 kB 15.3 kB
Client Build Manifests
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
_buildManifest.js gzip 458 B 458 B
Overall change 458 B 458 B
Rendered Page Sizes Overall decrease ✓
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
index.html gzip 532 B 530 B -2 B
link.html gzip 546 B 545 B -1 B
withRouter.html gzip 526 B 526 B
Overall change 1.6 kB 1.6 kB -3 B

Diffs

Diff for main-HASH.js
@@ -473,7 +473,7 @@
       var _routeAnnouncer = __webpack_require__(8483);
       var _router1 = __webpack_require__(880);
       var _isError = __webpack_require__(676);
-      var _vitals = __webpack_require__(7185);
+      var _vitals = __webpack_require__(4564);
       var _refresh = __webpack_require__(2129);
       var _imageConfigContext = __webpack_require__(8730);
       function asyncGeneratorStep(
@@ -3197,7 +3197,7 @@
       /***/
     },
 
-    /***/ 7185: /***/ function(
+    /***/ 4564: /***/ function(
       __unused_webpack_module,
       exports,
       __webpack_require__
@@ -4351,8 +4351,8 @@
       var _resolveRewrites = _interopRequireDefault1(__webpack_require__(2431));
       var _routeMatcher = __webpack_require__(3156);
       var _routeRegex = __webpack_require__(4903);
-      var _getMiddlewareRegex = __webpack_require__(3072);
       var _formatUrl = __webpack_require__(7795);
+      var _routingItems = __webpack_require__(7185);
       function _interopRequireDefault1(obj) {
         return obj && obj.__esModule
           ? obj
@@ -6378,8 +6378,16 @@
                 _runtimeJs.default.mark(function _callee() {
                   var asPathname,
                     cleanedAs,
-                    fns,
+                    middlewareList,
+                    middleware,
+                    routingItems,
                     requiresPreflight,
+                    _iteratorNormalCompletion,
+                    _didIteratorError,
+                    _iteratorError,
+                    _iterator,
+                    _step,
+                    item,
                     preflight,
                     parsed,
                     fsPathname,
@@ -6404,58 +6412,116 @@
                             _ctx.next = 4;
                             return _this.pageLoader.getMiddlewareList();
                           case 4:
-                            fns = _ctx.sent;
-                            requiresPreflight = fns.some(function(param) {
+                            middlewareList = _ctx.sent;
+                            middleware = middlewareList.map(function(param) {
                               var _param = _slicedToArray(param, 2),
-                                middleware = _param[0],
-                                isSSR = _param[1];
-                              return (0, _routeMatcher).getRouteMatcher(
-                                (0, _getMiddlewareRegex).getMiddlewareRegex(
-                                  middleware,
-                                  !isSSR
-                                )
-                              )(cleanedAs);
+                                page = _param[0],
+                                ssr = _param[1];
+                              return {
+                                page: page,
+                                ssr: ssr
+                              };
                             });
+                            routingItems = (0, _routingItems).getRoutingItems(
+                              options.pages,
+                              middleware
+                            );
+                            requiresPreflight = false;
+                            (_iteratorNormalCompletion = true),
+                              (_didIteratorError = false),
+                              (_iteratorError = undefined);
+                            _ctx.prev = 9;
+                            _iterator = routingItems[Symbol.iterator]();
+                          case 11:
+                            if (
+                              (_iteratorNormalCompletion = (_step = _iterator.next())
+                                .done)
+                            ) {
+                              _ctx.next = 19;
+                              break;
+                            }
+                            item = _step.value;
+                            if (!item.match(cleanedAs)) {
+                              _ctx.next = 16;
+                              break;
+                            }
+                            if (item.isMiddleware) {
+                              requiresPreflight = true;
+                            }
+                            return _ctx.abrupt("break", 19);
+                          case 16:
+                            _iteratorNormalCompletion = true;
+                            _ctx.next = 11;
+                            break;
+                          case 19:
+                            _ctx.next = 25;
+                            break;
+                          case 21:
+                            _ctx.prev = 21;
+                            _ctx.t0 = _ctx["catch"](9);
+                            _didIteratorError = true;
+                            _iteratorError = _ctx.t0;
+                          case 25:
+                            _ctx.prev = 25;
+                            _ctx.prev = 26;
+                            if (
+                              !_iteratorNormalCompletion &&
+                              _iterator.return != null
+                            ) {
+                              _iterator.return();
+                            }
+                          case 28:
+                            _ctx.prev = 28;
+                            if (!_didIteratorError) {
+                              _ctx.next = 31;
+                              break;
+                            }
+                            throw _iteratorError;
+                          case 31:
+                            return _ctx.finish(28);
+                          case 32:
+                            return _ctx.finish(25);
+                          case 33:
                             if (requiresPreflight) {
-                              _ctx.next = 8;
+                              _ctx.next = 35;
                               break;
                             }
                             return _ctx.abrupt("return", {
                               type: "next"
                             });
-                          case 8:
-                            _ctx.prev = 9;
-                            _ctx.next = 12;
+                          case 35:
+                            _ctx.prev = 36;
+                            _ctx.next = 39;
                             return _this._getPreflightData({
                               preflightHref: options.as,
                               shouldCache: options.cache,
                               isPreview: options.isPreview
                             });
-                          case 12:
+                          case 39:
                             preflight = _ctx.sent;
-                            _ctx.next = 18;
+                            _ctx.next = 45;
                             break;
-                          case 15:
-                            _ctx.prev = 15;
-                            _ctx.t0 = _ctx["catch"](9);
+                          case 42:
+                            _ctx.prev = 42;
+                            _ctx.t1 = _ctx["catch"](36);
                             return _ctx.abrupt("return", {
                               type: "redirect",
                               destination: options.as
                             });
-                          case 18:
+                          case 45:
                             if (!preflight.rewrite) {
-                              _ctx.next = 27;
+                              _ctx.next = 54;
                               break;
                             }
                             if (preflight.rewrite.startsWith("/")) {
-                              _ctx.next = 21;
+                              _ctx.next = 48;
                               break;
                             }
                             return _ctx.abrupt("return", {
                               type: "redirect",
                               destination: options.as
                             });
-                          case 21:
+                          case 48:
                             parsed = (0, _parseRelativeUrl).parseRelativeUrl(
                               (0, _normalizeLocalePath).normalizeLocalePath(
                                 hasBasePath(preflight.rewrite)
@@ -6490,13 +6556,13 @@
                               matchedPage: matchedPage,
                               resolvedHref: resolvedHref
                             });
-                          case 27:
+                          case 54:
                             if (!preflight.redirect) {
-                              _ctx.next = 33;
+                              _ctx.next = 60;
                               break;
                             }
                             if (!preflight.redirect.startsWith("/")) {
-                              _ctx.next = 32;
+                              _ctx.next = 59;
                               break;
                             }
                             cleanRedirect = (0,
@@ -6520,31 +6586,35 @@
                               newUrl: newUrl,
                               newAs: newAs
                             });
-                          case 32:
+                          case 59:
                             return _ctx.abrupt("return", {
                               type: "redirect",
                               destination: preflight.redirect
                             });
-                          case 33:
+                          case 60:
                             if (!(preflight.refresh && !preflight.ssr)) {
-                              _ctx.next = 35;
+                              _ctx.next = 62;
                               break;
                             }
                             return _ctx.abrupt("return", {
                               type: "refresh"
                             });
-                          case 35:
+                          case 62:
                             return _ctx.abrupt("return", {
                               type: "next"
                             });
-                          case 36:
+                          case 63:
                           case "end":
                             return _ctx.stop();
                         }
                     },
                     _callee,
                     null,
-                    [[9, 15]]
+                    [
+                      [9, 21, 25, 33],
+                      [26, , 28, 32],
+                      [36, 42]
+                    ]
                   );
                 })
               )();
@@ -6816,11 +6886,17 @@
       });
       exports.getMiddlewareRegex = getMiddlewareRegex;
       var _routeRegex = __webpack_require__(4903);
+      // Identify ^/[param]/ in route string
+      var FIRST_SEGMENT_DYNAMIC = /^\/\[[^/]+?\](?=\/|$)/;
+      var NOT_API_ROUTE = "(?!/api(?:/|$))";
       function getMiddlewareRegex(normalizedRoute) {
         var catchAll =
           arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : true;
         var result = (0, _routeRegex).getParametrizedRoute(normalizedRoute);
-        var catchAllRegex = catchAll ? "(?!_next).*" : "";
+        var notApiRegex = FIRST_SEGMENT_DYNAMIC.test(normalizedRoute)
+          ? NOT_API_ROUTE
+          : "";
+        var catchAllRegex = catchAll ? "(?!_next($|/)).*" : "";
         var catchAllGroupedRegex = catchAll ? "(?:(/.*)?)" : "";
         if ("routeKeys" in result) {
           if (result.parameterizedRoute === "/") {
@@ -6834,10 +6910,12 @@
           return {
             groups: result.groups,
             namedRegex: "^"
+              .concat(notApiRegex)
               .concat(result.namedParameterizedRoute)
               .concat(catchAllGroupedRegex, "$"),
             re: new RegExp(
               "^"
+                .concat(notApiRegex)
                 .concat(result.parameterizedRoute)
                 .concat(catchAllGroupedRegex, "$")
             ),
@@ -6854,6 +6932,7 @@
           groups: {},
           re: new RegExp(
             "^"
+              .concat(notApiRegex)
               .concat(result.parameterizedRoute)
               .concat(catchAllGroupedRegex, "$")
           )
@@ -6891,6 +6970,18 @@
           return _routeRegex.getRouteRegex;
         }
       });
+      Object.defineProperty(exports, "getRoutingItems", {
+        enumerable: true,
+        get: function get() {
+          return _routingItems.getRoutingItems;
+        }
+      });
+      Object.defineProperty(exports, "RoutingItem", {
+        enumerable: true,
+        get: function get() {
+          return _routingItems.RoutingItem;
+        }
+      });
       Object.defineProperty(exports, "getSortedRoutes", {
         enumerable: true,
         get: function get() {
@@ -6906,6 +6997,7 @@
       var _getMiddlewareRegex = __webpack_require__(3072);
       var _routeMatcher = __webpack_require__(3156);
       var _routeRegex = __webpack_require__(4903);
+      var _routingItems = __webpack_require__(7185);
       var _sortedRoutes = __webpack_require__(566);
       var _isDynamic = __webpack_require__(6238); //# sourceMappingURL=index.js.map
 
@@ -7237,6 +7329,101 @@
       /***/
     },
 
+    /***/ 7185: /***/ function(
+      __unused_webpack_module,
+      exports,
+      __webpack_require__
+    ) {
+      "use strict";
+
+      function _arrayLikeToArray(arr, len) {
+        if (len == null || len > arr.length) len = arr.length;
+        for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
+        return arr2;
+      }
+      function _arrayWithoutHoles(arr) {
+        if (Array.isArray(arr)) return _arrayLikeToArray(arr);
+      }
+      function _iterableToArray(iter) {
+        if (
+          (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null) ||
+          iter["@@iterator"] != null
+        )
+          return Array.from(iter);
+      }
+      function _nonIterableSpread() {
+        throw new TypeError(
+          "Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."
+        );
+      }
+      function _toConsumableArray(arr) {
+        return (
+          _arrayWithoutHoles(arr) ||
+          _iterableToArray(arr) ||
+          _unsupportedIterableToArray(arr) ||
+          _nonIterableSpread()
+        );
+      }
+      function _unsupportedIterableToArray(o, minLen) {
+        if (!o) return;
+        if (typeof o === "string") return _arrayLikeToArray(o, minLen);
+        var n = Object.prototype.toString.call(o).slice(8, -1);
+        if (n === "Object" && o.constructor) n = o.constructor.name;
+        if (n === "Map" || n === "Set") return Array.from(n);
+        if (
+          n === "Arguments" ||
+          /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)
+        )
+          return _arrayLikeToArray(o, minLen);
+      }
+      Object.defineProperty(exports, "__esModule", {
+        value: true
+      });
+      exports.getRoutingItems = getRoutingItems;
+      var _getMiddlewareRegex = __webpack_require__(3072);
+      var _routeMatcher = __webpack_require__(3156);
+      var _routeRegex = __webpack_require__(4903);
+      var _sortedRoutes = __webpack_require__(566);
+      var MIDDLEWARE_SUFFIX = "/_middleware";
+      function getRoutingItems(pages, middleware) {
+        // append the suffix so that `getSortedRoutes()` can handle middleware properly
+        var middlewarePages = middleware.map(function(m) {
+          return "".concat(m.page).concat(MIDDLEWARE_SUFFIX);
+        });
+        var middlewareMap = new Map(
+          middleware.map(function(m) {
+            return [m.page, m];
+          })
+        );
+        var sortedRoutes = (0, _sortedRoutes).getSortedRoutes(
+          _toConsumableArray(pages).concat(_toConsumableArray(middlewarePages))
+        );
+        return sortedRoutes.map(function(page) {
+          if (page.endsWith(MIDDLEWARE_SUFFIX)) {
+            var p = page.slice(0, -MIDDLEWARE_SUFFIX.length) || "/";
+            var ssr = middlewareMap.get(p).ssr;
+            return {
+              match: (0, _routeMatcher).getRouteMatcher(
+                (0, _getMiddlewareRegex).getMiddlewareRegex(p, !ssr)
+              ),
+              page: p,
+              ssr: ssr,
+              isMiddleware: true
+            };
+          } else {
+            return {
+              match: (0, _routeMatcher).getRouteMatcher(
+                (0, _routeRegex).getRouteRegex(page)
+              ),
+              page: page
+            };
+          }
+        });
+      } //# sourceMappingURL=routing-items.js.map
+
+      /***/
+    },
+
     /***/ 566: /***/ function(__unused_webpack_module, exports) {
       "use strict";
 
@@ -7311,6 +7498,7 @@
           this.slugName = null;
           this.restSlugName = null;
           this.optionalRestSlugName = null;
+          this.isMiddleware = false;
         }
         _createClass(UrlNode, [
           {
@@ -7345,6 +7533,9 @@
               if (this.optionalRestSlugName !== null) {
                 childrenPaths.splice(childrenPaths.indexOf("[[...]]"), 1);
               }
+              if (this.isMiddleware) {
+                childrenPaths.splice(childrenPaths.indexOf("_middleware"), 1);
+              }
               var routes = childrenPaths
                 .map(function(c) {
                   return _this.children
@@ -7381,10 +7572,21 @@
                 }
                 routes.unshift(r);
               }
-              if (this.restSlugName !== null) {
+              if (this.isMiddleware) {
                 var _routes1;
-                (_routes1 = routes).push.apply(
+                (_routes1 = routes).unshift.apply(
                   _routes1,
+                  _toConsumableArray(
+                    this.children
+                      .get("_middleware")
+                      ._smoosh("".concat(prefix, "_middleware/"))
+                  )
+                );
+              }
+              if (this.restSlugName !== null) {
+                var _routes2;
+                (_routes2 = routes).push.apply(
+                  _routes2,
                   _toConsumableArray(
                     this.children
                       .get("[...]")
@@ -7397,9 +7599,9 @@
                 );
               }
               if (this.optionalRestSlugName !== null) {
-                var _routes2;
-                (_routes2 = routes).push.apply(
-                  _routes2,
+                var _routes3;
+                (_routes3 = routes).push.apply(
+                  _routes3,
                   _toConsumableArray(
                     this.children
                       .get("[[...]]")
@@ -7540,6 +7742,11 @@
                   // nextSegment is overwritten to [] so that it can later be sorted specifically
                   nextSegment = "[]";
                 }
+              } else if (
+                nextSegment === "_middleware" &&
+                urlPaths.length === 1
+              ) {
+                this.isMiddleware = true;
               }
               // If this UrlNode doesn't have the nextSegment yet we create a new child UrlNode
               if (!this.children.has(nextSegment)) {
Diff for index.html
@@ -19,7 +19,7 @@
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/main-4519db47b727e3b6.js"
+      src="/_next/static/chunks/main-24bf6d59775add36.js"
       defer=""
     ></script>
     <script
Diff for link.html
@@ -19,7 +19,7 @@
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/main-4519db47b727e3b6.js"
+      src="/_next/static/chunks/main-24bf6d59775add36.js"
       defer=""
     ></script>
     <script
Diff for withRouter.html
@@ -19,7 +19,7 @@
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/main-4519db47b727e3b6.js"
+      src="/_next/static/chunks/main-24bf6d59775add36.js"
       defer=""
     ></script>
     <script
Commit: beb0728

@ijjk
Copy link
Member

ijjk commented Mar 28, 2022

Stats from current PR

Default Build (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
buildDuration 15.8s 15.4s -394ms
buildDurationCached 5.6s 5.7s ⚠️ +41ms
nodeModulesSize 467 MB 467 MB ⚠️ +9.67 kB
Page Load Tests Overall decrease ⚠️
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
/ failed reqs 0 0
/ total time (seconds) 3.168 3.203 ⚠️ +0.03
/ avg req/sec 789.22 780.5 ⚠️ -8.72
/error-in-render failed reqs 0 0
/error-in-render total time (seconds) 1.366 1.419 ⚠️ +0.05
/error-in-render avg req/sec 1830.77 1761.34 ⚠️ -69.43
Client Bundles (main, webpack) Overall increase ⚠️
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
925.HASH.js gzip 179 B 179 B
framework-HASH.js gzip 42 kB 42 kB
main-HASH.js gzip 27.9 kB 28.4 kB ⚠️ +490 B
webpack-HASH.js gzip 1.44 kB 1.44 kB
Overall change 71.6 kB 72.1 kB ⚠️ +490 B
Legacy Client Bundles (polyfills)
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
polyfills-HASH.js gzip 31 kB 31 kB
Overall change 31 kB 31 kB
Client Pages
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
_app-HASH.js gzip 1.36 kB 1.36 kB
_error-HASH.js gzip 192 B 192 B
amp-HASH.js gzip 309 B 309 B
css-HASH.js gzip 327 B 327 B
dynamic-HASH.js gzip 2.57 kB 2.57 kB
head-HASH.js gzip 351 B 351 B
hooks-HASH.js gzip 920 B 920 B
image-HASH.js gzip 5.48 kB 5.48 kB
index-HASH.js gzip 263 B 263 B
link-HASH.js gzip 2.26 kB 2.26 kB
routerDirect..HASH.js gzip 320 B 320 B
script-HASH.js gzip 387 B 387 B
withRouter-HASH.js gzip 319 B 319 B
85e02e95b279..7e3.css gzip 107 B 107 B
Overall change 15.2 kB 15.2 kB
Client Build Manifests
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
_buildManifest.js gzip 460 B 460 B
Overall change 460 B 460 B
Rendered Page Sizes Overall increase ⚠️
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
index.html gzip 532 B 532 B
link.html gzip 545 B 546 B ⚠️ +1 B
withRouter.html gzip 525 B 526 B ⚠️ +1 B
Overall change 1.6 kB 1.6 kB ⚠️ +2 B

Diffs

Diff for main-HASH.js
@@ -473,7 +473,7 @@
       var _routeAnnouncer = __webpack_require__(8483);
       var _router1 = __webpack_require__(880);
       var _isError = __webpack_require__(676);
-      var _vitals = __webpack_require__(7185);
+      var _vitals = __webpack_require__(4564);
       var _refresh = __webpack_require__(2129);
       var _imageConfigContext = __webpack_require__(8730);
       function asyncGeneratorStep(
@@ -3197,7 +3197,7 @@
       /***/
     },
 
-    /***/ 7185: /***/ function(
+    /***/ 4564: /***/ function(
       __unused_webpack_module,
       exports,
       __webpack_require__
@@ -4351,8 +4351,8 @@
       var _resolveRewrites = _interopRequireDefault1(__webpack_require__(2431));
       var _routeMatcher = __webpack_require__(3156);
       var _routeRegex = __webpack_require__(4903);
-      var _getMiddlewareRegex = __webpack_require__(3072);
       var _formatUrl = __webpack_require__(7795);
+      var _routingItems = __webpack_require__(7185);
       function _interopRequireDefault1(obj) {
         return obj && obj.__esModule
           ? obj
@@ -6378,8 +6378,16 @@
                 _runtimeJs.default.mark(function _callee() {
                   var asPathname,
                     cleanedAs,
-                    fns,
+                    middlewareList,
+                    middleware,
+                    routingItems,
                     requiresPreflight,
+                    _iteratorNormalCompletion,
+                    _didIteratorError,
+                    _iteratorError,
+                    _iterator,
+                    _step,
+                    item,
                     preflight,
                     parsed,
                     fsPathname,
@@ -6404,58 +6412,116 @@
                             _ctx.next = 4;
                             return _this.pageLoader.getMiddlewareList();
                           case 4:
-                            fns = _ctx.sent;
-                            requiresPreflight = fns.some(function(param) {
+                            middlewareList = _ctx.sent;
+                            middleware = middlewareList.map(function(param) {
                               var _param = _slicedToArray(param, 2),
-                                middleware = _param[0],
-                                isSSR = _param[1];
-                              return (0, _routeMatcher).getRouteMatcher(
-                                (0, _getMiddlewareRegex).getMiddlewareRegex(
-                                  middleware,
-                                  !isSSR
-                                )
-                              )(cleanedAs);
+                                page = _param[0],
+                                ssr = _param[1];
+                              return {
+                                page: page,
+                                ssr: ssr
+                              };
                             });
+                            routingItems = (0, _routingItems).getRoutingItems(
+                              options.pages,
+                              middleware
+                            );
+                            requiresPreflight = false;
+                            (_iteratorNormalCompletion = true),
+                              (_didIteratorError = false),
+                              (_iteratorError = undefined);
+                            _ctx.prev = 9;
+                            _iterator = routingItems[Symbol.iterator]();
+                          case 11:
+                            if (
+                              (_iteratorNormalCompletion = (_step = _iterator.next())
+                                .done)
+                            ) {
+                              _ctx.next = 19;
+                              break;
+                            }
+                            item = _step.value;
+                            if (!item.match(cleanedAs)) {
+                              _ctx.next = 16;
+                              break;
+                            }
+                            if (item.isMiddleware) {
+                              requiresPreflight = true;
+                            }
+                            return _ctx.abrupt("break", 19);
+                          case 16:
+                            _iteratorNormalCompletion = true;
+                            _ctx.next = 11;
+                            break;
+                          case 19:
+                            _ctx.next = 25;
+                            break;
+                          case 21:
+                            _ctx.prev = 21;
+                            _ctx.t0 = _ctx["catch"](9);
+                            _didIteratorError = true;
+                            _iteratorError = _ctx.t0;
+                          case 25:
+                            _ctx.prev = 25;
+                            _ctx.prev = 26;
+                            if (
+                              !_iteratorNormalCompletion &&
+                              _iterator.return != null
+                            ) {
+                              _iterator.return();
+                            }
+                          case 28:
+                            _ctx.prev = 28;
+                            if (!_didIteratorError) {
+                              _ctx.next = 31;
+                              break;
+                            }
+                            throw _iteratorError;
+                          case 31:
+                            return _ctx.finish(28);
+                          case 32:
+                            return _ctx.finish(25);
+                          case 33:
                             if (requiresPreflight) {
-                              _ctx.next = 8;
+                              _ctx.next = 35;
                               break;
                             }
                             return _ctx.abrupt("return", {
                               type: "next"
                             });
-                          case 8:
-                            _ctx.prev = 9;
-                            _ctx.next = 12;
+                          case 35:
+                            _ctx.prev = 36;
+                            _ctx.next = 39;
                             return _this._getPreflightData({
                               preflightHref: options.as,
                               shouldCache: options.cache,
                               isPreview: options.isPreview
                             });
-                          case 12:
+                          case 39:
                             preflight = _ctx.sent;
-                            _ctx.next = 18;
+                            _ctx.next = 45;
                             break;
-                          case 15:
-                            _ctx.prev = 15;
-                            _ctx.t0 = _ctx["catch"](9);
+                          case 42:
+                            _ctx.prev = 42;
+                            _ctx.t1 = _ctx["catch"](36);
                             return _ctx.abrupt("return", {
                               type: "redirect",
                               destination: options.as
                             });
-                          case 18:
+                          case 45:
                             if (!preflight.rewrite) {
-                              _ctx.next = 27;
+                              _ctx.next = 54;
                               break;
                             }
                             if (preflight.rewrite.startsWith("/")) {
-                              _ctx.next = 21;
+                              _ctx.next = 48;
                               break;
                             }
                             return _ctx.abrupt("return", {
                               type: "redirect",
                               destination: options.as
                             });
-                          case 21:
+                          case 48:
                             parsed = (0, _parseRelativeUrl).parseRelativeUrl(
                               (0, _normalizeLocalePath).normalizeLocalePath(
                                 hasBasePath(preflight.rewrite)
@@ -6490,13 +6556,13 @@
                               matchedPage: matchedPage,
                               resolvedHref: resolvedHref
                             });
-                          case 27:
+                          case 54:
                             if (!preflight.redirect) {
-                              _ctx.next = 33;
+                              _ctx.next = 60;
                               break;
                             }
                             if (!preflight.redirect.startsWith("/")) {
-                              _ctx.next = 32;
+                              _ctx.next = 59;
                               break;
                             }
                             cleanRedirect = (0,
@@ -6520,31 +6586,35 @@
                               newUrl: newUrl,
                               newAs: newAs
                             });
-                          case 32:
+                          case 59:
                             return _ctx.abrupt("return", {
                               type: "redirect",
                               destination: preflight.redirect
                             });
-                          case 33:
+                          case 60:
                             if (!(preflight.refresh && !preflight.ssr)) {
-                              _ctx.next = 35;
+                              _ctx.next = 62;
                               break;
                             }
                             return _ctx.abrupt("return", {
                               type: "refresh"
                             });
-                          case 35:
+                          case 62:
                             return _ctx.abrupt("return", {
                               type: "next"
                             });
-                          case 36:
+                          case 63:
                           case "end":
                             return _ctx.stop();
                         }
                     },
                     _callee,
                     null,
-                    [[9, 15]]
+                    [
+                      [9, 21, 25, 33],
+                      [26, , 28, 32],
+                      [36, 42]
+                    ]
                   );
                 })
               )();
@@ -6816,11 +6886,17 @@
       });
       exports.getMiddlewareRegex = getMiddlewareRegex;
       var _routeRegex = __webpack_require__(4903);
+      // Identify ^/[param]/ in route string
+      var FIRST_SEGMENT_DYNAMIC = /^\/\[[^/]+?\](?=\/|$)/;
+      var NOT_API_ROUTE = "(?!/api(?:/|$))";
       function getMiddlewareRegex(normalizedRoute) {
         var catchAll =
           arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : true;
         var result = (0, _routeRegex).getParametrizedRoute(normalizedRoute);
-        var catchAllRegex = catchAll ? "(?!_next).*" : "";
+        var notApiRegex = FIRST_SEGMENT_DYNAMIC.test(normalizedRoute)
+          ? NOT_API_ROUTE
+          : "";
+        var catchAllRegex = catchAll ? "(?!_next($|/)).*" : "";
         var catchAllGroupedRegex = catchAll ? "(?:(/.*)?)" : "";
         if ("routeKeys" in result) {
           if (result.parameterizedRoute === "/") {
@@ -6834,10 +6910,12 @@
           return {
             groups: result.groups,
             namedRegex: "^"
+              .concat(notApiRegex)
               .concat(result.namedParameterizedRoute)
               .concat(catchAllGroupedRegex, "$"),
             re: new RegExp(
               "^"
+                .concat(notApiRegex)
                 .concat(result.parameterizedRoute)
                 .concat(catchAllGroupedRegex, "$")
             ),
@@ -6854,6 +6932,7 @@
           groups: {},
           re: new RegExp(
             "^"
+              .concat(notApiRegex)
               .concat(result.parameterizedRoute)
               .concat(catchAllGroupedRegex, "$")
           )
@@ -6891,6 +6970,18 @@
           return _routeRegex.getRouteRegex;
         }
       });
+      Object.defineProperty(exports, "getRoutingItems", {
+        enumerable: true,
+        get: function get() {
+          return _routingItems.getRoutingItems;
+        }
+      });
+      Object.defineProperty(exports, "RoutingItem", {
+        enumerable: true,
+        get: function get() {
+          return _routingItems.RoutingItem;
+        }
+      });
       Object.defineProperty(exports, "getSortedRoutes", {
         enumerable: true,
         get: function get() {
@@ -6906,6 +6997,7 @@
       var _getMiddlewareRegex = __webpack_require__(3072);
       var _routeMatcher = __webpack_require__(3156);
       var _routeRegex = __webpack_require__(4903);
+      var _routingItems = __webpack_require__(7185);
       var _sortedRoutes = __webpack_require__(566);
       var _isDynamic = __webpack_require__(6238); //# sourceMappingURL=index.js.map
 
@@ -7237,6 +7329,101 @@
       /***/
     },
 
+    /***/ 7185: /***/ function(
+      __unused_webpack_module,
+      exports,
+      __webpack_require__
+    ) {
+      "use strict";
+
+      function _arrayLikeToArray(arr, len) {
+        if (len == null || len > arr.length) len = arr.length;
+        for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
+        return arr2;
+      }
+      function _arrayWithoutHoles(arr) {
+        if (Array.isArray(arr)) return _arrayLikeToArray(arr);
+      }
+      function _iterableToArray(iter) {
+        if (
+          (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null) ||
+          iter["@@iterator"] != null
+        )
+          return Array.from(iter);
+      }
+      function _nonIterableSpread() {
+        throw new TypeError(
+          "Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."
+        );
+      }
+      function _toConsumableArray(arr) {
+        return (
+          _arrayWithoutHoles(arr) ||
+          _iterableToArray(arr) ||
+          _unsupportedIterableToArray(arr) ||
+          _nonIterableSpread()
+        );
+      }
+      function _unsupportedIterableToArray(o, minLen) {
+        if (!o) return;
+        if (typeof o === "string") return _arrayLikeToArray(o, minLen);
+        var n = Object.prototype.toString.call(o).slice(8, -1);
+        if (n === "Object" && o.constructor) n = o.constructor.name;
+        if (n === "Map" || n === "Set") return Array.from(n);
+        if (
+          n === "Arguments" ||
+          /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)
+        )
+          return _arrayLikeToArray(o, minLen);
+      }
+      Object.defineProperty(exports, "__esModule", {
+        value: true
+      });
+      exports.getRoutingItems = getRoutingItems;
+      var _getMiddlewareRegex = __webpack_require__(3072);
+      var _routeMatcher = __webpack_require__(3156);
+      var _routeRegex = __webpack_require__(4903);
+      var _sortedRoutes = __webpack_require__(566);
+      var MIDDLEWARE_SUFFIX = "/_middleware";
+      function getRoutingItems(pages, middleware) {
+        // append the suffix so that `getSortedRoutes()` can handle middleware properly
+        var middlewarePages = middleware.map(function(m) {
+          return "".concat(m.page).concat(MIDDLEWARE_SUFFIX);
+        });
+        var middlewareMap = new Map(
+          middleware.map(function(m) {
+            return [m.page, m];
+          })
+        );
+        var sortedRoutes = (0, _sortedRoutes).getSortedRoutes(
+          _toConsumableArray(pages).concat(_toConsumableArray(middlewarePages))
+        );
+        return sortedRoutes.map(function(page) {
+          if (page.endsWith(MIDDLEWARE_SUFFIX)) {
+            var p = page.slice(0, -MIDDLEWARE_SUFFIX.length) || "/";
+            var ssr = middlewareMap.get(p).ssr;
+            return {
+              match: (0, _routeMatcher).getRouteMatcher(
+                (0, _getMiddlewareRegex).getMiddlewareRegex(p, !ssr)
+              ),
+              page: p,
+              ssr: ssr,
+              isMiddleware: true
+            };
+          } else {
+            return {
+              match: (0, _routeMatcher).getRouteMatcher(
+                (0, _routeRegex).getRouteRegex(page)
+              ),
+              page: page
+            };
+          }
+        });
+      } //# sourceMappingURL=routing-items.js.map
+
+      /***/
+    },
+
     /***/ 566: /***/ function(__unused_webpack_module, exports) {
       "use strict";
 
@@ -7311,6 +7498,7 @@
           this.slugName = null;
           this.restSlugName = null;
           this.optionalRestSlugName = null;
+          this.isMiddleware = false;
         }
         _createClass(UrlNode, [
           {
@@ -7345,6 +7533,9 @@
               if (this.optionalRestSlugName !== null) {
                 childrenPaths.splice(childrenPaths.indexOf("[[...]]"), 1);
               }
+              if (this.isMiddleware) {
+                childrenPaths.splice(childrenPaths.indexOf("_middleware"), 1);
+              }
               var routes = childrenPaths
                 .map(function(c) {
                   return _this.children
@@ -7381,10 +7572,21 @@
                 }
                 routes.unshift(r);
               }
-              if (this.restSlugName !== null) {
+              if (this.isMiddleware) {
                 var _routes1;
-                (_routes1 = routes).push.apply(
+                (_routes1 = routes).unshift.apply(
                   _routes1,
+                  _toConsumableArray(
+                    this.children
+                      .get("_middleware")
+                      ._smoosh("".concat(prefix, "_middleware/"))
+                  )
+                );
+              }
+              if (this.restSlugName !== null) {
+                var _routes2;
+                (_routes2 = routes).push.apply(
+                  _routes2,
                   _toConsumableArray(
                     this.children
                       .get("[...]")
@@ -7397,9 +7599,9 @@
                 );
               }
               if (this.optionalRestSlugName !== null) {
-                var _routes2;
-                (_routes2 = routes).push.apply(
-                  _routes2,
+                var _routes3;
+                (_routes3 = routes).push.apply(
+                  _routes3,
                   _toConsumableArray(
                     this.children
                       .get("[[...]]")
@@ -7540,6 +7742,11 @@
                   // nextSegment is overwritten to [] so that it can later be sorted specifically
                   nextSegment = "[]";
                 }
+              } else if (
+                nextSegment === "_middleware" &&
+                urlPaths.length === 1
+              ) {
+                this.isMiddleware = true;
               }
               // If this UrlNode doesn't have the nextSegment yet we create a new child UrlNode
               if (!this.children.has(nextSegment)) {
Diff for index.html
@@ -19,7 +19,7 @@
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/main-31e3f2e995c2cb43.js"
+      src="/_next/static/chunks/main-b5d24bd96df5cedc.js"
       defer=""
     ></script>
     <script
Diff for link.html
@@ -19,7 +19,7 @@
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/main-31e3f2e995c2cb43.js"
+      src="/_next/static/chunks/main-b5d24bd96df5cedc.js"
       defer=""
     ></script>
     <script
Diff for withRouter.html
@@ -19,7 +19,7 @@
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/main-31e3f2e995c2cb43.js"
+      src="/_next/static/chunks/main-b5d24bd96df5cedc.js"
       defer=""
     ></script>
     <script

Default Build with SWC (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
buildDuration 18.7s 18.5s -201ms
buildDurationCached 5.7s 6.1s ⚠️ +426ms
nodeModulesSize 467 MB 467 MB ⚠️ +9.67 kB
Page Load Tests Overall increase ✓
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
/ failed reqs 0 0
/ total time (seconds) 3.077 2.995 -0.08
/ avg req/sec 812.45 834.62 +22.17
/error-in-render failed reqs 0 0
/error-in-render total time (seconds) 1.369 1.339 -0.03
/error-in-render avg req/sec 1825.57 1866.41 +40.84
Client Bundles (main, webpack) Overall increase ⚠️
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
925.HASH.js gzip 178 B 178 B
framework-HASH.js gzip 42.3 kB 42.3 kB
main-HASH.js gzip 28.2 kB 28.8 kB ⚠️ +530 B
webpack-HASH.js gzip 1.45 kB 1.45 kB
Overall change 72.1 kB 72.7 kB ⚠️ +530 B
Legacy Client Bundles (polyfills)
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
polyfills-HASH.js gzip 31 kB 31 kB
Overall change 31 kB 31 kB
Client Pages
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
_app-HASH.js gzip 1.35 kB 1.35 kB
_error-HASH.js gzip 179 B 179 B
amp-HASH.js gzip 313 B 313 B
css-HASH.js gzip 324 B 324 B
dynamic-HASH.js gzip 2.56 kB 2.56 kB
head-HASH.js gzip 351 B 351 B
hooks-HASH.js gzip 921 B 921 B
image-HASH.js gzip 5.59 kB 5.59 kB
index-HASH.js gzip 261 B 261 B
link-HASH.js gzip 2.33 kB 2.33 kB
routerDirect..HASH.js gzip 322 B 322 B
script-HASH.js gzip 388 B 388 B
withRouter-HASH.js gzip 317 B 317 B
85e02e95b279..7e3.css gzip 107 B 107 B
Overall change 15.3 kB 15.3 kB
Client Build Manifests
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
_buildManifest.js gzip 458 B 458 B
Overall change 458 B 458 B
Rendered Page Sizes Overall decrease ✓
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
index.html gzip 532 B 530 B -2 B
link.html gzip 547 B 544 B -3 B
withRouter.html gzip 528 B 525 B -3 B
Overall change 1.61 kB 1.6 kB -8 B

Diffs

Diff for main-HASH.js
@@ -473,7 +473,7 @@
       var _routeAnnouncer = __webpack_require__(8483);
       var _router1 = __webpack_require__(880);
       var _isError = __webpack_require__(676);
-      var _vitals = __webpack_require__(7185);
+      var _vitals = __webpack_require__(4564);
       var _refresh = __webpack_require__(2129);
       var _imageConfigContext = __webpack_require__(8730);
       function asyncGeneratorStep(
@@ -3197,7 +3197,7 @@
       /***/
     },
 
-    /***/ 7185: /***/ function(
+    /***/ 4564: /***/ function(
       __unused_webpack_module,
       exports,
       __webpack_require__
@@ -4351,8 +4351,8 @@
       var _resolveRewrites = _interopRequireDefault1(__webpack_require__(2431));
       var _routeMatcher = __webpack_require__(3156);
       var _routeRegex = __webpack_require__(4903);
-      var _getMiddlewareRegex = __webpack_require__(3072);
       var _formatUrl = __webpack_require__(7795);
+      var _routingItems = __webpack_require__(7185);
       function _interopRequireDefault1(obj) {
         return obj && obj.__esModule
           ? obj
@@ -6378,8 +6378,16 @@
                 _runtimeJs.default.mark(function _callee() {
                   var asPathname,
                     cleanedAs,
-                    fns,
+                    middlewareList,
+                    middleware,
+                    routingItems,
                     requiresPreflight,
+                    _iteratorNormalCompletion,
+                    _didIteratorError,
+                    _iteratorError,
+                    _iterator,
+                    _step,
+                    item,
                     preflight,
                     parsed,
                     fsPathname,
@@ -6404,58 +6412,116 @@
                             _ctx.next = 4;
                             return _this.pageLoader.getMiddlewareList();
                           case 4:
-                            fns = _ctx.sent;
-                            requiresPreflight = fns.some(function(param) {
+                            middlewareList = _ctx.sent;
+                            middleware = middlewareList.map(function(param) {
                               var _param = _slicedToArray(param, 2),
-                                middleware = _param[0],
-                                isSSR = _param[1];
-                              return (0, _routeMatcher).getRouteMatcher(
-                                (0, _getMiddlewareRegex).getMiddlewareRegex(
-                                  middleware,
-                                  !isSSR
-                                )
-                              )(cleanedAs);
+                                page = _param[0],
+                                ssr = _param[1];
+                              return {
+                                page: page,
+                                ssr: ssr
+                              };
                             });
+                            routingItems = (0, _routingItems).getRoutingItems(
+                              options.pages,
+                              middleware
+                            );
+                            requiresPreflight = false;
+                            (_iteratorNormalCompletion = true),
+                              (_didIteratorError = false),
+                              (_iteratorError = undefined);
+                            _ctx.prev = 9;
+                            _iterator = routingItems[Symbol.iterator]();
+                          case 11:
+                            if (
+                              (_iteratorNormalCompletion = (_step = _iterator.next())
+                                .done)
+                            ) {
+                              _ctx.next = 19;
+                              break;
+                            }
+                            item = _step.value;
+                            if (!item.match(cleanedAs)) {
+                              _ctx.next = 16;
+                              break;
+                            }
+                            if (item.isMiddleware) {
+                              requiresPreflight = true;
+                            }
+                            return _ctx.abrupt("break", 19);
+                          case 16:
+                            _iteratorNormalCompletion = true;
+                            _ctx.next = 11;
+                            break;
+                          case 19:
+                            _ctx.next = 25;
+                            break;
+                          case 21:
+                            _ctx.prev = 21;
+                            _ctx.t0 = _ctx["catch"](9);
+                            _didIteratorError = true;
+                            _iteratorError = _ctx.t0;
+                          case 25:
+                            _ctx.prev = 25;
+                            _ctx.prev = 26;
+                            if (
+                              !_iteratorNormalCompletion &&
+                              _iterator.return != null
+                            ) {
+                              _iterator.return();
+                            }
+                          case 28:
+                            _ctx.prev = 28;
+                            if (!_didIteratorError) {
+                              _ctx.next = 31;
+                              break;
+                            }
+                            throw _iteratorError;
+                          case 31:
+                            return _ctx.finish(28);
+                          case 32:
+                            return _ctx.finish(25);
+                          case 33:
                             if (requiresPreflight) {
-                              _ctx.next = 8;
+                              _ctx.next = 35;
                               break;
                             }
                             return _ctx.abrupt("return", {
                               type: "next"
                             });
-                          case 8:
-                            _ctx.prev = 9;
-                            _ctx.next = 12;
+                          case 35:
+                            _ctx.prev = 36;
+                            _ctx.next = 39;
                             return _this._getPreflightData({
                               preflightHref: options.as,
                               shouldCache: options.cache,
                               isPreview: options.isPreview
                             });
-                          case 12:
+                          case 39:
                             preflight = _ctx.sent;
-                            _ctx.next = 18;
+                            _ctx.next = 45;
                             break;
-                          case 15:
-                            _ctx.prev = 15;
-                            _ctx.t0 = _ctx["catch"](9);
+                          case 42:
+                            _ctx.prev = 42;
+                            _ctx.t1 = _ctx["catch"](36);
                             return _ctx.abrupt("return", {
                               type: "redirect",
                               destination: options.as
                             });
-                          case 18:
+                          case 45:
                             if (!preflight.rewrite) {
-                              _ctx.next = 27;
+                              _ctx.next = 54;
                               break;
                             }
                             if (preflight.rewrite.startsWith("/")) {
-                              _ctx.next = 21;
+                              _ctx.next = 48;
                               break;
                             }
                             return _ctx.abrupt("return", {
                               type: "redirect",
                               destination: options.as
                             });
-                          case 21:
+                          case 48:
                             parsed = (0, _parseRelativeUrl).parseRelativeUrl(
                               (0, _normalizeLocalePath).normalizeLocalePath(
                                 hasBasePath(preflight.rewrite)
@@ -6490,13 +6556,13 @@
                               matchedPage: matchedPage,
                               resolvedHref: resolvedHref
                             });
-                          case 27:
+                          case 54:
                             if (!preflight.redirect) {
-                              _ctx.next = 33;
+                              _ctx.next = 60;
                               break;
                             }
                             if (!preflight.redirect.startsWith("/")) {
-                              _ctx.next = 32;
+                              _ctx.next = 59;
                               break;
                             }
                             cleanRedirect = (0,
@@ -6520,31 +6586,35 @@
                               newUrl: newUrl,
                               newAs: newAs
                             });
-                          case 32:
+                          case 59:
                             return _ctx.abrupt("return", {
                               type: "redirect",
                               destination: preflight.redirect
                             });
-                          case 33:
+                          case 60:
                             if (!(preflight.refresh && !preflight.ssr)) {
-                              _ctx.next = 35;
+                              _ctx.next = 62;
                               break;
                             }
                             return _ctx.abrupt("return", {
                               type: "refresh"
                             });
-                          case 35:
+                          case 62:
                             return _ctx.abrupt("return", {
                               type: "next"
                             });
-                          case 36:
+                          case 63:
                           case "end":
                             return _ctx.stop();
                         }
                     },
                     _callee,
                     null,
-                    [[9, 15]]
+                    [
+                      [9, 21, 25, 33],
+                      [26, , 28, 32],
+                      [36, 42]
+                    ]
                   );
                 })
               )();
@@ -6816,11 +6886,17 @@
       });
       exports.getMiddlewareRegex = getMiddlewareRegex;
       var _routeRegex = __webpack_require__(4903);
+      // Identify ^/[param]/ in route string
+      var FIRST_SEGMENT_DYNAMIC = /^\/\[[^/]+?\](?=\/|$)/;
+      var NOT_API_ROUTE = "(?!/api(?:/|$))";
       function getMiddlewareRegex(normalizedRoute) {
         var catchAll =
           arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : true;
         var result = (0, _routeRegex).getParametrizedRoute(normalizedRoute);
-        var catchAllRegex = catchAll ? "(?!_next).*" : "";
+        var notApiRegex = FIRST_SEGMENT_DYNAMIC.test(normalizedRoute)
+          ? NOT_API_ROUTE
+          : "";
+        var catchAllRegex = catchAll ? "(?!_next($|/)).*" : "";
         var catchAllGroupedRegex = catchAll ? "(?:(/.*)?)" : "";
         if ("routeKeys" in result) {
           if (result.parameterizedRoute === "/") {
@@ -6834,10 +6910,12 @@
           return {
             groups: result.groups,
             namedRegex: "^"
+              .concat(notApiRegex)
               .concat(result.namedParameterizedRoute)
               .concat(catchAllGroupedRegex, "$"),
             re: new RegExp(
               "^"
+                .concat(notApiRegex)
                 .concat(result.parameterizedRoute)
                 .concat(catchAllGroupedRegex, "$")
             ),
@@ -6854,6 +6932,7 @@
           groups: {},
           re: new RegExp(
             "^"
+              .concat(notApiRegex)
               .concat(result.parameterizedRoute)
               .concat(catchAllGroupedRegex, "$")
           )
@@ -6891,6 +6970,18 @@
           return _routeRegex.getRouteRegex;
         }
       });
+      Object.defineProperty(exports, "getRoutingItems", {
+        enumerable: true,
+        get: function get() {
+          return _routingItems.getRoutingItems;
+        }
+      });
+      Object.defineProperty(exports, "RoutingItem", {
+        enumerable: true,
+        get: function get() {
+          return _routingItems.RoutingItem;
+        }
+      });
       Object.defineProperty(exports, "getSortedRoutes", {
         enumerable: true,
         get: function get() {
@@ -6906,6 +6997,7 @@
       var _getMiddlewareRegex = __webpack_require__(3072);
       var _routeMatcher = __webpack_require__(3156);
       var _routeRegex = __webpack_require__(4903);
+      var _routingItems = __webpack_require__(7185);
       var _sortedRoutes = __webpack_require__(566);
       var _isDynamic = __webpack_require__(6238); //# sourceMappingURL=index.js.map
 
@@ -7237,6 +7329,101 @@
       /***/
     },
 
+    /***/ 7185: /***/ function(
+      __unused_webpack_module,
+      exports,
+      __webpack_require__
+    ) {
+      "use strict";
+
+      function _arrayLikeToArray(arr, len) {
+        if (len == null || len > arr.length) len = arr.length;
+        for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
+        return arr2;
+      }
+      function _arrayWithoutHoles(arr) {
+        if (Array.isArray(arr)) return _arrayLikeToArray(arr);
+      }
+      function _iterableToArray(iter) {
+        if (
+          (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null) ||
+          iter["@@iterator"] != null
+        )
+          return Array.from(iter);
+      }
+      function _nonIterableSpread() {
+        throw new TypeError(
+          "Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."
+        );
+      }
+      function _toConsumableArray(arr) {
+        return (
+          _arrayWithoutHoles(arr) ||
+          _iterableToArray(arr) ||
+          _unsupportedIterableToArray(arr) ||
+          _nonIterableSpread()
+        );
+      }
+      function _unsupportedIterableToArray(o, minLen) {
+        if (!o) return;
+        if (typeof o === "string") return _arrayLikeToArray(o, minLen);
+        var n = Object.prototype.toString.call(o).slice(8, -1);
+        if (n === "Object" && o.constructor) n = o.constructor.name;
+        if (n === "Map" || n === "Set") return Array.from(n);
+        if (
+          n === "Arguments" ||
+          /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)
+        )
+          return _arrayLikeToArray(o, minLen);
+      }
+      Object.defineProperty(exports, "__esModule", {
+        value: true
+      });
+      exports.getRoutingItems = getRoutingItems;
+      var _getMiddlewareRegex = __webpack_require__(3072);
+      var _routeMatcher = __webpack_require__(3156);
+      var _routeRegex = __webpack_require__(4903);
+      var _sortedRoutes = __webpack_require__(566);
+      var MIDDLEWARE_SUFFIX = "/_middleware";
+      function getRoutingItems(pages, middleware) {
+        // append the suffix so that `getSortedRoutes()` can handle middleware properly
+        var middlewarePages = middleware.map(function(m) {
+          return "".concat(m.page).concat(MIDDLEWARE_SUFFIX);
+        });
+        var middlewareMap = new Map(
+          middleware.map(function(m) {
+            return [m.page, m];
+          })
+        );
+        var sortedRoutes = (0, _sortedRoutes).getSortedRoutes(
+          _toConsumableArray(pages).concat(_toConsumableArray(middlewarePages))
+        );
+        return sortedRoutes.map(function(page) {
+          if (page.endsWith(MIDDLEWARE_SUFFIX)) {
+            var p = page.slice(0, -MIDDLEWARE_SUFFIX.length) || "/";
+            var ssr = middlewareMap.get(p).ssr;
+            return {
+              match: (0, _routeMatcher).getRouteMatcher(
+                (0, _getMiddlewareRegex).getMiddlewareRegex(p, !ssr)
+              ),
+              page: p,
+              ssr: ssr,
+              isMiddleware: true
+            };
+          } else {
+            return {
+              match: (0, _routeMatcher).getRouteMatcher(
+                (0, _routeRegex).getRouteRegex(page)
+              ),
+              page: page
+            };
+          }
+        });
+      } //# sourceMappingURL=routing-items.js.map
+
+      /***/
+    },
+
     /***/ 566: /***/ function(__unused_webpack_module, exports) {
       "use strict";
 
@@ -7311,6 +7498,7 @@
           this.slugName = null;
           this.restSlugName = null;
           this.optionalRestSlugName = null;
+          this.isMiddleware = false;
         }
         _createClass(UrlNode, [
           {
@@ -7345,6 +7533,9 @@
               if (this.optionalRestSlugName !== null) {
                 childrenPaths.splice(childrenPaths.indexOf("[[...]]"), 1);
               }
+              if (this.isMiddleware) {
+                childrenPaths.splice(childrenPaths.indexOf("_middleware"), 1);
+              }
               var routes = childrenPaths
                 .map(function(c) {
                   return _this.children
@@ -7381,10 +7572,21 @@
                 }
                 routes.unshift(r);
               }
-              if (this.restSlugName !== null) {
+              if (this.isMiddleware) {
                 var _routes1;
-                (_routes1 = routes).push.apply(
+                (_routes1 = routes).unshift.apply(
                   _routes1,
+                  _toConsumableArray(
+                    this.children
+                      .get("_middleware")
+                      ._smoosh("".concat(prefix, "_middleware/"))
+                  )
+                );
+              }
+              if (this.restSlugName !== null) {
+                var _routes2;
+                (_routes2 = routes).push.apply(
+                  _routes2,
                   _toConsumableArray(
                     this.children
                       .get("[...]")
@@ -7397,9 +7599,9 @@
                 );
               }
               if (this.optionalRestSlugName !== null) {
-                var _routes2;
-                (_routes2 = routes).push.apply(
-                  _routes2,
+                var _routes3;
+                (_routes3 = routes).push.apply(
+                  _routes3,
                   _toConsumableArray(
                     this.children
                       .get("[[...]]")
@@ -7540,6 +7742,11 @@
                   // nextSegment is overwritten to [] so that it can later be sorted specifically
                   nextSegment = "[]";
                 }
+              } else if (
+                nextSegment === "_middleware" &&
+                urlPaths.length === 1
+              ) {
+                this.isMiddleware = true;
               }
               // If this UrlNode doesn't have the nextSegment yet we create a new child UrlNode
               if (!this.children.has(nextSegment)) {
Diff for index.html
@@ -19,7 +19,7 @@
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/main-31e3f2e995c2cb43.js"
+      src="/_next/static/chunks/main-b5d24bd96df5cedc.js"
       defer=""
     ></script>
     <script
Diff for link.html
@@ -19,7 +19,7 @@
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/main-31e3f2e995c2cb43.js"
+      src="/_next/static/chunks/main-b5d24bd96df5cedc.js"
       defer=""
     ></script>
     <script
Diff for withRouter.html
@@ -19,7 +19,7 @@
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/main-31e3f2e995c2cb43.js"
+      src="/_next/static/chunks/main-b5d24bd96df5cedc.js"
       defer=""
     ></script>
     <script
Commit: a089ea5

@ijjk
Copy link
Member

ijjk commented Mar 28, 2022

Stats from current PR

Default Build (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
buildDuration 14s 14.2s ⚠️ +191ms
buildDurationCached 5.5s 5.5s -58ms
nodeModulesSize 467 MB 467 MB ⚠️ +9.67 kB
Page Load Tests Overall increase ✓
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
/ failed reqs 0 0
/ total time (seconds) 2.889 2.872 -0.02
/ avg req/sec 865.46 870.39 +4.93
/error-in-render failed reqs 0 0
/error-in-render total time (seconds) 1.258 1.25 -0.01
/error-in-render avg req/sec 1986.5 1999.32 +12.82
Client Bundles (main, webpack) Overall increase ⚠️
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
925.HASH.js gzip 179 B 179 B
framework-HASH.js gzip 42 kB 42 kB
main-HASH.js gzip 27.9 kB 28.4 kB ⚠️ +490 B
webpack-HASH.js gzip 1.44 kB 1.44 kB
Overall change 71.6 kB 72.1 kB ⚠️ +490 B
Legacy Client Bundles (polyfills)
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
polyfills-HASH.js gzip 31 kB 31 kB
Overall change 31 kB 31 kB
Client Pages
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
_app-HASH.js gzip 1.36 kB 1.36 kB
_error-HASH.js gzip 192 B 192 B
amp-HASH.js gzip 309 B 309 B
css-HASH.js gzip 327 B 327 B
dynamic-HASH.js gzip 2.57 kB 2.57 kB
head-HASH.js gzip 351 B 351 B
hooks-HASH.js gzip 920 B 920 B
image-HASH.js gzip 5.48 kB 5.48 kB
index-HASH.js gzip 263 B 263 B
link-HASH.js gzip 2.26 kB 2.26 kB
routerDirect..HASH.js gzip 320 B 320 B
script-HASH.js gzip 387 B 387 B
withRouter-HASH.js gzip 319 B 319 B
85e02e95b279..7e3.css gzip 107 B 107 B
Overall change 15.2 kB 15.2 kB
Client Build Manifests
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
_buildManifest.js gzip 460 B 460 B
Overall change 460 B 460 B
Rendered Page Sizes Overall increase ⚠️
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
index.html gzip 532 B 532 B
link.html gzip 545 B 546 B ⚠️ +1 B
withRouter.html gzip 525 B 526 B ⚠️ +1 B
Overall change 1.6 kB 1.6 kB ⚠️ +2 B

Diffs

Diff for main-HASH.js
@@ -473,7 +473,7 @@
       var _routeAnnouncer = __webpack_require__(8483);
       var _router1 = __webpack_require__(880);
       var _isError = __webpack_require__(676);
-      var _vitals = __webpack_require__(7185);
+      var _vitals = __webpack_require__(4564);
       var _refresh = __webpack_require__(2129);
       var _imageConfigContext = __webpack_require__(8730);
       function asyncGeneratorStep(
@@ -3197,7 +3197,7 @@
       /***/
     },
 
-    /***/ 7185: /***/ function(
+    /***/ 4564: /***/ function(
       __unused_webpack_module,
       exports,
       __webpack_require__
@@ -4351,8 +4351,8 @@
       var _resolveRewrites = _interopRequireDefault1(__webpack_require__(2431));
       var _routeMatcher = __webpack_require__(3156);
       var _routeRegex = __webpack_require__(4903);
-      var _getMiddlewareRegex = __webpack_require__(3072);
       var _formatUrl = __webpack_require__(7795);
+      var _routingItems = __webpack_require__(7185);
       function _interopRequireDefault1(obj) {
         return obj && obj.__esModule
           ? obj
@@ -6378,8 +6378,16 @@
                 _runtimeJs.default.mark(function _callee() {
                   var asPathname,
                     cleanedAs,
-                    fns,
+                    middlewareList,
+                    middleware,
+                    routingItems,
                     requiresPreflight,
+                    _iteratorNormalCompletion,
+                    _didIteratorError,
+                    _iteratorError,
+                    _iterator,
+                    _step,
+                    item,
                     preflight,
                     parsed,
                     fsPathname,
@@ -6404,58 +6412,116 @@
                             _ctx.next = 4;
                             return _this.pageLoader.getMiddlewareList();
                           case 4:
-                            fns = _ctx.sent;
-                            requiresPreflight = fns.some(function(param) {
+                            middlewareList = _ctx.sent;
+                            middleware = middlewareList.map(function(param) {
                               var _param = _slicedToArray(param, 2),
-                                middleware = _param[0],
-                                isSSR = _param[1];
-                              return (0, _routeMatcher).getRouteMatcher(
-                                (0, _getMiddlewareRegex).getMiddlewareRegex(
-                                  middleware,
-                                  !isSSR
-                                )
-                              )(cleanedAs);
+                                page = _param[0],
+                                ssr = _param[1];
+                              return {
+                                page: page,
+                                ssr: ssr
+                              };
                             });
+                            routingItems = (0, _routingItems).getRoutingItems(
+                              options.pages,
+                              middleware
+                            );
+                            requiresPreflight = false;
+                            (_iteratorNormalCompletion = true),
+                              (_didIteratorError = false),
+                              (_iteratorError = undefined);
+                            _ctx.prev = 9;
+                            _iterator = routingItems[Symbol.iterator]();
+                          case 11:
+                            if (
+                              (_iteratorNormalCompletion = (_step = _iterator.next())
+                                .done)
+                            ) {
+                              _ctx.next = 19;
+                              break;
+                            }
+                            item = _step.value;
+                            if (!item.match(cleanedAs)) {
+                              _ctx.next = 16;
+                              break;
+                            }
+                            if (item.isMiddleware) {
+                              requiresPreflight = true;
+                            }
+                            return _ctx.abrupt("break", 19);
+                          case 16:
+                            _iteratorNormalCompletion = true;
+                            _ctx.next = 11;
+                            break;
+                          case 19:
+                            _ctx.next = 25;
+                            break;
+                          case 21:
+                            _ctx.prev = 21;
+                            _ctx.t0 = _ctx["catch"](9);
+                            _didIteratorError = true;
+                            _iteratorError = _ctx.t0;
+                          case 25:
+                            _ctx.prev = 25;
+                            _ctx.prev = 26;
+                            if (
+                              !_iteratorNormalCompletion &&
+                              _iterator.return != null
+                            ) {
+                              _iterator.return();
+                            }
+                          case 28:
+                            _ctx.prev = 28;
+                            if (!_didIteratorError) {
+                              _ctx.next = 31;
+                              break;
+                            }
+                            throw _iteratorError;
+                          case 31:
+                            return _ctx.finish(28);
+                          case 32:
+                            return _ctx.finish(25);
+                          case 33:
                             if (requiresPreflight) {
-                              _ctx.next = 8;
+                              _ctx.next = 35;
                               break;
                             }
                             return _ctx.abrupt("return", {
                               type: "next"
                             });
-                          case 8:
-                            _ctx.prev = 9;
-                            _ctx.next = 12;
+                          case 35:
+                            _ctx.prev = 36;
+                            _ctx.next = 39;
                             return _this._getPreflightData({
                               preflightHref: options.as,
                               shouldCache: options.cache,
                               isPreview: options.isPreview
                             });
-                          case 12:
+                          case 39:
                             preflight = _ctx.sent;
-                            _ctx.next = 18;
+                            _ctx.next = 45;
                             break;
-                          case 15:
-                            _ctx.prev = 15;
-                            _ctx.t0 = _ctx["catch"](9);
+                          case 42:
+                            _ctx.prev = 42;
+                            _ctx.t1 = _ctx["catch"](36);
                             return _ctx.abrupt("return", {
                               type: "redirect",
                               destination: options.as
                             });
-                          case 18:
+                          case 45:
                             if (!preflight.rewrite) {
-                              _ctx.next = 27;
+                              _ctx.next = 54;
                               break;
                             }
                             if (preflight.rewrite.startsWith("/")) {
-                              _ctx.next = 21;
+                              _ctx.next = 48;
                               break;
                             }
                             return _ctx.abrupt("return", {
                               type: "redirect",
                               destination: options.as
                             });
-                          case 21:
+                          case 48:
                             parsed = (0, _parseRelativeUrl).parseRelativeUrl(
                               (0, _normalizeLocalePath).normalizeLocalePath(
                                 hasBasePath(preflight.rewrite)
@@ -6490,13 +6556,13 @@
                               matchedPage: matchedPage,
                               resolvedHref: resolvedHref
                             });
-                          case 27:
+                          case 54:
                             if (!preflight.redirect) {
-                              _ctx.next = 33;
+                              _ctx.next = 60;
                               break;
                             }
                             if (!preflight.redirect.startsWith("/")) {
-                              _ctx.next = 32;
+                              _ctx.next = 59;
                               break;
                             }
                             cleanRedirect = (0,
@@ -6520,31 +6586,35 @@
                               newUrl: newUrl,
                               newAs: newAs
                             });
-                          case 32:
+                          case 59:
                             return _ctx.abrupt("return", {
                               type: "redirect",
                               destination: preflight.redirect
                             });
-                          case 33:
+                          case 60:
                             if (!(preflight.refresh && !preflight.ssr)) {
-                              _ctx.next = 35;
+                              _ctx.next = 62;
                               break;
                             }
                             return _ctx.abrupt("return", {
                               type: "refresh"
                             });
-                          case 35:
+                          case 62:
                             return _ctx.abrupt("return", {
                               type: "next"
                             });
-                          case 36:
+                          case 63:
                           case "end":
                             return _ctx.stop();
                         }
                     },
                     _callee,
                     null,
-                    [[9, 15]]
+                    [
+                      [9, 21, 25, 33],
+                      [26, , 28, 32],
+                      [36, 42]
+                    ]
                   );
                 })
               )();
@@ -6816,11 +6886,17 @@
       });
       exports.getMiddlewareRegex = getMiddlewareRegex;
       var _routeRegex = __webpack_require__(4903);
+      // Identify ^/[param]/ in route string
+      var FIRST_SEGMENT_DYNAMIC = /^\/\[[^/]+?\](?=\/|$)/;
+      var NOT_API_ROUTE = "(?!/api(?:/|$))";
       function getMiddlewareRegex(normalizedRoute) {
         var catchAll =
           arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : true;
         var result = (0, _routeRegex).getParametrizedRoute(normalizedRoute);
-        var catchAllRegex = catchAll ? "(?!_next).*" : "";
+        var notApiRegex = FIRST_SEGMENT_DYNAMIC.test(normalizedRoute)
+          ? NOT_API_ROUTE
+          : "";
+        var catchAllRegex = catchAll ? "(?!_next($|/)).*" : "";
         var catchAllGroupedRegex = catchAll ? "(?:(/.*)?)" : "";
         if ("routeKeys" in result) {
           if (result.parameterizedRoute === "/") {
@@ -6834,10 +6910,12 @@
           return {
             groups: result.groups,
             namedRegex: "^"
+              .concat(notApiRegex)
               .concat(result.namedParameterizedRoute)
               .concat(catchAllGroupedRegex, "$"),
             re: new RegExp(
               "^"
+                .concat(notApiRegex)
                 .concat(result.parameterizedRoute)
                 .concat(catchAllGroupedRegex, "$")
             ),
@@ -6854,6 +6932,7 @@
           groups: {},
           re: new RegExp(
             "^"
+              .concat(notApiRegex)
               .concat(result.parameterizedRoute)
               .concat(catchAllGroupedRegex, "$")
           )
@@ -6891,6 +6970,18 @@
           return _routeRegex.getRouteRegex;
         }
       });
+      Object.defineProperty(exports, "getRoutingItems", {
+        enumerable: true,
+        get: function get() {
+          return _routingItems.getRoutingItems;
+        }
+      });
+      Object.defineProperty(exports, "RoutingItem", {
+        enumerable: true,
+        get: function get() {
+          return _routingItems.RoutingItem;
+        }
+      });
       Object.defineProperty(exports, "getSortedRoutes", {
         enumerable: true,
         get: function get() {
@@ -6906,6 +6997,7 @@
       var _getMiddlewareRegex = __webpack_require__(3072);
       var _routeMatcher = __webpack_require__(3156);
       var _routeRegex = __webpack_require__(4903);
+      var _routingItems = __webpack_require__(7185);
       var _sortedRoutes = __webpack_require__(566);
       var _isDynamic = __webpack_require__(6238); //# sourceMappingURL=index.js.map
 
@@ -7237,6 +7329,101 @@
       /***/
     },
 
+    /***/ 7185: /***/ function(
+      __unused_webpack_module,
+      exports,
+      __webpack_require__
+    ) {
+      "use strict";
+
+      function _arrayLikeToArray(arr, len) {
+        if (len == null || len > arr.length) len = arr.length;
+        for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
+        return arr2;
+      }
+      function _arrayWithoutHoles(arr) {
+        if (Array.isArray(arr)) return _arrayLikeToArray(arr);
+      }
+      function _iterableToArray(iter) {
+        if (
+          (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null) ||
+          iter["@@iterator"] != null
+        )
+          return Array.from(iter);
+      }
+      function _nonIterableSpread() {
+        throw new TypeError(
+          "Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."
+        );
+      }
+      function _toConsumableArray(arr) {
+        return (
+          _arrayWithoutHoles(arr) ||
+          _iterableToArray(arr) ||
+          _unsupportedIterableToArray(arr) ||
+          _nonIterableSpread()
+        );
+      }
+      function _unsupportedIterableToArray(o, minLen) {
+        if (!o) return;
+        if (typeof o === "string") return _arrayLikeToArray(o, minLen);
+        var n = Object.prototype.toString.call(o).slice(8, -1);
+        if (n === "Object" && o.constructor) n = o.constructor.name;
+        if (n === "Map" || n === "Set") return Array.from(n);
+        if (
+          n === "Arguments" ||
+          /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)
+        )
+          return _arrayLikeToArray(o, minLen);
+      }
+      Object.defineProperty(exports, "__esModule", {
+        value: true
+      });
+      exports.getRoutingItems = getRoutingItems;
+      var _getMiddlewareRegex = __webpack_require__(3072);
+      var _routeMatcher = __webpack_require__(3156);
+      var _routeRegex = __webpack_require__(4903);
+      var _sortedRoutes = __webpack_require__(566);
+      var MIDDLEWARE_SUFFIX = "/_middleware";
+      function getRoutingItems(pages, middleware) {
+        // append the suffix so that `getSortedRoutes()` can handle middleware properly
+        var middlewarePages = middleware.map(function(m) {
+          return "".concat(m.page).concat(MIDDLEWARE_SUFFIX);
+        });
+        var middlewareMap = new Map(
+          middleware.map(function(m) {
+            return [m.page, m];
+          })
+        );
+        var sortedRoutes = (0, _sortedRoutes).getSortedRoutes(
+          _toConsumableArray(pages).concat(_toConsumableArray(middlewarePages))
+        );
+        return sortedRoutes.map(function(page) {
+          if (page.endsWith(MIDDLEWARE_SUFFIX)) {
+            var p = page.slice(0, -MIDDLEWARE_SUFFIX.length) || "/";
+            var ssr = middlewareMap.get(p).ssr;
+            return {
+              match: (0, _routeMatcher).getRouteMatcher(
+                (0, _getMiddlewareRegex).getMiddlewareRegex(p, !ssr)
+              ),
+              page: p,
+              ssr: ssr,
+              isMiddleware: true
+            };
+          } else {
+            return {
+              match: (0, _routeMatcher).getRouteMatcher(
+                (0, _routeRegex).getRouteRegex(page)
+              ),
+              page: page
+            };
+          }
+        });
+      } //# sourceMappingURL=routing-items.js.map
+
+      /***/
+    },
+
     /***/ 566: /***/ function(__unused_webpack_module, exports) {
       "use strict";
 
@@ -7311,6 +7498,7 @@
           this.slugName = null;
           this.restSlugName = null;
           this.optionalRestSlugName = null;
+          this.isMiddleware = false;
         }
         _createClass(UrlNode, [
           {
@@ -7345,6 +7533,9 @@
               if (this.optionalRestSlugName !== null) {
                 childrenPaths.splice(childrenPaths.indexOf("[[...]]"), 1);
               }
+              if (this.isMiddleware) {
+                childrenPaths.splice(childrenPaths.indexOf("_middleware"), 1);
+              }
               var routes = childrenPaths
                 .map(function(c) {
                   return _this.children
@@ -7381,10 +7572,21 @@
                 }
                 routes.unshift(r);
               }
-              if (this.restSlugName !== null) {
+              if (this.isMiddleware) {
                 var _routes1;
-                (_routes1 = routes).push.apply(
+                (_routes1 = routes).unshift.apply(
                   _routes1,
+                  _toConsumableArray(
+                    this.children
+                      .get("_middleware")
+                      ._smoosh("".concat(prefix, "_middleware/"))
+                  )
+                );
+              }
+              if (this.restSlugName !== null) {
+                var _routes2;
+                (_routes2 = routes).push.apply(
+                  _routes2,
                   _toConsumableArray(
                     this.children
                       .get("[...]")
@@ -7397,9 +7599,9 @@
                 );
               }
               if (this.optionalRestSlugName !== null) {
-                var _routes2;
-                (_routes2 = routes).push.apply(
-                  _routes2,
+                var _routes3;
+                (_routes3 = routes).push.apply(
+                  _routes3,
                   _toConsumableArray(
                     this.children
                       .get("[[...]]")
@@ -7540,6 +7742,11 @@
                   // nextSegment is overwritten to [] so that it can later be sorted specifically
                   nextSegment = "[]";
                 }
+              } else if (
+                nextSegment === "_middleware" &&
+                urlPaths.length === 1
+              ) {
+                this.isMiddleware = true;
               }
               // If this UrlNode doesn't have the nextSegment yet we create a new child UrlNode
               if (!this.children.has(nextSegment)) {
Diff for index.html
@@ -19,7 +19,7 @@
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/main-31e3f2e995c2cb43.js"
+      src="/_next/static/chunks/main-b5d24bd96df5cedc.js"
       defer=""
     ></script>
     <script
Diff for link.html
@@ -19,7 +19,7 @@
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/main-31e3f2e995c2cb43.js"
+      src="/_next/static/chunks/main-b5d24bd96df5cedc.js"
       defer=""
     ></script>
     <script
Diff for withRouter.html
@@ -19,7 +19,7 @@
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/main-31e3f2e995c2cb43.js"
+      src="/_next/static/chunks/main-b5d24bd96df5cedc.js"
       defer=""
     ></script>
     <script

Default Build with SWC (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
buildDuration 17.5s 17.5s -35ms
buildDurationCached 5.6s 6s ⚠️ +440ms
nodeModulesSize 467 MB 467 MB ⚠️ +9.67 kB
Page Load Tests Overall decrease ⚠️
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
/ failed reqs 0 0
/ total time (seconds) 2.935 2.96 ⚠️ +0.02
/ avg req/sec 851.82 844.47 ⚠️ -7.35
/error-in-render failed reqs 0 0
/error-in-render total time (seconds) 1.336 1.334 0
/error-in-render avg req/sec 1871.31 1874.42 +3.11
Client Bundles (main, webpack) Overall increase ⚠️
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
925.HASH.js gzip 178 B 178 B
framework-HASH.js gzip 42.3 kB 42.3 kB
main-HASH.js gzip 28.2 kB 28.8 kB ⚠️ +530 B
webpack-HASH.js gzip 1.45 kB 1.45 kB
Overall change 72.1 kB 72.7 kB ⚠️ +530 B
Legacy Client Bundles (polyfills)
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
polyfills-HASH.js gzip 31 kB 31 kB
Overall change 31 kB 31 kB
Client Pages
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
_app-HASH.js gzip 1.35 kB 1.35 kB
_error-HASH.js gzip 179 B 179 B
amp-HASH.js gzip 313 B 313 B
css-HASH.js gzip 324 B 324 B
dynamic-HASH.js gzip 2.56 kB 2.56 kB
head-HASH.js gzip 351 B 351 B
hooks-HASH.js gzip 921 B 921 B
image-HASH.js gzip 5.59 kB 5.59 kB
index-HASH.js gzip 261 B 261 B
link-HASH.js gzip 2.33 kB 2.33 kB
routerDirect..HASH.js gzip 322 B 322 B
script-HASH.js gzip 388 B 388 B
withRouter-HASH.js gzip 317 B 317 B
85e02e95b279..7e3.css gzip 107 B 107 B
Overall change 15.3 kB 15.3 kB
Client Build Manifests
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
_buildManifest.js gzip 458 B 458 B
Overall change 458 B 458 B
Rendered Page Sizes Overall decrease ✓
vercel/next.js canary nkzawa/next.js fix-dynamic-middleware-routing.patch Change
index.html gzip 532 B 530 B -2 B
link.html gzip 547 B 544 B -3 B
withRouter.html gzip 528 B 525 B -3 B
Overall change 1.61 kB 1.6 kB -8 B

Diffs

Diff for main-HASH.js
@@ -473,7 +473,7 @@
       var _routeAnnouncer = __webpack_require__(8483);
       var _router1 = __webpack_require__(880);
       var _isError = __webpack_require__(676);
-      var _vitals = __webpack_require__(7185);
+      var _vitals = __webpack_require__(4564);
       var _refresh = __webpack_require__(2129);
       var _imageConfigContext = __webpack_require__(8730);
       function asyncGeneratorStep(
@@ -3197,7 +3197,7 @@
       /***/
     },
 
-    /***/ 7185: /***/ function(
+    /***/ 4564: /***/ function(
       __unused_webpack_module,
       exports,
       __webpack_require__
@@ -4351,8 +4351,8 @@
       var _resolveRewrites = _interopRequireDefault1(__webpack_require__(2431));
       var _routeMatcher = __webpack_require__(3156);
       var _routeRegex = __webpack_require__(4903);
-      var _getMiddlewareRegex = __webpack_require__(3072);
       var _formatUrl = __webpack_require__(7795);
+      var _routingItems = __webpack_require__(7185);
       function _interopRequireDefault1(obj) {
         return obj && obj.__esModule
           ? obj
@@ -6378,8 +6378,16 @@
                 _runtimeJs.default.mark(function _callee() {
                   var asPathname,
                     cleanedAs,
-                    fns,
+                    middlewareList,
+                    middleware,
+                    routingItems,
                     requiresPreflight,
+                    _iteratorNormalCompletion,
+                    _didIteratorError,
+                    _iteratorError,
+                    _iterator,
+                    _step,
+                    item,
                     preflight,
                     parsed,
                     fsPathname,
@@ -6404,58 +6412,116 @@
                             _ctx.next = 4;
                             return _this.pageLoader.getMiddlewareList();
                           case 4:
-                            fns = _ctx.sent;
-                            requiresPreflight = fns.some(function(param) {
+                            middlewareList = _ctx.sent;
+                            middleware = middlewareList.map(function(param) {
                               var _param = _slicedToArray(param, 2),
-                                middleware = _param[0],
-                                isSSR = _param[1];
-                              return (0, _routeMatcher).getRouteMatcher(
-                                (0, _getMiddlewareRegex).getMiddlewareRegex(
-                                  middleware,
-                                  !isSSR
-                                )
-                              )(cleanedAs);
+                                page = _param[0],
+                                ssr = _param[1];
+                              return {
+                                page: page,
+                                ssr: ssr
+                              };
                             });
+                            routingItems = (0, _routingItems).getRoutingItems(
+                              options.pages,
+                              middleware
+                            );
+                            requiresPreflight = false;
+                            (_iteratorNormalCompletion = true),
+                              (_didIteratorError = false),
+                              (_iteratorError = undefined);
+                            _ctx.prev = 9;
+                            _iterator = routingItems[Symbol.iterator]();
+                          case 11:
+                            if (
+                              (_iteratorNormalCompletion = (_step = _iterator.next())
+                                .done)
+                            ) {
+                              _ctx.next = 19;
+                              break;
+                            }
+                            item = _step.value;
+                            if (!item.match(cleanedAs)) {
+                              _ctx.next = 16;
+                              break;
+                            }
+                            if (item.isMiddleware) {
+                              requiresPreflight = true;
+                            }
+                            return _ctx.abrupt("break", 19);
+                          case 16:
+                            _iteratorNormalCompletion = true;
+                            _ctx.next = 11;
+                            break;
+                          case 19:
+                            _ctx.next = 25;
+                            break;
+                          case 21:
+                            _ctx.prev = 21;
+                            _ctx.t0 = _ctx["catch"](9);
+                            _didIteratorError = true;
+                            _iteratorError = _ctx.t0;
+                          case 25:
+                            _ctx.prev = 25;
+                            _ctx.prev = 26;
+                            if (
+                              !_iteratorNormalCompletion &&
+                              _iterator.return != null
+                            ) {
+                              _iterator.return();
+                            }
+                          case 28:
+                            _ctx.prev = 28;
+                            if (!_didIteratorError) {
+                              _ctx.next = 31;
+                              break;
+                            }
+                            throw _iteratorError;
+                          case 31:
+                            return _ctx.finish(28);
+                          case 32:
+                            return _ctx.finish(25);
+                          case 33:
                             if (requiresPreflight) {
-                              _ctx.next = 8;
+                              _ctx.next = 35;
                               break;
                             }
                             return _ctx.abrupt("return", {
                               type: "next"
                             });
-                          case 8:
-                            _ctx.prev = 9;
-                            _ctx.next = 12;
+                          case 35:
+                            _ctx.prev = 36;
+                            _ctx.next = 39;
                             return _this._getPreflightData({
                               preflightHref: options.as,
                               shouldCache: options.cache,
                               isPreview: options.isPreview
                             });
-                          case 12:
+                          case 39:
                             preflight = _ctx.sent;
-                            _ctx.next = 18;
+                            _ctx.next = 45;
                             break;
-                          case 15:
-                            _ctx.prev = 15;
-                            _ctx.t0 = _ctx["catch"](9);
+                          case 42:
+                            _ctx.prev = 42;
+                            _ctx.t1 = _ctx["catch"](36);
                             return _ctx.abrupt("return", {
                               type: "redirect",
                               destination: options.as
                             });
-                          case 18:
+                          case 45:
                             if (!preflight.rewrite) {
-                              _ctx.next = 27;
+                              _ctx.next = 54;
                               break;
                             }
                             if (preflight.rewrite.startsWith("/")) {
-                              _ctx.next = 21;
+                              _ctx.next = 48;
                               break;
                             }
                             return _ctx.abrupt("return", {
                               type: "redirect",
                               destination: options.as
                             });
-                          case 21:
+                          case 48:
                             parsed = (0, _parseRelativeUrl).parseRelativeUrl(
                               (0, _normalizeLocalePath).normalizeLocalePath(
                                 hasBasePath(preflight.rewrite)
@@ -6490,13 +6556,13 @@
                               matchedPage: matchedPage,
                               resolvedHref: resolvedHref
                             });
-                          case 27:
+                          case 54:
                             if (!preflight.redirect) {
-                              _ctx.next = 33;
+                              _ctx.next = 60;
                               break;
                             }
                             if (!preflight.redirect.startsWith("/")) {
-                              _ctx.next = 32;
+                              _ctx.next = 59;
                               break;
                             }
                             cleanRedirect = (0,
@@ -6520,31 +6586,35 @@
                               newUrl: newUrl,
                               newAs: newAs
                             });
-                          case 32:
+                          case 59:
                             return _ctx.abrupt("return", {
                               type: "redirect",
                               destination: preflight.redirect
                             });
-                          case 33:
+                          case 60:
                             if (!(preflight.refresh && !preflight.ssr)) {
-                              _ctx.next = 35;
+                              _ctx.next = 62;
                               break;
                             }
                             return _ctx.abrupt("return", {
                               type: "refresh"
                             });
-                          case 35:
+                          case 62:
                             return _ctx.abrupt("return", {
                               type: "next"
                             });
-                          case 36:
+                          case 63:
                           case "end":
                             return _ctx.stop();
                         }
                     },
                     _callee,
                     null,
-                    [[9, 15]]
+                    [
+                      [9, 21, 25, 33],
+                      [26, , 28, 32],
+                      [36, 42]
+                    ]
                   );
                 })
               )();
@@ -6816,11 +6886,17 @@
       });
       exports.getMiddlewareRegex = getMiddlewareRegex;
       var _routeRegex = __webpack_require__(4903);
+      // Identify ^/[param]/ in route string
+      var FIRST_SEGMENT_DYNAMIC = /^\/\[[^/]+?\](?=\/|$)/;
+      var NOT_API_ROUTE = "(?!/api(?:/|$))";
       function getMiddlewareRegex(normalizedRoute) {
         var catchAll =
           arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : true;
         var result = (0, _routeRegex).getParametrizedRoute(normalizedRoute);
-        var catchAllRegex = catchAll ? "(?!_next).*" : "";
+        var notApiRegex = FIRST_SEGMENT_DYNAMIC.test(normalizedRoute)
+          ? NOT_API_ROUTE
+          : "";
+        var catchAllRegex = catchAll ? "(?!_next($|/)).*" : "";
         var catchAllGroupedRegex = catchAll ? "(?:(/.*)?)" : "";
         if ("routeKeys" in result) {
           if (result.parameterizedRoute === "/") {
@@ -6834,10 +6910,12 @@
           return {
             groups: result.groups,
             namedRegex: "^"
+              .concat(notApiRegex)
               .concat(result.namedParameterizedRoute)
               .concat(catchAllGroupedRegex, "$"),
             re: new RegExp(
               "^"
+                .concat(notApiRegex)
                 .concat(result.parameterizedRoute)
                 .concat(catchAllGroupedRegex, "$")
             ),
@@ -6854,6 +6932,7 @@
           groups: {},
           re: new RegExp(
             "^"
+              .concat(notApiRegex)
               .concat(result.parameterizedRoute)
               .concat(catchAllGroupedRegex, "$")
           )
@@ -6891,6 +6970,18 @@
           return _routeRegex.getRouteRegex;
         }
       });
+      Object.defineProperty(exports, "getRoutingItems", {
+        enumerable: true,
+        get: function get() {
+          return _routingItems.getRoutingItems;
+        }
+      });
+      Object.defineProperty(exports, "RoutingItem", {
+        enumerable: true,
+        get: function get() {
+          return _routingItems.RoutingItem;
+        }
+      });
       Object.defineProperty(exports, "getSortedRoutes", {
         enumerable: true,
         get: function get() {
@@ -6906,6 +6997,7 @@
       var _getMiddlewareRegex = __webpack_require__(3072);
       var _routeMatcher = __webpack_require__(3156);
       var _routeRegex = __webpack_require__(4903);
+      var _routingItems = __webpack_require__(7185);
       var _sortedRoutes = __webpack_require__(566);
       var _isDynamic = __webpack_require__(6238); //# sourceMappingURL=index.js.map
 
@@ -7237,6 +7329,101 @@
       /***/
     },
 
+    /***/ 7185: /***/ function(
+      __unused_webpack_module,
+      exports,
+      __webpack_require__
+    ) {
+      "use strict";
+
+      function _arrayLikeToArray(arr, len) {
+        if (len == null || len > arr.length) len = arr.length;
+        for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
+        return arr2;
+      }
+      function _arrayWithoutHoles(arr) {
+        if (Array.isArray(arr)) return _arrayLikeToArray(arr);
+      }
+      function _iterableToArray(iter) {
+        if (
+          (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null) ||
+          iter["@@iterator"] != null
+        )
+          return Array.from(iter);
+      }
+      function _nonIterableSpread() {
+        throw new TypeError(
+          "Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."
+        );
+      }
+      function _toConsumableArray(arr) {
+        return (
+          _arrayWithoutHoles(arr) ||
+          _iterableToArray(arr) ||
+          _unsupportedIterableToArray(arr) ||
+          _nonIterableSpread()
+        );
+      }
+      function _unsupportedIterableToArray(o, minLen) {
+        if (!o) return;
+        if (typeof o === "string") return _arrayLikeToArray(o, minLen);
+        var n = Object.prototype.toString.call(o).slice(8, -1);
+        if (n === "Object" && o.constructor) n = o.constructor.name;
+        if (n === "Map" || n === "Set") return Array.from(n);
+        if (
+          n === "Arguments" ||
+          /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)
+        )
+          return _arrayLikeToArray(o, minLen);
+      }
+      Object.defineProperty(exports, "__esModule", {
+        value: true
+      });
+      exports.getRoutingItems = getRoutingItems;
+      var _getMiddlewareRegex = __webpack_require__(3072);
+      var _routeMatcher = __webpack_require__(3156);
+      var _routeRegex = __webpack_require__(4903);
+      var _sortedRoutes = __webpack_require__(566);
+      var MIDDLEWARE_SUFFIX = "/_middleware";
+      function getRoutingItems(pages, middleware) {
+        // append the suffix so that `getSortedRoutes()` can handle middleware properly
+        var middlewarePages = middleware.map(function(m) {
+          return "".concat(m.page).concat(MIDDLEWARE_SUFFIX);
+        });
+        var middlewareMap = new Map(
+          middleware.map(function(m) {
+            return [m.page, m];
+          })
+        );
+        var sortedRoutes = (0, _sortedRoutes).getSortedRoutes(
+          _toConsumableArray(pages).concat(_toConsumableArray(middlewarePages))
+        );
+        return sortedRoutes.map(function(page) {
+          if (page.endsWith(MIDDLEWARE_SUFFIX)) {
+            var p = page.slice(0, -MIDDLEWARE_SUFFIX.length) || "/";
+            var ssr = middlewareMap.get(p).ssr;
+            return {
+              match: (0, _routeMatcher).getRouteMatcher(
+                (0, _getMiddlewareRegex).getMiddlewareRegex(p, !ssr)
+              ),
+              page: p,
+              ssr: ssr,
+              isMiddleware: true
+            };
+          } else {
+            return {
+              match: (0, _routeMatcher).getRouteMatcher(
+                (0, _routeRegex).getRouteRegex(page)
+              ),
+              page: page
+            };
+          }
+        });
+      } //# sourceMappingURL=routing-items.js.map
+
+      /***/
+    },
+
     /***/ 566: /***/ function(__unused_webpack_module, exports) {
       "use strict";
 
@@ -7311,6 +7498,7 @@
           this.slugName = null;
           this.restSlugName = null;
           this.optionalRestSlugName = null;
+          this.isMiddleware = false;
         }
         _createClass(UrlNode, [
           {
@@ -7345,6 +7533,9 @@
               if (this.optionalRestSlugName !== null) {
                 childrenPaths.splice(childrenPaths.indexOf("[[...]]"), 1);
               }
+              if (this.isMiddleware) {
+                childrenPaths.splice(childrenPaths.indexOf("_middleware"), 1);
+              }
               var routes = childrenPaths
                 .map(function(c) {
                   return _this.children
@@ -7381,10 +7572,21 @@
                 }
                 routes.unshift(r);
               }
-              if (this.restSlugName !== null) {
+              if (this.isMiddleware) {
                 var _routes1;
-                (_routes1 = routes).push.apply(
+                (_routes1 = routes).unshift.apply(
                   _routes1,
+                  _toConsumableArray(
+                    this.children
+                      .get("_middleware")
+                      ._smoosh("".concat(prefix, "_middleware/"))
+                  )
+                );
+              }
+              if (this.restSlugName !== null) {
+                var _routes2;
+                (_routes2 = routes).push.apply(
+                  _routes2,
                   _toConsumableArray(
                     this.children
                       .get("[...]")
@@ -7397,9 +7599,9 @@
                 );
               }
               if (this.optionalRestSlugName !== null) {
-                var _routes2;
-                (_routes2 = routes).push.apply(
-                  _routes2,
+                var _routes3;
+                (_routes3 = routes).push.apply(
+                  _routes3,
                   _toConsumableArray(
                     this.children
                       .get("[[...]]")
@@ -7540,6 +7742,11 @@
                   // nextSegment is overwritten to [] so that it can later be sorted specifically
                   nextSegment = "[]";
                 }
+              } else if (
+                nextSegment === "_middleware" &&
+                urlPaths.length === 1
+              ) {
+                this.isMiddleware = true;
               }
               // If this UrlNode doesn't have the nextSegment yet we create a new child UrlNode
               if (!this.children.has(nextSegment)) {
Diff for index.html
@@ -19,7 +19,7 @@
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/main-31e3f2e995c2cb43.js"
+      src="/_next/static/chunks/main-b5d24bd96df5cedc.js"
       defer=""
     ></script>
     <script
Diff for link.html
@@ -19,7 +19,7 @@
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/main-31e3f2e995c2cb43.js"
+      src="/_next/static/chunks/main-b5d24bd96df5cedc.js"
       defer=""
     ></script>
     <script
Diff for withRouter.html
@@ -19,7 +19,7 @@
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/main-31e3f2e995c2cb43.js"
+      src="/_next/static/chunks/main-b5d24bd96df5cedc.js"
       defer=""
     ></script>
     <script
Commit: 2ed828f

@ijjk ijjk merged commit 53d1b00 into vercel:canary Mar 28, 2022
@leo
Copy link
Contributor

leo commented Mar 29, 2022

@nkzawa @ijjk I believe this change has caused a new bug: #35686

nkzawa added a commit to nkzawa/next.js that referenced this pull request Apr 6, 2022
kodiakhq bot pushed a commit that referenced this pull request Apr 6, 2022
colinhacks pushed a commit to colinhacks/next.js that referenced this pull request Apr 14, 2022
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Apr 28, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
4 participants