-
Notifications
You must be signed in to change notification settings - Fork 27.1k
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 dynamic routes with pages under index folder #32440
Merged
Merged
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
huozhi
force-pushed
the
fix/index-dynamic-routes
branch
from
December 13, 2021 10:51
57ad0d4
to
3b49034
Compare
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
huozhi
force-pushed
the
fix/index-dynamic-routes
branch
from
December 13, 2021 14:41
2f29e0f
to
668a33d
Compare
This comment has been minimized.
This comment has been minimized.
ijjk
reviewed
Dec 13, 2021
Co-authored-by: JJ Kasper <jj@jjsweb.site>
ijjk
previously approved these changes
Dec 13, 2021
Failing test suitesCommit: 1676ece test/integration/react-streaming-and-server-components/test/index.test.js
Expand output● concurrentFeatures - dev › should support next/link
|
This comment has been minimized.
This comment has been minimized.
ijjk
approved these changes
Dec 13, 2021
Stats from current PRDefault Build (Increase detected
|
vercel/next.js canary | huozhi/next.js fix/index-dynamic-routes | Change | |
---|---|---|---|
buildDuration | 18.1s | 18.4s | |
buildDurationCached | 3.5s | 3.4s | -74ms |
nodeModulesSize | 350 MB | 350 MB |
Page Load Tests Overall increase ✓
vercel/next.js canary | huozhi/next.js fix/index-dynamic-routes | Change | |
---|---|---|---|
/ failed reqs | 0 | 0 | ✓ |
/ total time (seconds) | 2.872 | 2.943 | |
/ avg req/sec | 870.56 | 849.33 | |
/error-in-render failed reqs | 0 | 0 | ✓ |
/error-in-render total time (seconds) | 1.367 | 1.337 | -0.03 |
/error-in-render avg req/sec | 1829.07 | 1869.98 | +40.91 |
Client Bundles (main, webpack, commons) Overall increase ⚠️
vercel/next.js canary | huozhi/next.js fix/index-dynamic-routes | Change | |
---|---|---|---|
450.HASH.js gzip | 179 B | 179 B | ✓ |
framework-HASH.js gzip | 42.2 kB | 42.2 kB | ✓ |
main-HASH.js gzip | 28.9 kB | 30.2 kB | |
webpack-HASH.js gzip | 1.45 kB | 1.45 kB | ✓ |
Overall change | 72.8 kB | 74 kB |
Legacy Client Bundles (polyfills)
vercel/next.js canary | huozhi/next.js fix/index-dynamic-routes | Change | |
---|---|---|---|
polyfills-HASH.js gzip | 31 kB | 31 kB | ✓ |
Overall change | 31 kB | 31 kB | ✓ |
Client Pages
vercel/next.js canary | huozhi/next.js fix/index-dynamic-routes | Change | |
---|---|---|---|
_app-HASH.js gzip | 1.37 kB | 1.37 kB | ✓ |
_error-HASH.js gzip | 194 B | 194 B | ✓ |
amp-HASH.js gzip | 312 B | 312 B | ✓ |
css-HASH.js gzip | 326 B | 326 B | ✓ |
dynamic-HASH.js gzip | 2.39 kB | 2.39 kB | ✓ |
head-HASH.js gzip | 350 B | 350 B | ✓ |
hooks-HASH.js gzip | 919 B | 919 B | ✓ |
image-HASH.js gzip | 4.73 kB | 4.73 kB | ✓ |
index-HASH.js gzip | 263 B | 263 B | ✓ |
link-HASH.js gzip | 2.13 kB | 2.13 kB | ✓ |
routerDirect..HASH.js gzip | 321 B | 321 B | ✓ |
script-HASH.js gzip | 383 B | 383 B | ✓ |
withRouter-HASH.js gzip | 318 B | 318 B | ✓ |
85e02e95b279..7e3.css gzip | 107 B | 107 B | ✓ |
Overall change | 14.1 kB | 14.1 kB | ✓ |
Client Build Manifests
vercel/next.js canary | huozhi/next.js fix/index-dynamic-routes | Change | |
---|---|---|---|
_buildManifest.js gzip | 459 B | 459 B | ✓ |
Overall change | 459 B | 459 B | ✓ |
Rendered Page Sizes Overall increase ⚠️
vercel/next.js canary | huozhi/next.js fix/index-dynamic-routes | Change | |
---|---|---|---|
index.html gzip | 531 B | 532 B | |
link.html gzip | 545 B | 547 B | |
withRouter.html gzip | 526 B | 527 B | |
Overall change | 1.6 kB | 1.61 kB |
Diffs
Diff for main-HASH.js
@@ -6525,6 +6525,55 @@
/***/
},
+ /***/ 418: /***/ function(
+ __unused_webpack_module,
+ exports,
+ __webpack_require__
+ ) {
+ "use strict";
+
+ Object.defineProperty(exports, "__esModule", {
+ value: true
+ });
+ Object.defineProperty(exports, "getMiddlewareRegex", {
+ enumerable: true,
+ get: function get() {
+ return _getMiddlewareRegex.getMiddlewareRegex;
+ }
+ });
+ Object.defineProperty(exports, "getRouteMatcher", {
+ enumerable: true,
+ get: function get() {
+ return _routeMatcher.getRouteMatcher;
+ }
+ });
+ Object.defineProperty(exports, "getRouteRegex", {
+ enumerable: true,
+ get: function get() {
+ return _routeRegex.getRouteRegex;
+ }
+ });
+ Object.defineProperty(exports, "getSortedRoutes", {
+ enumerable: true,
+ get: function get() {
+ return _sortedRoutes.getSortedRoutes;
+ }
+ });
+ Object.defineProperty(exports, "isDynamicRoute", {
+ enumerable: true,
+ get: function get() {
+ return _isDynamic.isDynamicRoute;
+ }
+ });
+ var _getMiddlewareRegex = __webpack_require__(9820);
+ var _routeMatcher = __webpack_require__(3888);
+ var _routeRegex = __webpack_require__(4095);
+ var _sortedRoutes = __webpack_require__(3907);
+ var _isDynamic = __webpack_require__(8689); //# sourceMappingURL=index.js.map
+
+ /***/
+ },
+
/***/ 8689: /***/ function(__unused_webpack_module, exports) {
"use strict";
@@ -6850,6 +6899,345 @@
/***/
},
+ /***/ 3907: /***/ function(__unused_webpack_module, exports) {
+ "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 _classCallCheck(instance, Constructor) {
+ if (!(instance instanceof Constructor)) {
+ throw new TypeError("Cannot call a class as a function");
+ }
+ }
+ function _defineProperties(target, props) {
+ for (var i = 0; i < props.length; i++) {
+ var descriptor = props[i];
+ descriptor.enumerable = descriptor.enumerable || false;
+ descriptor.configurable = true;
+ if ("value" in descriptor) descriptor.writable = true;
+ Object.defineProperty(target, descriptor.key, descriptor);
+ }
+ }
+ function _createClass(Constructor, protoProps, staticProps) {
+ if (protoProps) _defineProperties(Constructor.prototype, protoProps);
+ if (staticProps) _defineProperties(Constructor, staticProps);
+ return Constructor;
+ }
+ 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.getSortedRoutes = getSortedRoutes;
+ var UrlNode = /*#__PURE__*/ (function() {
+ function UrlNode() {
+ _classCallCheck(this, UrlNode);
+ this.placeholder = true;
+ this.children = new Map();
+ this.slugName = null;
+ this.restSlugName = null;
+ this.optionalRestSlugName = null;
+ }
+ _createClass(UrlNode, [
+ {
+ key: "insert",
+ value: function insert(urlPath) {
+ this._insert(urlPath.split("/").filter(Boolean), [], false);
+ }
+ },
+ {
+ key: "smoosh",
+ value: function smoosh() {
+ return this._smoosh();
+ }
+ },
+ {
+ key: "_smoosh",
+ value: function _smoosh() {
+ var prefix =
+ arguments.length > 0 && arguments[0] !== void 0
+ ? arguments[0]
+ : "/";
+ var _this = this;
+ var childrenPaths = _toConsumableArray(
+ this.children.keys()
+ ).sort();
+ if (this.slugName !== null) {
+ childrenPaths.splice(childrenPaths.indexOf("[]"), 1);
+ }
+ if (this.restSlugName !== null) {
+ childrenPaths.splice(childrenPaths.indexOf("[...]"), 1);
+ }
+ if (this.optionalRestSlugName !== null) {
+ childrenPaths.splice(childrenPaths.indexOf("[[...]]"), 1);
+ }
+ var routes = childrenPaths
+ .map(function(c) {
+ return _this.children
+ .get(c)
+ ._smoosh("".concat(prefix).concat(c, "/"));
+ })
+ .reduce(function(prev, curr) {
+ return _toConsumableArray(prev).concat(
+ _toConsumableArray(curr)
+ );
+ }, []);
+ if (this.slugName !== null) {
+ var _routes;
+ (_routes = routes).push.apply(
+ _routes,
+ _toConsumableArray(
+ this.children
+ .get("[]")
+ ._smoosh(
+ "".concat(prefix, "[").concat(this.slugName, "]/")
+ )
+ )
+ );
+ }
+ if (!this.placeholder) {
+ var r = prefix === "/" ? "/" : prefix.slice(0, -1);
+ if (this.optionalRestSlugName != null) {
+ throw new Error(
+ 'You cannot define a route with the same specificity as a optional catch-all route ("'
+ .concat(r, '" and "')
+ .concat(r, "[[...")
+ .concat(this.optionalRestSlugName, ']]").')
+ );
+ }
+ routes.unshift(r);
+ }
+ if (this.restSlugName !== null) {
+ var _routes1;
+ (_routes1 = routes).push.apply(
+ _routes1,
+ _toConsumableArray(
+ this.children
+ .get("[...]")
+ ._smoosh(
+ ""
+ .concat(prefix, "[...")
+ .concat(this.restSlugName, "]/")
+ )
+ )
+ );
+ }
+ if (this.optionalRestSlugName !== null) {
+ var _routes2;
+ (_routes2 = routes).push.apply(
+ _routes2,
+ _toConsumableArray(
+ this.children
+ .get("[[...]]")
+ ._smoosh(
+ ""
+ .concat(prefix, "[[...")
+ .concat(this.optionalRestSlugName, "]]/")
+ )
+ )
+ );
+ }
+ return routes;
+ }
+ },
+ {
+ key: "_insert",
+ value: function _insert(urlPaths, slugNames, isCatchAll) {
+ if (urlPaths.length === 0) {
+ this.placeholder = false;
+ return;
+ }
+ if (isCatchAll) {
+ throw new Error("Catch-all must be the last part of the URL.");
+ }
+ // The next segment in the urlPaths list
+ var nextSegment = urlPaths[0];
+ // Check if the segment matches `[something]`
+ if (nextSegment.startsWith("[") && nextSegment.endsWith("]")) {
+ var handleSlug = function handleSlug(previousSlug, nextSlug) {
+ if (previousSlug !== null) {
+ // If the specific segment already has a slug but the slug is not `something`
+ // This prevents collisions like:
+ // pages/[post]/index.js
+ // pages/[id]/index.js
+ // Because currently multiple dynamic params on the same segment level are not supported
+ if (previousSlug !== nextSlug) {
+ // TODO: This error seems to be confusing for users, needs an error link, the description can be based on above comment.
+ throw new Error(
+ "You cannot use different slug names for the same dynamic path ('"
+ .concat(previousSlug, "' !== '")
+ .concat(nextSlug, "').")
+ );
+ }
+ }
+ slugNames.forEach(function(slug) {
+ if (slug === nextSlug) {
+ throw new Error(
+ 'You cannot have the same slug name "'.concat(
+ nextSlug,
+ '" repeat within a single dynamic path'
+ )
+ );
+ }
+ if (
+ slug.replace(/\W/g, "") === nextSegment.replace(/\W/g, "")
+ ) {
+ throw new Error(
+ 'You cannot have the slug names "'
+ .concat(slug, '" and "')
+ .concat(
+ nextSlug,
+ '" differ only by non-word symbols within a single dynamic path'
+ )
+ );
+ }
+ });
+ slugNames.push(nextSlug);
+ };
+ // Strip `[` and `]`, leaving only `something`
+ var segmentName = nextSegment.slice(1, -1);
+ var isOptional = false;
+ if (segmentName.startsWith("[") && segmentName.endsWith("]")) {
+ // Strip optional `[` and `]`, leaving only `something`
+ segmentName = segmentName.slice(1, -1);
+ isOptional = true;
+ }
+ if (segmentName.startsWith("...")) {
+ // Strip `...`, leaving only `something`
+ segmentName = segmentName.substring(3);
+ isCatchAll = true;
+ }
+ if (segmentName.startsWith("[") || segmentName.endsWith("]")) {
+ throw new Error(
+ "Segment names may not start or end with extra brackets ('".concat(
+ segmentName,
+ "')."
+ )
+ );
+ }
+ if (segmentName.startsWith(".")) {
+ throw new Error(
+ "Segment names may not start with erroneous periods ('".concat(
+ segmentName,
+ "')."
+ )
+ );
+ }
+ if (isCatchAll) {
+ if (isOptional) {
+ if (this.restSlugName != null) {
+ throw new Error(
+ 'You cannot use both an required and optional catch-all route at the same level ("[...'
+ .concat(this.restSlugName, ']" and "')
+ .concat(urlPaths[0], '" ).')
+ );
+ }
+ handleSlug(this.optionalRestSlugName, segmentName);
+ // slugName is kept as it can only be one particular slugName
+ this.optionalRestSlugName = segmentName;
+ // nextSegment is overwritten to [[...]] so that it can later be sorted specifically
+ nextSegment = "[[...]]";
+ } else {
+ if (this.optionalRestSlugName != null) {
+ throw new Error(
+ 'You cannot use both an optional and required catch-all route at the same level ("[[...'
+ .concat(this.optionalRestSlugName, ']]" and "')
+ .concat(urlPaths[0], '").')
+ );
+ }
+ handleSlug(this.restSlugName, segmentName);
+ // slugName is kept as it can only be one particular slugName
+ this.restSlugName = segmentName;
+ // nextSegment is overwritten to [...] so that it can later be sorted specifically
+ nextSegment = "[...]";
+ }
+ } else {
+ if (isOptional) {
+ throw new Error(
+ 'Optional route parameters are not yet supported ("'.concat(
+ urlPaths[0],
+ '").'
+ )
+ );
+ }
+ handleSlug(this.slugName, segmentName);
+ // slugName is kept as it can only be one particular slugName
+ this.slugName = segmentName;
+ // nextSegment is overwritten to [] so that it can later be sorted specifically
+ nextSegment = "[]";
+ }
+ }
+ // If this UrlNode doesn't have the nextSegment yet we create a new child UrlNode
+ if (!this.children.has(nextSegment)) {
+ this.children.set(nextSegment, new UrlNode());
+ }
+ this.children
+ .get(nextSegment)
+ ._insert(urlPaths.slice(1), slugNames, isCatchAll);
+ }
+ }
+ ]);
+ return UrlNode;
+ })();
+ function getSortedRoutes(normalizedPages) {
+ // First the UrlNode is created, and every UrlNode can have only 1 dynamic segment
+ // Eg you can't have pages/[post]/abc.js and pages/[hello]/something-else.js
+ // Only 1 dynamic segment per nesting level
+ // So in the case that is test/integration/dynamic-routing it'll be this:
+ // pages/[post]/comments.js
+ // pages/blog/[post]/comment/[id].js
+ // Both are fine because `pages/[post]` and `pages/blog` are on the same level
+ // So in this case `UrlNode` created here has `this.slugName === 'post'`
+ // And since your PR passed through `slugName` as an array basically it'd including it in too many possibilities
+ // Instead what has to be passed through is the upwards path's dynamic names
+ var root = new UrlNode();
+ // Here the `root` gets injected multiple paths, and insert will break them up into sublevels
+ normalizedPages.forEach(function(pagePath) {
+ return root.insert(pagePath);
+ });
+ // Smoosh will then sort those sublevels up to the point where you get the correct route definition priority
+ return root.smoosh();
+ } //# sourceMappingURL=sorted-routes.js.map
+
+ /***/
+ },
+
/***/ 8027: /***/ function(__unused_webpack_module, exports) {
"use strict";
@@ -7913,7 +8301,11 @@
/***/
},
- /***/ 4522: /***/ function(__unused_webpack_module, exports) {
+ /***/ 4522: /***/ function(
+ __unused_webpack_module,
+ exports,
+ __webpack_require__
+ ) {
"use strict";
Object.defineProperty(exports, "__esModule", {
@@ -7921,12 +8313,13 @@
});
exports.normalizePathSep = normalizePathSep;
exports.denormalizePagePath = denormalizePagePath;
+ var _utils = __webpack_require__(418);
function normalizePathSep(path) {
return path.replace(/\\/g, "/");
}
function denormalizePagePath(page) {
page = normalizePathSep(page);
- if (page.startsWith("/index/")) {
+ if (page.startsWith("/index/") && !(0, _utils).isDynamicRoute(page)) {
page = page.slice(6);
} else if (page === "/index") {
page = "/";
Diff for index.html
@@ -19,7 +19,7 @@
defer=""
></script>
<script
- src="/_next/static/chunks/main-265c59c213a49f1c.js"
+ src="/_next/static/chunks/main-92a7810899e6ca71.js"
defer=""
></script>
<script
Diff for link.html
@@ -19,7 +19,7 @@
defer=""
></script>
<script
- src="/_next/static/chunks/main-265c59c213a49f1c.js"
+ src="/_next/static/chunks/main-92a7810899e6ca71.js"
defer=""
></script>
<script
Diff for withRouter.html
@@ -19,7 +19,7 @@
defer=""
></script>
<script
- src="/_next/static/chunks/main-265c59c213a49f1c.js"
+ src="/_next/static/chunks/main-92a7810899e6ca71.js"
defer=""
></script>
<script
Default Build with SWC (Increase detected ⚠️ )
General Overall increase ⚠️
vercel/next.js canary | huozhi/next.js fix/index-dynamic-routes | Change | |
---|---|---|---|
buildDuration | 19.5s | 19.6s | |
buildDurationCached | 3.5s | 3.4s | -149ms |
nodeModulesSize | 350 MB | 350 MB |
Page Load Tests Overall increase ✓
vercel/next.js canary | huozhi/next.js fix/index-dynamic-routes | Change | |
---|---|---|---|
/ failed reqs | 0 | 0 | ✓ |
/ total time (seconds) | 2.917 | 2.924 | |
/ avg req/sec | 857.17 | 855 | |
/error-in-render failed reqs | 0 | 0 | ✓ |
/error-in-render total time (seconds) | 1.344 | 1.301 | -0.04 |
/error-in-render avg req/sec | 1860.72 | 1921.01 | +60.29 |
Client Bundles (main, webpack, commons) Overall increase ⚠️
vercel/next.js canary | huozhi/next.js fix/index-dynamic-routes | Change | |
---|---|---|---|
450.HASH.js gzip | 179 B | 179 B | ✓ |
framework-HASH.js gzip | 42.3 kB | 42.3 kB | ✓ |
main-HASH.js gzip | 29.1 kB | 30.3 kB | |
webpack-HASH.js gzip | 1.44 kB | 1.44 kB | ✓ |
Overall change | 73 kB | 74.2 kB |
Legacy Client Bundles (polyfills)
vercel/next.js canary | huozhi/next.js fix/index-dynamic-routes | Change | |
---|---|---|---|
polyfills-HASH.js gzip | 31 kB | 31 kB | ✓ |
Overall change | 31 kB | 31 kB | ✓ |
Client Pages
vercel/next.js canary | huozhi/next.js fix/index-dynamic-routes | Change | |
---|---|---|---|
_app-HASH.js gzip | 1.35 kB | 1.35 kB | ✓ |
_error-HASH.js gzip | 180 B | 180 B | ✓ |
amp-HASH.js gzip | 305 B | 305 B | ✓ |
css-HASH.js gzip | 321 B | 321 B | ✓ |
dynamic-HASH.js gzip | 2.39 kB | 2.39 kB | ✓ |
head-HASH.js gzip | 342 B | 342 B | ✓ |
hooks-HASH.js gzip | 906 B | 906 B | ✓ |
image-HASH.js gzip | 4.75 kB | 4.75 kB | ✓ |
index-HASH.js gzip | 256 B | 256 B | ✓ |
link-HASH.js gzip | 2.19 kB | 2.19 kB | ✓ |
routerDirect..HASH.js gzip | 314 B | 314 B | ✓ |
script-HASH.js gzip | 375 B | 375 B | ✓ |
withRouter-HASH.js gzip | 309 B | 309 B | ✓ |
85e02e95b279..7e3.css gzip | 107 B | 107 B | ✓ |
Overall change | 14.1 kB | 14.1 kB | ✓ |
Client Build Manifests
vercel/next.js canary | huozhi/next.js fix/index-dynamic-routes | Change | |
---|---|---|---|
_buildManifest.js gzip | 458 B | 458 B | ✓ |
Overall change | 458 B | 458 B | ✓ |
Rendered Page Sizes
vercel/next.js canary | huozhi/next.js fix/index-dynamic-routes | Change | |
---|---|---|---|
index.html gzip | 533 B | 533 B | ✓ |
link.html gzip | 546 B | 546 B | ✓ |
withRouter.html gzip | 527 B | 527 B | ✓ |
Overall change | 1.61 kB | 1.61 kB | ✓ |
Diffs
Diff for main-HASH.js
@@ -6525,6 +6525,55 @@
/***/
},
+ /***/ 418: /***/ function(
+ __unused_webpack_module,
+ exports,
+ __webpack_require__
+ ) {
+ "use strict";
+
+ Object.defineProperty(exports, "__esModule", {
+ value: true
+ });
+ Object.defineProperty(exports, "getMiddlewareRegex", {
+ enumerable: true,
+ get: function get() {
+ return _getMiddlewareRegex.getMiddlewareRegex;
+ }
+ });
+ Object.defineProperty(exports, "getRouteMatcher", {
+ enumerable: true,
+ get: function get() {
+ return _routeMatcher.getRouteMatcher;
+ }
+ });
+ Object.defineProperty(exports, "getRouteRegex", {
+ enumerable: true,
+ get: function get() {
+ return _routeRegex.getRouteRegex;
+ }
+ });
+ Object.defineProperty(exports, "getSortedRoutes", {
+ enumerable: true,
+ get: function get() {
+ return _sortedRoutes.getSortedRoutes;
+ }
+ });
+ Object.defineProperty(exports, "isDynamicRoute", {
+ enumerable: true,
+ get: function get() {
+ return _isDynamic.isDynamicRoute;
+ }
+ });
+ var _getMiddlewareRegex = __webpack_require__(9820);
+ var _routeMatcher = __webpack_require__(3888);
+ var _routeRegex = __webpack_require__(4095);
+ var _sortedRoutes = __webpack_require__(3907);
+ var _isDynamic = __webpack_require__(8689); //# sourceMappingURL=index.js.map
+
+ /***/
+ },
+
/***/ 8689: /***/ function(__unused_webpack_module, exports) {
"use strict";
@@ -6850,6 +6899,345 @@
/***/
},
+ /***/ 3907: /***/ function(__unused_webpack_module, exports) {
+ "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 _classCallCheck(instance, Constructor) {
+ if (!(instance instanceof Constructor)) {
+ throw new TypeError("Cannot call a class as a function");
+ }
+ }
+ function _defineProperties(target, props) {
+ for (var i = 0; i < props.length; i++) {
+ var descriptor = props[i];
+ descriptor.enumerable = descriptor.enumerable || false;
+ descriptor.configurable = true;
+ if ("value" in descriptor) descriptor.writable = true;
+ Object.defineProperty(target, descriptor.key, descriptor);
+ }
+ }
+ function _createClass(Constructor, protoProps, staticProps) {
+ if (protoProps) _defineProperties(Constructor.prototype, protoProps);
+ if (staticProps) _defineProperties(Constructor, staticProps);
+ return Constructor;
+ }
+ 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.getSortedRoutes = getSortedRoutes;
+ var UrlNode = /*#__PURE__*/ (function() {
+ function UrlNode() {
+ _classCallCheck(this, UrlNode);
+ this.placeholder = true;
+ this.children = new Map();
+ this.slugName = null;
+ this.restSlugName = null;
+ this.optionalRestSlugName = null;
+ }
+ _createClass(UrlNode, [
+ {
+ key: "insert",
+ value: function insert(urlPath) {
+ this._insert(urlPath.split("/").filter(Boolean), [], false);
+ }
+ },
+ {
+ key: "smoosh",
+ value: function smoosh() {
+ return this._smoosh();
+ }
+ },
+ {
+ key: "_smoosh",
+ value: function _smoosh() {
+ var prefix =
+ arguments.length > 0 && arguments[0] !== void 0
+ ? arguments[0]
+ : "/";
+ var _this = this;
+ var childrenPaths = _toConsumableArray(
+ this.children.keys()
+ ).sort();
+ if (this.slugName !== null) {
+ childrenPaths.splice(childrenPaths.indexOf("[]"), 1);
+ }
+ if (this.restSlugName !== null) {
+ childrenPaths.splice(childrenPaths.indexOf("[...]"), 1);
+ }
+ if (this.optionalRestSlugName !== null) {
+ childrenPaths.splice(childrenPaths.indexOf("[[...]]"), 1);
+ }
+ var routes = childrenPaths
+ .map(function(c) {
+ return _this.children
+ .get(c)
+ ._smoosh("".concat(prefix).concat(c, "/"));
+ })
+ .reduce(function(prev, curr) {
+ return _toConsumableArray(prev).concat(
+ _toConsumableArray(curr)
+ );
+ }, []);
+ if (this.slugName !== null) {
+ var _routes;
+ (_routes = routes).push.apply(
+ _routes,
+ _toConsumableArray(
+ this.children
+ .get("[]")
+ ._smoosh(
+ "".concat(prefix, "[").concat(this.slugName, "]/")
+ )
+ )
+ );
+ }
+ if (!this.placeholder) {
+ var r = prefix === "/" ? "/" : prefix.slice(0, -1);
+ if (this.optionalRestSlugName != null) {
+ throw new Error(
+ 'You cannot define a route with the same specificity as a optional catch-all route ("'
+ .concat(r, '" and "')
+ .concat(r, "[[...")
+ .concat(this.optionalRestSlugName, ']]").')
+ );
+ }
+ routes.unshift(r);
+ }
+ if (this.restSlugName !== null) {
+ var _routes1;
+ (_routes1 = routes).push.apply(
+ _routes1,
+ _toConsumableArray(
+ this.children
+ .get("[...]")
+ ._smoosh(
+ ""
+ .concat(prefix, "[...")
+ .concat(this.restSlugName, "]/")
+ )
+ )
+ );
+ }
+ if (this.optionalRestSlugName !== null) {
+ var _routes2;
+ (_routes2 = routes).push.apply(
+ _routes2,
+ _toConsumableArray(
+ this.children
+ .get("[[...]]")
+ ._smoosh(
+ ""
+ .concat(prefix, "[[...")
+ .concat(this.optionalRestSlugName, "]]/")
+ )
+ )
+ );
+ }
+ return routes;
+ }
+ },
+ {
+ key: "_insert",
+ value: function _insert(urlPaths, slugNames, isCatchAll) {
+ if (urlPaths.length === 0) {
+ this.placeholder = false;
+ return;
+ }
+ if (isCatchAll) {
+ throw new Error("Catch-all must be the last part of the URL.");
+ }
+ // The next segment in the urlPaths list
+ var nextSegment = urlPaths[0];
+ // Check if the segment matches `[something]`
+ if (nextSegment.startsWith("[") && nextSegment.endsWith("]")) {
+ var handleSlug = function handleSlug(previousSlug, nextSlug) {
+ if (previousSlug !== null) {
+ // If the specific segment already has a slug but the slug is not `something`
+ // This prevents collisions like:
+ // pages/[post]/index.js
+ // pages/[id]/index.js
+ // Because currently multiple dynamic params on the same segment level are not supported
+ if (previousSlug !== nextSlug) {
+ // TODO: This error seems to be confusing for users, needs an error link, the description can be based on above comment.
+ throw new Error(
+ "You cannot use different slug names for the same dynamic path ('"
+ .concat(previousSlug, "' !== '")
+ .concat(nextSlug, "').")
+ );
+ }
+ }
+ slugNames.forEach(function(slug) {
+ if (slug === nextSlug) {
+ throw new Error(
+ 'You cannot have the same slug name "'.concat(
+ nextSlug,
+ '" repeat within a single dynamic path'
+ )
+ );
+ }
+ if (
+ slug.replace(/\W/g, "") === nextSegment.replace(/\W/g, "")
+ ) {
+ throw new Error(
+ 'You cannot have the slug names "'
+ .concat(slug, '" and "')
+ .concat(
+ nextSlug,
+ '" differ only by non-word symbols within a single dynamic path'
+ )
+ );
+ }
+ });
+ slugNames.push(nextSlug);
+ };
+ // Strip `[` and `]`, leaving only `something`
+ var segmentName = nextSegment.slice(1, -1);
+ var isOptional = false;
+ if (segmentName.startsWith("[") && segmentName.endsWith("]")) {
+ // Strip optional `[` and `]`, leaving only `something`
+ segmentName = segmentName.slice(1, -1);
+ isOptional = true;
+ }
+ if (segmentName.startsWith("...")) {
+ // Strip `...`, leaving only `something`
+ segmentName = segmentName.substring(3);
+ isCatchAll = true;
+ }
+ if (segmentName.startsWith("[") || segmentName.endsWith("]")) {
+ throw new Error(
+ "Segment names may not start or end with extra brackets ('".concat(
+ segmentName,
+ "')."
+ )
+ );
+ }
+ if (segmentName.startsWith(".")) {
+ throw new Error(
+ "Segment names may not start with erroneous periods ('".concat(
+ segmentName,
+ "')."
+ )
+ );
+ }
+ if (isCatchAll) {
+ if (isOptional) {
+ if (this.restSlugName != null) {
+ throw new Error(
+ 'You cannot use both an required and optional catch-all route at the same level ("[...'
+ .concat(this.restSlugName, ']" and "')
+ .concat(urlPaths[0], '" ).')
+ );
+ }
+ handleSlug(this.optionalRestSlugName, segmentName);
+ // slugName is kept as it can only be one particular slugName
+ this.optionalRestSlugName = segmentName;
+ // nextSegment is overwritten to [[...]] so that it can later be sorted specifically
+ nextSegment = "[[...]]";
+ } else {
+ if (this.optionalRestSlugName != null) {
+ throw new Error(
+ 'You cannot use both an optional and required catch-all route at the same level ("[[...'
+ .concat(this.optionalRestSlugName, ']]" and "')
+ .concat(urlPaths[0], '").')
+ );
+ }
+ handleSlug(this.restSlugName, segmentName);
+ // slugName is kept as it can only be one particular slugName
+ this.restSlugName = segmentName;
+ // nextSegment is overwritten to [...] so that it can later be sorted specifically
+ nextSegment = "[...]";
+ }
+ } else {
+ if (isOptional) {
+ throw new Error(
+ 'Optional route parameters are not yet supported ("'.concat(
+ urlPaths[0],
+ '").'
+ )
+ );
+ }
+ handleSlug(this.slugName, segmentName);
+ // slugName is kept as it can only be one particular slugName
+ this.slugName = segmentName;
+ // nextSegment is overwritten to [] so that it can later be sorted specifically
+ nextSegment = "[]";
+ }
+ }
+ // If this UrlNode doesn't have the nextSegment yet we create a new child UrlNode
+ if (!this.children.has(nextSegment)) {
+ this.children.set(nextSegment, new UrlNode());
+ }
+ this.children
+ .get(nextSegment)
+ ._insert(urlPaths.slice(1), slugNames, isCatchAll);
+ }
+ }
+ ]);
+ return UrlNode;
+ })();
+ function getSortedRoutes(normalizedPages) {
+ // First the UrlNode is created, and every UrlNode can have only 1 dynamic segment
+ // Eg you can't have pages/[post]/abc.js and pages/[hello]/something-else.js
+ // Only 1 dynamic segment per nesting level
+ // So in the case that is test/integration/dynamic-routing it'll be this:
+ // pages/[post]/comments.js
+ // pages/blog/[post]/comment/[id].js
+ // Both are fine because `pages/[post]` and `pages/blog` are on the same level
+ // So in this case `UrlNode` created here has `this.slugName === 'post'`
+ // And since your PR passed through `slugName` as an array basically it'd including it in too many possibilities
+ // Instead what has to be passed through is the upwards path's dynamic names
+ var root = new UrlNode();
+ // Here the `root` gets injected multiple paths, and insert will break them up into sublevels
+ normalizedPages.forEach(function(pagePath) {
+ return root.insert(pagePath);
+ });
+ // Smoosh will then sort those sublevels up to the point where you get the correct route definition priority
+ return root.smoosh();
+ } //# sourceMappingURL=sorted-routes.js.map
+
+ /***/
+ },
+
/***/ 8027: /***/ function(__unused_webpack_module, exports) {
"use strict";
@@ -7913,7 +8301,11 @@
/***/
},
- /***/ 4522: /***/ function(__unused_webpack_module, exports) {
+ /***/ 4522: /***/ function(
+ __unused_webpack_module,
+ exports,
+ __webpack_require__
+ ) {
"use strict";
Object.defineProperty(exports, "__esModule", {
@@ -7921,12 +8313,13 @@
});
exports.normalizePathSep = normalizePathSep;
exports.denormalizePagePath = denormalizePagePath;
+ var _utils = __webpack_require__(418);
function normalizePathSep(path) {
return path.replace(/\\/g, "/");
}
function denormalizePagePath(page) {
page = normalizePathSep(page);
- if (page.startsWith("/index/")) {
+ if (page.startsWith("/index/") && !(0, _utils).isDynamicRoute(page)) {
page = page.slice(6);
} else if (page === "/index") {
page = "/";
Diff for index.html
@@ -19,7 +19,7 @@
defer=""
></script>
<script
- src="/_next/static/chunks/main-265c59c213a49f1c.js"
+ src="/_next/static/chunks/main-92a7810899e6ca71.js"
defer=""
></script>
<script
Diff for link.html
@@ -19,7 +19,7 @@
defer=""
></script>
<script
- src="/_next/static/chunks/main-265c59c213a49f1c.js"
+ src="/_next/static/chunks/main-92a7810899e6ca71.js"
defer=""
></script>
<script
Diff for withRouter.html
@@ -19,7 +19,7 @@
defer=""
></script>
<script
- src="/_next/static/chunks/main-265c59c213a49f1c.js"
+ src="/_next/static/chunks/main-92a7810899e6ca71.js"
defer=""
></script>
<script
@RizBizKits It's fixed after v12.0.8-canary.5, so would be released in v12.0.8-canary.6! 🙏 |
cdierkens
pushed a commit
to cdierkens/next.js
that referenced
this pull request
Dec 20, 2021
Fixes incorrect generated manifest and generated directory for `index/[...dynamic]` pages Too much normalizing adding extra `index/` prefix to `index/[...dynamic]` routes which lead to the incorrected generated routes like `.next/server/pages/index/index/index/[...dynamic]` ## Bug Fixes https://github.com/vercel/customer-issues/issues/146 - [x] Related issues linked using `fixes #number` - [x] Integration tests added - [ ] Errors have helpful link attached, see `contributing.md`
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Fixes incorrect generated manifest and generated directory for
index/[...dynamic]
pagesToo much normalizing adding extra
index/
prefix toindex/[...dynamic]
routes which lead to the incorrected generated routes like.next/server/pages/index/index/index/[...dynamic]
Bug
Fixes https://github.com/vercel/customer-issues/issues/146
fixes #number
contributing.md