next.js
next.js copied to clipboard
next/root-params [WIP]
Implements accessing root params (params segments that occur above root layouts) via compiler-generated getters from the next/root-params module:
// app/[lang]/layout.tsx
// (there is no app/layout.tsx, this is the root layout)
import { lang } from "next/root-params";
// ^^^^ coresponds to the [lang] segment above this module
export default async function RootLayout({ children }) {
return (
<html lang={await lang()}>
<body>{children}</body>
</html>
);
}
This API is only usable within server components (support for using it in route handlers will likely be added in the future). It can be called anywhere in the tree, not just in a page or a layout. It will replace unstable_rootParams, which will be removed soon.
Note that we can also have multiple root layouts with distinct params, like this:
app/product/[productId]/layout.tsx
app/brand/[brandId]/layout.tsx
In this case we'll generate getters for both productId and brandId. They can be called anywhere, but they'll return undefined if used in a subtree where a param isn't available.
Note that this PR does not yet generate type declarations for the generated getters, essentially leaving them typed as any. This will be handled in a follow up.
Implementation notes
Turbopack
We collect the root param names when analyzing the folder structure in app_structure.rs. The set is then passed down (as a Vc) all the way to next_import_map.rs, where we insert an alias to a virtual next/root-params.js module. We use a ImportMapping::Dynamic to generate its code lazily in a separate turbo task (which is the only place that actually reads the root params). This avoids invalidating the whole ResolveOptionsContext if the root params change.
Webpack
We alias next/root-params to next-root-params-loader, which scans the directory structure manually (i haven't found a good way to re-use existing methods for doing this) and returns the generated module. Each directory we traverse before finidng a root layout is marked as a contextDependency, which should invalidate the loader's result if new files are added to any of them or if they get renamed, because it might mean that the set of root params changed.
Tests Passed
Stats from current PR
Default Build (Increase detected ⚠️)
General Overall increase ⚠️
| vercel/next.js canary | vercel/next.js lubieowoce/rootparams-module | Change | |
|---|---|---|---|
| buildDuration | 19.7s | 15.3s | N/A |
| buildDurationCached | 14.5s | 12.9s | N/A |
| nodeModulesSize | 443 MB | 443 MB | ⚠️ +144 kB |
| nextStartRea..uration (ms) | 380ms | 381ms | N/A |
Client Bundles (main, webpack) Overall increase ⚠️
| vercel/next.js canary | vercel/next.js lubieowoce/rootparams-module | Change | |
|---|---|---|---|
| 194b18f3-HASH.js gzip | 54.1 kB | 54.1 kB | N/A |
| 2192.HASH.js gzip | 169 B | 169 B | ✓ |
| 4719-HASH.js gzip | 5.3 kB | 5.26 kB | N/A |
| 6236-HASH.js gzip | 44.2 kB | 44.7 kB | ⚠️ +510 B |
| framework-HASH.js gzip | 57.4 kB | 57.4 kB | N/A |
| main-app-HASH.js gzip | 254 B | 257 B | N/A |
| main-HASH.js gzip | 36 kB | 36.2 kB | ⚠️ +197 B |
| webpack-HASH.js gzip | 1.71 kB | 1.71 kB | N/A |
| Overall change | 80.3 kB | 81 kB | ⚠️ +707 B |
Legacy Client Bundles (polyfills)
| vercel/next.js canary | vercel/next.js lubieowoce/rootparams-module | Change | |
|---|---|---|---|
| polyfills-HASH.js gzip | 39.4 kB | 39.4 kB | ✓ |
| Overall change | 39.4 kB | 39.4 kB | ✓ |
Client Pages
| vercel/next.js canary | vercel/next.js lubieowoce/rootparams-module | Change | |
|---|---|---|---|
| _app-HASH.js gzip | 193 B | 193 B | ✓ |
| _error-HASH.js gzip | 182 B | 182 B | ✓ |
| amp-HASH.js gzip | 501 B | 503 B | N/A |
| css-HASH.js gzip | 335 B | 334 B | N/A |
| dynamic-HASH.js gzip | 1.83 kB | 1.83 kB | N/A |
| edge-ssr-HASH.js gzip | 256 B | 255 B | N/A |
| head-HASH.js gzip | 350 B | 351 B | N/A |
| hooks-HASH.js gzip | 382 B | 383 B | N/A |
| image-HASH.js gzip | 4.68 kB | 4.65 kB | N/A |
| index-HASH.js gzip | 259 B | 258 B | N/A |
| link-HASH.js gzip | 2.52 kB | 2.51 kB | N/A |
| routerDirect..HASH.js gzip | 319 B | 319 B | ✓ |
| script-HASH.js gzip | 386 B | 386 B | ✓ |
| withRouter-HASH.js gzip | 316 B | 316 B | ✓ |
| 1afbb74e6ecf..834.css gzip | 106 B | 106 B | ✓ |
| Overall change | 1.5 kB | 1.5 kB | ✓ |
Client Build Manifests
| vercel/next.js canary | vercel/next.js lubieowoce/rootparams-module | Change | |
|---|---|---|---|
| _buildManifest.js gzip | 752 B | 753 B | N/A |
| Overall change | 0 B | 0 B | ✓ |
Rendered Page Sizes
| vercel/next.js canary | vercel/next.js lubieowoce/rootparams-module | Change | |
|---|---|---|---|
| index.html gzip | 523 B | 524 B | N/A |
| link.html gzip | 537 B | 540 B | N/A |
| withRouter.html gzip | 520 B | 520 B | ✓ |
| Overall change | 520 B | 520 B | ✓ |
Edge SSR bundle Size
| vercel/next.js canary | vercel/next.js lubieowoce/rootparams-module | Change | |
|---|---|---|---|
| edge-ssr.js gzip | 121 kB | 121 kB | N/A |
| page.js gzip | 222 kB | 221 kB | N/A |
| Overall change | 0 B | 0 B | ✓ |
Middleware size Overall increase ⚠️
| vercel/next.js canary | vercel/next.js lubieowoce/rootparams-module | Change | |
|---|---|---|---|
| middleware-b..fest.js gzip | 678 B | 674 B | N/A |
| middleware-r..fest.js gzip | 155 B | 155 B | ✓ |
| middleware.js gzip | 32.2 kB | 32.4 kB | ⚠️ +194 B |
| edge-runtime..pack.js gzip | 853 B | 853 B | ✓ |
| Overall change | 33.2 kB | 33.4 kB | ⚠️ +194 B |
Next Runtimes
| vercel/next.js canary | vercel/next.js lubieowoce/rootparams-module | Change | |
|---|---|---|---|
| app-page-exp...dev.js gzip | 280 kB | 280 kB | N/A |
| app-page-exp..prod.js gzip | 154 kB | 154 kB | ✓ |
| app-page-tur...dev.js gzip | 280 kB | 280 kB | ✓ |
| app-page-tur..prod.js gzip | 154 kB | 154 kB | ✓ |
| app-page-tur...dev.js gzip | 268 kB | 268 kB | ✓ |
| app-page-tur..prod.js gzip | 148 kB | 148 kB | ✓ |
| app-page.run...dev.js gzip | 268 kB | 268 kB | ✓ |
| app-page.run..prod.js gzip | 148 kB | 148 kB | ✓ |
| app-route-ex...dev.js gzip | 69.1 kB | 69.1 kB | ✓ |
| app-route-ex..prod.js gzip | 48.6 kB | 48.6 kB | ✓ |
| app-route-tu...dev.js gzip | 69.1 kB | 69.1 kB | ✓ |
| app-route-tu..prod.js gzip | 48.6 kB | 48.6 kB | ✓ |
| app-route-tu...dev.js gzip | 68.5 kB | 68.5 kB | ✓ |
| app-route-tu..prod.js gzip | 48.2 kB | 48.2 kB | ✓ |
| app-route.ru...dev.js gzip | 68.4 kB | 68.4 kB | ✓ |
| app-route.ru..prod.js gzip | 48.2 kB | 48.2 kB | ✓ |
| dist_client_...dev.js gzip | 326 B | 326 B | ✓ |
| dist_client_...dev.js gzip | 328 B | 328 B | ✓ |
| dist_client_...dev.js gzip | 320 B | 320 B | ✓ |
| dist_client_...dev.js gzip | 318 B | 318 B | ✓ |
| pages-api-tu...dev.js gzip | 42.3 kB | 42.3 kB | ✓ |
| pages-api-tu..prod.js gzip | 32.5 kB | 32.5 kB | ✓ |
| pages-api.ru...dev.js gzip | 42.2 kB | 42.2 kB | ✓ |
| pages-api.ru..prod.js gzip | 32.5 kB | 32.5 kB | ✓ |
| pages-turbo....dev.js gzip | 52.3 kB | 52.3 kB | ✓ |
| pages-turbo...prod.js gzip | 39.9 kB | 39.9 kB | ✓ |
| pages.runtim...dev.js gzip | 52.4 kB | 52.4 kB | ✓ |
| pages.runtim..prod.js gzip | 40 kB | 40 kB | ✓ |
| server.runti..prod.js gzip | 59.5 kB | 59.5 kB | ✓ |
| Overall change | 2.28 MB | 2.28 MB | ✓ |
build cache Overall increase ⚠️
| vercel/next.js canary | vercel/next.js lubieowoce/rootparams-module | Change | |
|---|---|---|---|
| 0.pack gzip | 2.8 MB | 2.81 MB | ⚠️ +6.04 kB |
| index.pack gzip | 91.8 kB | 91.7 kB | N/A |
| Overall change | 2.8 MB | 2.81 MB | ⚠️ +6.04 kB |
Diff details
Diff for page.js
Diff too large to display
Diff for middleware.js
Diff too large to display
Diff for edge-ssr.js
Diff too large to display
Diff for amp-HASH.js
@@ -1,56 +1,34 @@
(self["webpackChunk_N_E"] = self["webpackChunk_N_E"] || []).push([
[5034],
{
- /***/ 3960: /***/ (
+ /***/ 3870: /***/ (
module,
__unused_webpack_exports,
__webpack_require__
) => {
- module.exports = __webpack_require__(5313);
+ module.exports = __webpack_require__(9298);
/***/
},
- /***/ 5313: /***/ (module, exports, __webpack_require__) => {
- "use strict";
-
- Object.defineProperty(exports, "__esModule", {
- value: true,
- });
- Object.defineProperty(exports, "useAmp", {
- enumerable: true,
- get: function () {
- return useAmp;
+ /***/ 8318: /***/ (
+ __unused_webpack_module,
+ __unused_webpack_exports,
+ __webpack_require__
+ ) => {
+ (window.__NEXT_P = window.__NEXT_P || []).push([
+ "/amp",
+ function () {
+ return __webpack_require__(8921);
},
- });
- const _interop_require_default = __webpack_require__(1532);
- const _react = /*#__PURE__*/ _interop_require_default._(
- __webpack_require__(148)
- );
- const _ampcontextsharedruntime = __webpack_require__(919);
- const _ampmode = __webpack_require__(1615);
- function useAmp() {
- // Don't assign the context value to a variable to save bytes
- return (0, _ampmode.isInAmpMode)(
- _react.default.useContext(_ampcontextsharedruntime.AmpStateContext)
- );
+ ]);
+ if (false) {
}
- if (
- (typeof exports.default === "function" ||
- (typeof exports.default === "object" && exports.default !== null)) &&
- typeof exports.default.__esModule === "undefined"
- ) {
- Object.defineProperty(exports.default, "__esModule", {
- value: true,
- });
- Object.assign(exports.default, exports);
- module.exports = exports.default;
- } //# sourceMappingURL=amp.js.map
/***/
},
- /***/ 6756: /***/ (
+ /***/ 8921: /***/ (
__unused_webpack_module,
__webpack_exports__,
__webpack_require__
@@ -63,7 +41,7 @@
/* harmony export */
});
/* harmony import */ var next_amp__WEBPACK_IMPORTED_MODULE_0__ =
- __webpack_require__(3960);
+ __webpack_require__(3870);
/* harmony import */ var next_amp__WEBPACK_IMPORTED_MODULE_0___default =
/*#__PURE__*/ __webpack_require__.n(
next_amp__WEBPACK_IMPORTED_MODULE_0__
@@ -81,19 +59,41 @@
/***/
},
- /***/ 7252: /***/ (
- __unused_webpack_module,
- __unused_webpack_exports,
- __webpack_require__
- ) => {
- (window.__NEXT_P = window.__NEXT_P || []).push([
- "/amp",
- function () {
- return __webpack_require__(6756);
+ /***/ 9298: /***/ (module, exports, __webpack_require__) => {
+ "use strict";
+
+ Object.defineProperty(exports, "__esModule", {
+ value: true,
+ });
+ Object.defineProperty(exports, "useAmp", {
+ enumerable: true,
+ get: function () {
+ return useAmp;
},
- ]);
- if (false) {
+ });
+ const _interop_require_default = __webpack_require__(1532);
+ const _react = /*#__PURE__*/ _interop_require_default._(
+ __webpack_require__(148)
+ );
+ const _ampcontextsharedruntime = __webpack_require__(326);
+ const _ampmode = __webpack_require__(9474);
+ function useAmp() {
+ // Don't assign the context value to a variable to save bytes
+ return (0, _ampmode.isInAmpMode)(
+ _react.default.useContext(_ampcontextsharedruntime.AmpStateContext)
+ );
}
+ if (
+ (typeof exports.default === "function" ||
+ (typeof exports.default === "object" && exports.default !== null)) &&
+ typeof exports.default.__esModule === "undefined"
+ ) {
+ Object.defineProperty(exports.default, "__esModule", {
+ value: true,
+ });
+ Object.assign(exports.default, exports);
+ module.exports = exports.default;
+ } //# sourceMappingURL=amp.js.map
/***/
},
@@ -103,7 +103,7 @@
/******/ var __webpack_exec__ = (moduleId) =>
__webpack_require__((__webpack_require__.s = moduleId));
/******/ __webpack_require__.O(0, [636, 6593, 8792], () =>
- __webpack_exec__(7252)
+ __webpack_exec__(8318)
);
/******/ var __webpack_exports__ = __webpack_require__.O();
/******/ _N_E = __webpack_exports__;
Diff for css-HASH.js
@@ -1,7 +1,7 @@
(self["webpackChunk_N_E"] = self["webpackChunk_N_E"] || []).push([
[9813],
{
- /***/ 1586: /***/ (
+ /***/ 2628: /***/ (
__unused_webpack_module,
__unused_webpack_exports,
__webpack_require__
@@ -9,7 +9,7 @@
(window.__NEXT_P = window.__NEXT_P || []).push([
"/css",
function () {
- return __webpack_require__(4362);
+ return __webpack_require__(5892);
},
]);
if (false) {
@@ -18,14 +18,7 @@
/***/
},
- /***/ 4350: /***/ (module) => {
- // extracted by mini-css-extract-plugin
- module.exports = { helloWorld: "css_helloWorld__aUdUq" };
-
- /***/
- },
-
- /***/ 4362: /***/ (
+ /***/ 5892: /***/ (
__unused_webpack_module,
__webpack_exports__,
__webpack_require__
@@ -39,7 +32,7 @@
/* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__ =
__webpack_require__(5640);
/* harmony import */ var _css_module_css__WEBPACK_IMPORTED_MODULE_1__ =
- __webpack_require__(4350);
+ __webpack_require__(8937);
/* harmony import */ var _css_module_css__WEBPACK_IMPORTED_MODULE_1___default =
/*#__PURE__*/ __webpack_require__.n(
_css_module_css__WEBPACK_IMPORTED_MODULE_1__
@@ -58,13 +51,20 @@
/***/
},
+
+ /***/ 8937: /***/ (module) => {
+ // extracted by mini-css-extract-plugin
+ module.exports = { helloWorld: "css_helloWorld__aUdUq" };
+
+ /***/
+ },
},
/******/ (__webpack_require__) => {
// webpackRuntimeModules
/******/ var __webpack_exec__ = (moduleId) =>
__webpack_require__((__webpack_require__.s = moduleId));
/******/ __webpack_require__.O(0, [636, 6593, 8792], () =>
- __webpack_exec__(1586)
+ __webpack_exec__(2628)
);
/******/ var __webpack_exports__ = __webpack_require__.O();
/******/ _N_E = __webpack_exports__;
Diff for dynamic-HASH.js
@@ -1,17 +1,7 @@
(self["webpackChunk_N_E"] = self["webpackChunk_N_E"] || []).push([
[2291],
{
- /***/ 283: /***/ (
- module,
- __unused_webpack_exports,
- __webpack_require__
- ) => {
- module.exports = __webpack_require__(6990);
-
- /***/
- },
-
- /***/ 505: /***/ (
+ /***/ 290: /***/ (
__unused_webpack_module,
exports,
__webpack_require__
@@ -53,7 +43,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE
const _react = /*#__PURE__*/ _interop_require_default._(
__webpack_require__(148)
);
- const _loadablecontextsharedruntime = __webpack_require__(6179);
+ const _loadablecontextsharedruntime = __webpack_require__(8452);
function resolve(obj) {
return obj && obj.default ? obj.default : obj;
}
@@ -288,7 +278,17 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE
/***/
},
- /***/ 5703: /***/ (
+ /***/ 1934: /***/ (
+ module,
+ __unused_webpack_exports,
+ __webpack_require__
+ ) => {
+ module.exports = __webpack_require__(9141);
+
+ /***/
+ },
+
+ /***/ 2598: /***/ (
__unused_webpack_module,
__webpack_exports__,
__webpack_require__
@@ -303,7 +303,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE
/* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__ =
__webpack_require__(5640);
/* harmony import */ var next_dynamic__WEBPACK_IMPORTED_MODULE_1__ =
- __webpack_require__(283);
+ __webpack_require__(1934);
/* harmony import */ var next_dynamic__WEBPACK_IMPORTED_MODULE_1___default =
/*#__PURE__*/ __webpack_require__.n(
next_dynamic__WEBPACK_IMPORTED_MODULE_1__
@@ -312,12 +312,12 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE
const DynamicHello = next_dynamic__WEBPACK_IMPORTED_MODULE_1___default()(
() =>
__webpack_require__
- .e(/* import() */ 2192)
- .then(__webpack_require__.bind(__webpack_require__, 2192))
+ .e(/* import() */ 8751)
+ .then(__webpack_require__.bind(__webpack_require__, 8751))
.then((mod) => mod.Hello),
{
loadableGenerated: {
- webpack: () => [/*require.resolve*/ 2192],
+ webpack: () => [/*require.resolve*/ 8751],
},
}
);
@@ -344,7 +344,24 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE
/***/
},
- /***/ 6179: /***/ (
+ /***/ 2976: /***/ (
+ __unused_webpack_module,
+ __unused_webpack_exports,
+ __webpack_require__
+ ) => {
+ (window.__NEXT_P = window.__NEXT_P || []).push([
+ "/dynamic",
+ function () {
+ return __webpack_require__(2598);
+ },
+ ]);
+ if (false) {
+ }
+
+ /***/
+ },
+
+ /***/ 8452: /***/ (
__unused_webpack_module,
exports,
__webpack_require__
@@ -371,7 +388,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE
/***/
},
- /***/ 6990: /***/ (module, exports, __webpack_require__) => {
+ /***/ 9141: /***/ (module, exports, __webpack_require__) => {
"use strict";
Object.defineProperty(exports, "__esModule", {
@@ -404,7 +421,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE
__webpack_require__(148)
);
const _loadablesharedruntime = /*#__PURE__*/ _interop_require_default._(
- __webpack_require__(505)
+ __webpack_require__(290)
);
const isServerSide = "object" === "undefined";
// Normalize loader to return the module as form { default: Component } for `React.lazy`.
@@ -504,30 +521,13 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE
/***/
},
-
- /***/ 9254: /***/ (
- __unused_webpack_module,
- __unused_webpack_exports,
- __webpack_require__
- ) => {
- (window.__NEXT_P = window.__NEXT_P || []).push([
- "/dynamic",
- function () {
- return __webpack_require__(5703);
- },
- ]);
- if (false) {
- }
-
- /***/
- },
},
/******/ (__webpack_require__) => {
// webpackRuntimeModules
/******/ var __webpack_exec__ = (moduleId) =>
__webpack_require__((__webpack_require__.s = moduleId));
/******/ __webpack_require__.O(0, [636, 6593, 8792], () =>
- __webpack_exec__(9254)
+ __webpack_exec__(2976)
);
/******/ var __webpack_exports__ = __webpack_require__.O();
/******/ _N_E = __webpack_exports__;
Diff for hooks-HASH.js
@@ -1,24 +1,7 @@
(self["webpackChunk_N_E"] = self["webpackChunk_N_E"] || []).push([
[9804],
{
- /***/ 1664: /***/ (
- __unused_webpack_module,
- __unused_webpack_exports,
- __webpack_require__
- ) => {
- (window.__NEXT_P = window.__NEXT_P || []).push([
- "/hooks",
- function () {
- return __webpack_require__(6130);
- },
- ]);
- if (false) {
- }
-
- /***/
- },
-
- /***/ 6130: /***/ (
+ /***/ 3251: /***/ (
__unused_webpack_module,
__webpack_exports__,
__webpack_require__
@@ -76,13 +59,30 @@
/***/
},
+
+ /***/ 5426: /***/ (
+ __unused_webpack_module,
+ __unused_webpack_exports,
+ __webpack_require__
+ ) => {
+ (window.__NEXT_P = window.__NEXT_P || []).push([
+ "/hooks",
+ function () {
+ return __webpack_require__(3251);
+ },
+ ]);
+ if (false) {
+ }
+
+ /***/
+ },
},
/******/ (__webpack_require__) => {
// webpackRuntimeModules
/******/ var __webpack_exec__ = (moduleId) =>
__webpack_require__((__webpack_require__.s = moduleId));
/******/ __webpack_require__.O(0, [636, 6593, 8792], () =>
- __webpack_exec__(1664)
+ __webpack_exec__(5426)
);
/******/ var __webpack_exports__ = __webpack_require__.O();
/******/ _N_E = __webpack_exports__;
Diff for image-HASH.js
Diff too large to display
Diff for link-HASH.js
@@ -1,108 +1,116 @@
(self["webpackChunk_N_E"] = self["webpackChunk_N_E"] || []).push([
[4672],
{
- /***/ 1854: /***/ (
- __unused_webpack_module,
- __webpack_exports__,
- __webpack_require__
- ) => {
- "use strict";
- __webpack_require__.r(__webpack_exports__);
- /* harmony export */ __webpack_require__.d(__webpack_exports__, {
- /* harmony export */ __N_SSP: () => /* binding */ __N_SSP,
- /* harmony export */ default: () => __WEBPACK_DEFAULT_EXPORT__,
- /* harmony export */
- });
- /* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__ =
- __webpack_require__(5640);
- /* harmony import */ var next_link__WEBPACK_IMPORTED_MODULE_1__ =
- __webpack_require__(8770);
- /* harmony import */ var next_link__WEBPACK_IMPORTED_MODULE_1___default =
- /*#__PURE__*/ __webpack_require__.n(
- next_link__WEBPACK_IMPORTED_MODULE_1__
- );
-
- function aLink(props) {
- return /*#__PURE__*/ (0,
- react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)("div", {
- children: [
- /*#__PURE__*/ (0,
- react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)("h3", {
- children: "A Link page!",
- }),
- /*#__PURE__*/ (0,
- react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(
- next_link__WEBPACK_IMPORTED_MODULE_1___default(),
- {
- href: "/",
- children: "Go to /",
- }
- ),
- ],
- });
- }
- var __N_SSP = true;
- /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = aLink;
-
- /***/
- },
-
- /***/ 3199: /***/ (__unused_webpack_module, exports) => {
- "use strict";
-
- Object.defineProperty(exports, "__esModule", {
- value: true,
- });
- Object.defineProperty(exports, "errorOnce", {
- enumerable: true,
- get: function () {
- return errorOnce;
- },
- });
- let errorOnce = (_) => {};
- if (false) {
- } //# sourceMappingURL=error-once.js.map
-
- /***/
- },
-
- /***/ 3568: /***/ (
- __unused_webpack_module,
- __unused_webpack_exports,
- __webpack_require__
- ) => {
- (window.__NEXT_P = window.__NEXT_P || []).push([
- "/link",
- function () {
- return __webpack_require__(1854);
- },
- ]);
- if (false) {
- }
-
- /***/
- },
-
- /***/ 3857: /***/ (module, exports, __webpack_require__) => {
+ /***/ 606: /***/ (module, exports, __webpack_require__) => {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true,
});
- Object.defineProperty(exports, "getDomainLocale", {
+ Object.defineProperty(exports, "useIntersection", {
enumerable: true,
get: function () {
- return getDomainLocale;
+ return useIntersection;
},
});
- const _normalizetrailingslash = __webpack_require__(4869);
- const basePath =
- /* unused pure expression or super */ null && (false || "");
- function getDomainLocale(path, locale, locales, domainLocales) {
- if (false) {
- } else {
- return false;
+ const _react = __webpack_require__(148);
+ const _requestidlecallback = __webpack_require__(9940);
+ const hasIntersectionObserver =
+ typeof IntersectionObserver === "function";
+ const observers = new Map();
+ const idList = [];
+ function createObserver(options) {
+ const id = {
+ root: options.root || null,
+ margin: options.rootMargin || "",
+ };
+ const existing = idList.find(
+ (obj) => obj.root === id.root && obj.margin === id.margin
+ );
+ let instance;
+ if (existing) {
+ instance = observers.get(existing);
+ if (instance) {
+ return instance;
+ }
}
+ const elements = new Map();
+ const observer = new IntersectionObserver((entries) => {
+ entries.forEach((entry) => {
+ const callback = elements.get(entry.target);
+ const isVisible =
+ entry.isIntersecting || entry.intersectionRatio > 0;
+ if (callback && isVisible) {
+ callback(isVisible);
+ }
+ });
+ }, options);
+ instance = {
+ id,
+ observer,
+ elements,
+ };
+ idList.push(id);
+ observers.set(id, instance);
+ return instance;
+ }
+ function observe(element, callback, options) {
+ const { id, observer, elements } = createObserver(options);
+ elements.set(element, callback);
+ observer.observe(element);
+ return function unobserve() {
+ elements.delete(element);
+ observer.unobserve(element);
+ // Destroy observer when there's nothing left to watch:
+ if (elements.size === 0) {
+ observer.disconnect();
+ observers.delete(id);
+ const index = idList.findIndex(
+ (obj) => obj.root === id.root && obj.margin === id.margin
+ );
+ if (index > -1) {
+ idList.splice(index, 1);
+ }
+ }
+ };
+ }
+ function useIntersection(param) {
+ let { rootRef, rootMargin, disabled } = param;
+ const isDisabled = disabled || !hasIntersectionObserver;
+ const [visible, setVisible] = (0, _react.useState)(false);
+ const elementRef = (0, _react.useRef)(null);
+ const setElement = (0, _react.useCallback)((element) => {
+ elementRef.current = element;
+ }, []);
+ (0, _react.useEffect)(() => {
+ if (hasIntersectionObserver) {
+ if (isDisabled || visible) return;
+ const element = elementRef.current;
+ if (element && element.tagName) {
+ const unobserve = observe(
+ element,
+ (isVisible) => isVisible && setVisible(isVisible),
+ {
+ root: rootRef == null ? void 0 : rootRef.current,
+ rootMargin,
+ }
+ );
+ return unobserve;
+ }
+ } else {
+ if (!visible) {
+ const idleCallback = (0,
+ _requestidlecallback.requestIdleCallback)(() => setVisible(true));
+ return () =>
+ (0, _requestidlecallback.cancelIdleCallback)(idleCallback);
+ }
+ }
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [isDisabled, rootMargin, rootRef, visible, elementRef.current]);
+ const resetVisible = (0, _react.useCallback)(() => {
+ setVisible(false);
+ }, []);
+ return [setElement, visible, resetVisible];
}
if (
(typeof exports.default === "function" ||
@@ -114,12 +122,22 @@
});
Object.assign(exports.default, exports);
module.exports = exports.default;
- } //# sourceMappingURL=get-domain-locale.js.map
+ } //# sourceMappingURL=use-intersection.js.map
/***/
},
- /***/ 3947: /***/ (module, exports, __webpack_require__) => {
+ /***/ 1148: /***/ (
+ module,
+ __unused_webpack_exports,
+ __webpack_require__
+ ) => {
+ module.exports = __webpack_require__(2994);
+
+ /***/
+ },
+
+ /***/ 2994: /***/ (module, exports, __webpack_require__) => {
"use strict";
/* __next_internal_client_entry_do_not_use__ cjs */
Object.defineProperty(exports, "__esModule", {
@@ -146,17 +164,17 @@
const _react = /*#__PURE__*/ _interop_require_wildcard._(
__webpack_require__(148)
);
- const _resolvehref = __webpack_require__(3161);
- const _islocalurl = __webpack_require__(2309);
- const _formaturl = __webpack_require__(3768);
- const _utils = __webpack_require__(5554);
- const _addlocale = __webpack_require__(7591);
- const _routercontextsharedruntime = __webpack_require__(3556);
- const _useintersection = __webpack_require__(5624);
- const _getdomainlocale = __webpack_require__(3857);
- const _addbasepath = __webpack_require__(4356);
- const _usemergedref = __webpack_require__(4985);
- const _erroronce = __webpack_require__(3199);
+ const _resolvehref = __webpack_require__(8624);
+ const _islocalurl = __webpack_require__(6722);
+ const _formaturl = __webpack_require__(4411);
+ const _utils = __webpack_require__(1061);
+ const _addlocale = __webpack_require__(2006);
+ const _routercontextsharedruntime = __webpack_require__(2479);
+ const _useintersection = __webpack_require__(606);
+ const _getdomainlocale = __webpack_require__(4194);
+ const _addbasepath = __webpack_require__(2135);
+ const _usemergedref = __webpack_require__(6156);
+ const _erroronce = __webpack_require__(5174);
const prefetched = new Set();
function prefetch(router, href, as, options) {
if (false) {
@@ -545,7 +563,108 @@
/***/
},
- /***/ 4985: /***/ (module, exports, __webpack_require__) => {
+ /***/ 3645: /***/ (
+ __unused_webpack_module,
+ __webpack_exports__,
+ __webpack_require__
+ ) => {
+ "use strict";
+ __webpack_require__.r(__webpack_exports__);
+ /* harmony export */ __webpack_require__.d(__webpack_exports__, {
+ /* harmony export */ __N_SSP: () => /* binding */ __N_SSP,
+ /* harmony export */ default: () => __WEBPACK_DEFAULT_EXPORT__,
+ /* harmony export */
+ });
+ /* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__ =
+ __webpack_require__(5640);
+ /* harmony import */ var next_link__WEBPACK_IMPORTED_MODULE_1__ =
+ __webpack_require__(1148);
+ /* harmony import */ var next_link__WEBPACK_IMPORTED_MODULE_1___default =
+ /*#__PURE__*/ __webpack_require__.n(
+ next_link__WEBPACK_IMPORTED_MODULE_1__
+ );
+
+ function aLink(props) {
+ return /*#__PURE__*/ (0,
+ react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)("div", {
+ children: [
+ /*#__PURE__*/ (0,
+ react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)("h3", {
+ children: "A Link page!",
+ }),
+ /*#__PURE__*/ (0,
+ react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(
+ next_link__WEBPACK_IMPORTED_MODULE_1___default(),
+ {
+ href: "/",
+ children: "Go to /",
+ }
+ ),
+ ],
+ });
+ }
+ var __N_SSP = true;
+ /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = aLink;
+
+ /***/
+ },
+
+ /***/ 4194: /***/ (module, exports, __webpack_require__) => {
+ "use strict";
+
+ Object.defineProperty(exports, "__esModule", {
+ value: true,
+ });
+ Object.defineProperty(exports, "getDomainLocale", {
+ enumerable: true,
+ get: function () {
+ return getDomainLocale;
+ },
+ });
+ const _normalizetrailingslash = __webpack_require__(6036);
+ const basePath =
+ /* unused pure expression or super */ null && (false || "");
+ function getDomainLocale(path, locale, locales, domainLocales) {
+ if (false) {
+ } else {
+ return false;
+ }
+ }
+ if (
+ (typeof exports.default === "function" ||
+ (typeof exports.default === "object" && exports.default !== null)) &&
+ typeof exports.default.__esModule === "undefined"
+ ) {
+ Object.defineProperty(exports.default, "__esModule", {
+ value: true,
+ });
+ Object.assign(exports.default, exports);
+ module.exports = exports.default;
+ } //# sourceMappingURL=get-domain-locale.js.map
+
+ /***/
+ },
+
+ /***/ 5174: /***/ (__unused_webpack_module, exports) => {
+ "use strict";
+
+ Object.defineProperty(exports, "__esModule", {
+ value: true,
+ });
+ Object.defineProperty(exports, "errorOnce", {
+ enumerable: true,
+ get: function () {
+ return errorOnce;
+ },
+ });
+ let errorOnce = (_) => {};
+ if (false) {
+ } //# sourceMappingURL=error-once.js.map
+
+ /***/
+ },
+
+ /***/ 6156: /***/ (module, exports, __webpack_require__) => {
"use strict";
Object.defineProperty(exports, "__esModule", {
@@ -623,138 +742,19 @@
/***/
},
- /***/ 5624: /***/ (module, exports, __webpack_require__) => {
- "use strict";
-
- Object.defineProperty(exports, "__esModule", {
- value: true,
- });
- Object.defineProperty(exports, "useIntersection", {
- enumerable: true,
- get: function () {
- return useIntersection;
- },
- });
- const _react = __webpack_require__(148);
- const _requestidlecallback = __webpack_require__(3543);
- const hasIntersectionObserver =
- typeof IntersectionObserver === "function";
- const observers = new Map();
- const idList = [];
- function createObserver(options) {
- const id = {
- root: options.root || null,
- margin: options.rootMargin || "",
- };
- const existing = idList.find(
- (obj) => obj.root === id.root && obj.margin === id.margin
- );
- let instance;
- if (existing) {
- instance = observers.get(existing);
- if (instance) {
- return instance;
- }
- }
- const elements = new Map();
- const observer = new IntersectionObserver((entries) => {
- entries.forEach((entry) => {
- const callback = elements.get(entry.target);
- const isVisible =
- entry.isIntersecting || entry.intersectionRatio > 0;
- if (callback && isVisible) {
- callback(isVisible);
- }
- });
- }, options);
- instance = {
- id,
- observer,
- elements,
- };
- idList.push(id);
- observers.set(id, instance);
- return instance;
- }
- function observe(element, callback, options) {
- const { id, observer, elements } = createObserver(options);
- elements.set(element, callback);
- observer.observe(element);
- return function unobserve() {
- elements.delete(element);
- observer.unobserve(element);
- // Destroy observer when there's nothing left to watch:
- if (elements.size === 0) {
- observer.disconnect();
- observers.delete(id);
- const index = idList.findIndex(
- (obj) => obj.root === id.root && obj.margin === id.margin
- );
- if (index > -1) {
- idList.splice(index, 1);
- }
- }
- };
- }
- function useIntersection(param) {
- let { rootRef, rootMargin, disabled } = param;
- const isDisabled = disabled || !hasIntersectionObserver;
- const [visible, setVisible] = (0, _react.useState)(false);
- const elementRef = (0, _react.useRef)(null);
- const setElement = (0, _react.useCallback)((element) => {
- elementRef.current = element;
- }, []);
- (0, _react.useEffect)(() => {
- if (hasIntersectionObserver) {
- if (isDisabled || visible) return;
- const element = elementRef.current;
- if (element && element.tagName) {
- const unobserve = observe(
- element,
- (isVisible) => isVisible && setVisible(isVisible),
- {
- root: rootRef == null ? void 0 : rootRef.current,
- rootMargin,
- }
- );
- return unobserve;
- }
- } else {
- if (!visible) {
- const idleCallback = (0,
- _requestidlecallback.requestIdleCallback)(() => setVisible(true));
- return () =>
- (0, _requestidlecallback.cancelIdleCallback)(idleCallback);
- }
- }
- // eslint-disable-next-line react-hooks/exhaustive-deps
- }, [isDisabled, rootMargin, rootRef, visible, elementRef.current]);
- const resetVisible = (0, _react.useCallback)(() => {
- setVisible(false);
- }, []);
- return [setElement, visible, resetVisible];
- }
- if (
- (typeof exports.default === "function" ||
- (typeof exports.default === "object" && exports.default !== null)) &&
- typeof exports.default.__esModule === "undefined"
- ) {
- Object.defineProperty(exports.default, "__esModule", {
- value: true,
- });
- Object.assign(exports.default, exports);
- module.exports = exports.default;
- } //# sourceMappingURL=use-intersection.js.map
-
- /***/
- },
-
- /***/ 8770: /***/ (
- module,
+ /***/ 9666: /***/ (
+ __unused_webpack_module,
__unused_webpack_exports,
__webpack_require__
) => {
- module.exports = __webpack_require__(3947);
+ (window.__NEXT_P = window.__NEXT_P || []).push([
+ "/link",
+ function () {
+ return __webpack_require__(3645);
+ },
+ ]);
+ if (false) {
+ }
/***/
},
@@ -764,7 +764,7 @@
/******/ var __webpack_exec__ = (moduleId) =>
__webpack_require__((__webpack_require__.s = moduleId));
/******/ __webpack_require__.O(0, [636, 6593, 8792], () =>
- __webpack_exec__(3568)
+ __webpack_exec__(9666)
);
/******/ var __webpack_exports__ = __webpack_require__.O();
/******/ _N_E = __webpack_exports__;
Diff for routerDirect-HASH.js
@@ -1,7 +1,24 @@
(self["webpackChunk_N_E"] = self["webpackChunk_N_E"] || []).push([
[188],
{
- /***/ 3618: /***/ (
+ /***/ 1810: /***/ (
+ __unused_webpack_module,
+ __unused_webpack_exports,
+ __webpack_require__
+ ) => {
+ (window.__NEXT_P = window.__NEXT_P || []).push([
+ "/routerDirect",
+ function () {
+ return __webpack_require__(7989);
+ },
+ ]);
+ if (false) {
+ }
+
+ /***/
+ },
+
+ /***/ 7989: /***/ (
__unused_webpack_module,
__webpack_exports__,
__webpack_require__
@@ -16,7 +33,7 @@
/* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__ =
__webpack_require__(5640);
/* harmony import */ var next_router__WEBPACK_IMPORTED_MODULE_1__ =
- __webpack_require__(4631);
+ __webpack_require__(9413);
/* harmony import */ var next_router__WEBPACK_IMPORTED_MODULE_1___default =
/*#__PURE__*/ __webpack_require__.n(
next_router__WEBPACK_IMPORTED_MODULE_1__
@@ -36,29 +53,12 @@
/***/
},
- /***/ 4631: /***/ (
+ /***/ 9413: /***/ (
module,
__unused_webpack_exports,
__webpack_require__
) => {
- module.exports = __webpack_require__(7086);
-
- /***/
- },
-
- /***/ 7824: /***/ (
- __unused_webpack_module,
- __unused_webpack_exports,
- __webpack_require__
- ) => {
- (window.__NEXT_P = window.__NEXT_P || []).push([
- "/routerDirect",
- function () {
- return __webpack_require__(3618);
- },
- ]);
- if (false) {
- }
+ module.exports = __webpack_require__(9751);
/***/
},
@@ -68,7 +68,7 @@
/******/ var __webpack_exec__ = (moduleId) =>
__webpack_require__((__webpack_require__.s = moduleId));
/******/ __webpack_require__.O(0, [636, 6593, 8792], () =>
- __webpack_exec__(7824)
+ __webpack_exec__(1810)
);
/******/ var __webpack_exports__ = __webpack_require__.O();
/******/ _N_E = __webpack_exports__;
Diff for script-HASH.js
@@ -1,7 +1,17 @@
(self["webpackChunk_N_E"] = self["webpackChunk_N_E"] || []).push([
[1209],
{
- /***/ 1984: /***/ (
+ /***/ 2227: /***/ (
+ module,
+ __unused_webpack_exports,
+ __webpack_require__
+ ) => {
+ module.exports = __webpack_require__(9765);
+
+ /***/
+ },
+
+ /***/ 3642: /***/ (
__unused_webpack_module,
__unused_webpack_exports,
__webpack_require__
@@ -9,7 +19,7 @@
(window.__NEXT_P = window.__NEXT_P || []).push([
"/script",
function () {
- return __webpack_require__(5769);
+ return __webpack_require__(8034);
},
]);
if (false) {
@@ -18,7 +28,7 @@
/***/
},
- /***/ 5769: /***/ (
+ /***/ 8034: /***/ (
__unused_webpack_module,
__webpack_exports__,
__webpack_require__
@@ -33,7 +43,7 @@
/* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__ =
__webpack_require__(5640);
/* harmony import */ var next_script__WEBPACK_IMPORTED_MODULE_1__ =
- __webpack_require__(8293);
+ __webpack_require__(2227);
/* harmony import */ var next_script__WEBPACK_IMPORTED_MODULE_1___default =
/*#__PURE__*/ __webpack_require__.n(
next_script__WEBPACK_IMPORTED_MODULE_1__
@@ -65,23 +75,13 @@
/***/
},
-
- /***/ 8293: /***/ (
- module,
- __unused_webpack_exports,
- __webpack_require__
- ) => {
- module.exports = __webpack_require__(900);
-
- /***/
- },
},
/******/ (__webpack_require__) => {
// webpackRuntimeModules
/******/ var __webpack_exec__ = (moduleId) =>
__webpack_require__((__webpack_require__.s = moduleId));
/******/ __webpack_require__.O(0, [636, 6593, 8792], () =>
- __webpack_exec__(1984)
+ __webpack_exec__(3642)
);
/******/ var __webpack_exports__ = __webpack_require__.O();
/******/ _N_E = __webpack_exports__;
Diff for withRouter-HASH.js
@@ -1,34 +1,7 @@
(self["webpackChunk_N_E"] = self["webpackChunk_N_E"] || []).push([
[3263],
{
- /***/ 4631: /***/ (
- module,
- __unused_webpack_exports,
- __webpack_require__
- ) => {
- module.exports = __webpack_require__(7086);
-
- /***/
- },
-
- /***/ 9216: /***/ (
- __unused_webpack_module,
- __unused_webpack_exports,
- __webpack_require__
- ) => {
- (window.__NEXT_P = window.__NEXT_P || []).push([
- "/withRouter",
- function () {
- return __webpack_require__(9803);
- },
- ]);
- if (false) {
- }
-
- /***/
- },
-
- /***/ 9803: /***/ (
+ /***/ 2148: /***/ (
__unused_webpack_module,
__webpack_exports__,
__webpack_require__
@@ -43,7 +16,7 @@
/* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__ =
__webpack_require__(5640);
/* harmony import */ var next_router__WEBPACK_IMPORTED_MODULE_1__ =
- __webpack_require__(4631);
+ __webpack_require__(9413);
/* harmony import */ var next_router__WEBPACK_IMPORTED_MODULE_1___default =
/*#__PURE__*/ __webpack_require__.n(
next_router__WEBPACK_IMPORTED_MODULE_1__
@@ -61,13 +34,40 @@
/***/
},
+
+ /***/ 3962: /***/ (
+ __unused_webpack_module,
+ __unused_webpack_exports,
+ __webpack_require__
+ ) => {
+ (window.__NEXT_P = window.__NEXT_P || []).push([
+ "/withRouter",
+ function () {
+ return __webpack_require__(2148);
+ },
+ ]);
+ if (false) {
+ }
+
+ /***/
+ },
+
+ /***/ 9413: /***/ (
+ module,
+ __unused_webpack_exports,
+ __webpack_require__
+ ) => {
+ module.exports = __webpack_require__(9751);
+
+ /***/
+ },
},
/******/ (__webpack_require__) => {
// webpackRuntimeModules
/******/ var __webpack_exec__ = (moduleId) =>
__webpack_require__((__webpack_require__.s = moduleId));
/******/ __webpack_require__.O(0, [636, 6593, 8792], () =>
- __webpack_exec__(9216)
+ __webpack_exec__(3962)
);
/******/ var __webpack_exports__ = __webpack_require__.O();
/******/ _N_E = __webpack_exports__;
Diff for 4719-HASH.js
Diff too large to display
Diff for 6236-HASH.js
Diff too large to display
Diff for main-HASH.js
Diff too large to display
CodSpeed Performance Report
Merging #80255 will not alter performance
Comparing lubieowoce/rootparams-module (c18f675) with canary (29ae22b)
Summary
✅ 9 untouched benchmarks
I'm slightly worried that this might cause some unnecessary invalidations when new root params are added. AFAIU if the alias definition changes (because collected_root_params changes), we'll also have update the whole ResolveOptionsContext, which seems like it'd invalidate a lot of other things. feedback/ideas for improvement welcome.
That is absolutely correct.
What you want to do is pass down a Vc<CollectedRootParams>, that cell then doesn't change which when adding/removing root params. And then you mustn't read the cell when inserting the import mapping (which currently happens in get_next_root_params_mapping), so if you instead create a ImportMapping::Dynamic, then you would only read the root params when actually encountering a next/root-params imports (and then create the JS sourcecode inside of that).
- #81086

- #80684

- #80618

- #80255
👈 (View in Graphite) canary
This stack of pull requests is managed by Graphite. Learn more about stacking.
Each directory we traverse before finding a root layout is marked as a
contextDependency
Any new directory in app could also cause a new root param to be created. So I think you need to contextDependency on the app dir. And since it's recursive, this is the only dependency needed.