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

Also provide AppTree in NextPageContext #8223

Merged
merged 16 commits into from Aug 13, 2019
Merged

Conversation

ijjk
Copy link
Member

@ijjk ijjk commented Aug 2, 2019

Follow up to #7732 that exposes AppTree in NextPageContext.

Might be good to remove AppTree from AppContextType since it's being supplied in two places here and _app could still access the value in ctx.AppTree

@timneutkens
Copy link
Member

Related to urql-graphql/urql#344 (comment)

@Timer Timer added this to the 9.0.4 milestone Aug 4, 2019
@ijjk
Copy link
Member Author

ijjk commented Aug 5, 2019

Stats from current PR

Click to expand stats ⚠️ Total Bundle Size Increase ⚠️
zeit/next.js canary ijjk/next.js add-apptree-ctx Change
Build Duration 12.2s 12.2s -41ms
node_modules Size 43.6 MB 43.6 MB ⚠️ +564 B
Total Bundle (main, webpack, commons) Size 206 kB 206 kB ⚠️ +94 B
Total Bundle (main, webpack, commons) gzip Size 67.8 kB 67.8 kB ⚠️ +30 B
Client _app Size 2.39 kB 2.39 kB
Client _app gzip Size 1.08 kB 1.08 kB
Client _error Size 8.22 kB 8.22 kB
Client _error gzip Size 3.16 kB 3.16 kB
Client pages/index Size 343 B 343 B
Client pages/index gzip Size 246 B 246 B
Client pages/link Size 4.08 kB 4.08 kB
Client pages/link gzip Size 1.8 kB 1.8 kB
Client pages/routerDirect Size 423 B 423 B
Client pages/routerDirect gzip Size 306 B 306 B
Client pages/withRouter Size 435 B 435 B
Client pages/withRouter gzip Size 301 B 301 B
Client main Size 15.4 kB 15.4 kB ⚠️ +32 B
Client main gzip Size 5.35 kB 5.36 kB ⚠️ +11 B
Client commons Size 188 kB 188 kB ⚠️ +62 B
Client commons gzip Size 61.1 kB 61.1 kB ⚠️ +19 B
Client webpack Size 1.53 kB 1.53 kB
Client webpack gzip Size 778 B 778 B
Base Rendered Size 1.35 kB 1.35 kB
Build Dir Size 702 kB 703 kB ⚠️ +536 B
Click to expand serverless stats ⚠️ Total Bundle Size Increase ⚠️
zeit/next.js canary ijjk/next.js add-apptree-ctx Change
Build Duration 13s 13.3s ⚠️ +318ms
node_modules Size 43.6 MB 43.6 MB ⚠️ +564 B
Total Bundle (main, webpack, commons) Size 206 kB 206 kB ⚠️ +94 B
Total Bundle (main, webpack, commons) gzip Size 67.8 kB 67.8 kB ⚠️ +30 B
Client _app Size 2.39 kB 2.39 kB
Client _app gzip Size 1.08 kB 1.08 kB
Client _error Size 8.22 kB 8.22 kB
Client _error gzip Size 3.16 kB 3.16 kB
Client pages/index Size 343 B 343 B
Client pages/index gzip Size 246 B 246 B
Client pages/link Size 4.08 kB 4.08 kB
Client pages/link gzip Size 1.8 kB 1.8 kB
Client pages/routerDirect Size 423 B 423 B
Client pages/routerDirect gzip Size 306 B 306 B
Client pages/withRouter Size 435 B 435 B
Client pages/withRouter gzip Size 301 B 301 B
Client main Size 15.4 kB 15.4 kB ⚠️ +32 B
Client main gzip Size 5.35 kB 5.36 kB ⚠️ +11 B
Client commons Size 188 kB 188 kB ⚠️ +62 B
Client commons gzip Size 61.1 kB 61.1 kB ⚠️ +19 B
Client webpack Size 1.53 kB 1.53 kB
Client webpack gzip Size 778 B 778 B
Serverless pages/link Size 251 kB 251 kB ⚠️ +137 B
Serverless pages/link gzip Size 67.8 kB 67.9 kB ⚠️ +37 B
Serverless pages/index Size 244 kB 244 kB ⚠️ +137 B
Serverless pages/index gzip Size 65.6 kB 65.7 kB ⚠️ +37 B
Serverless pages/_error Size 243 kB 243 kB ⚠️ +137 B
Serverless pages/_error gzip Size 65.4 kB 65.4 kB ⚠️ +37 B
Serverless pages/routerDirect Size 244 kB 245 kB ⚠️ +137 B
Serverless pages/routerDirect gzip Size 65.6 kB 65.6 kB ⚠️ +37 B
Serverless pages/withRouter Size 244 kB 245 kB ⚠️ +137 B
Serverless pages/withRouter gzip Size 65.7 kB 65.8 kB ⚠️ +34 B
Build Dir Size 1.89 MB 1.89 MB ⚠️ +1.36 kB
Diff for commons.js
@@ -3336,7 +3336,8 @@ function () {
           var ctx = {
             pathname: pathname,
             query: query,
-            asPath: as
+            asPath: as,
+            AppTree: null
           };
 
           _this3.getInitialProps(Component, ctx).then(function (props) {
@@ -3378,7 +3379,8 @@ function () {
             var ctx = {
               err: err,
               pathname: pathname,
-              query: query
+              query: query,
+              AppTree: null
             };
             return new _promise["default"](function (resolve) {
               _this3.getInitialProps(Component, ctx).then(function (props) {
@@ -3563,7 +3565,7 @@ function () {
       var _getInitialProps = (0, _asyncToGenerator2["default"])(
       /*#__PURE__*/
       _regenerator["default"].mark(function _callee2(Component, ctx) {
-        var cancelled, cancel, App, props, err;
+        var cancelled, cancel, App, AppTree, props, err;
         return _regenerator["default"].wrap(function _callee2$(_context2) {
           while (1) {
             switch (_context2.prev = _context2.next) {
@@ -3576,15 +3578,18 @@ function () {
 
                 this.clc = cancel;
                 App = this.components['/_app'].Component;
-                _context2.next = 6;
+                AppTree = this._wrapApp(App);
+                _context2.next = 7;
                 return utils_1.loadGetInitialProps(App, {
-                  AppTree: this._wrapApp(App),
+                  AppTree: AppTree,
                   Component: Component,
                   router: this,
-                  ctx: ctx
+                  ctx: (0, _assign["default"])({}, ctx, {
+                    AppTree: AppTree
+                  })
                 });
 
-              case 6:
+              case 7:
                 props = _context2.sent;
 
                 if (cancel === this.clc) {
@@ -3592,7 +3597,7 @@ function () {
                 }
 
                 if (!cancelled) {
-                  _context2.next = 12;
+                  _context2.next = 13;
                   break;
                 }
 
@@ -3600,10 +3605,10 @@ function () {
                 err.cancelled = true;
                 throw err;
 
-              case 12:
+              case 13:
                 return _context2.abrupt("return", props);
 
-              case 13:
+              case 14:
               case "end":
                 return _context2.stop();
             }
Diff for main.js
@@ -670,7 +670,7 @@ function _renderError() {
   _renderError = (0, _asyncToGenerator2["default"])(
   /*#__PURE__*/
   _regenerator["default"].mark(function _callee3(props) {
-    var App, err, appCtx, initProps;
+    var App, err, AppTree, appCtx, initProps;
     return _regenerator["default"].wrap(function _callee3$(_context3) {
       while (1) {
         switch (_context3.prev = _context3.next) {
@@ -696,44 +696,46 @@ function _renderError() {
             // In production we do a normal render with the `ErrorComponent` as component.
             // If we've gotten here upon initial render, we can use the props from the server.
             // Otherwise, we need to call `getInitialProps` on `App` before mounting.
+            AppTree = wrapApp(App);
             appCtx = {
-              AppTree: wrapApp(App),
               Component: ErrorComponent,
+              AppTree: AppTree,
               router: router,
               ctx: {
                 err: err,
                 pathname: page,
                 query: query,
-                asPath: asPath
+                asPath: asPath,
+                AppTree: AppTree
               }
             };
 
             if (!props.props) {
-              _context3.next = 12;
+              _context3.next = 13;
               break;
             }
 
             _context3.t0 = props.props;
-            _context3.next = 15;
+            _context3.next = 16;
             break;
 
-          case 12:
-            _context3.next = 14;
+          case 13:
+            _context3.next = 15;
             return (0, _utils.loadGetInitialProps)(App, appCtx);
 
-          case 14:
+          case 15:
             _context3.t0 = _context3.sent;
 
-          case 15:
+          case 16:
             initProps = _context3.t0;
-            _context3.next = 18;
+            _context3.next = 19;
             return doRender((0, _extends2["default"])({}, props, {
               err: err,
               Component: ErrorComponent,
               props: initProps
             }));
 
-          case 18:
+          case 19:
           case "end":
             return _context3.stop();
         }
@@ -797,7 +799,7 @@ function _doRender() {
   _doRender = (0, _asyncToGenerator2["default"])(
   /*#__PURE__*/
   _regenerator["default"].mark(function _callee4(_ref5) {
-    var App, Component, props, err, _router2, pathname, _query, _asPath, appCtx, appProps;
+    var App, Component, props, err, _router2, pathname, _query, _asPath, AppTree, appCtx, appProps;
 
     return _regenerator["default"].wrap(function _callee4$(_context4) {
       while (1) {
@@ -807,29 +809,31 @@ function _doRender() {
             // this is for when ErrorComponent gets replaced by Component by HMR
 
             if (!(!props && Component && Component !== ErrorComponent && lastAppProps.Component === ErrorComponent)) {
-              _context4.next = 7;
+              _context4.next = 8;
               break;
             }
 
             _router2 = router, pathname = _router2.pathname, _query = _router2.query, _asPath = _router2.asPath;
+            AppTree = wrapApp(App);
             appCtx = {
               router: router,
-              AppTree: wrapApp(App),
+              AppTree: AppTree,
               Component: ErrorComponent,
               ctx: {
                 err: err,
                 pathname: pathname,
                 query: _query,
-                asPath: _asPath
+                asPath: _asPath,
+                AppTree: AppTree
               }
             };
-            _context4.next = 6;
+            _context4.next = 7;
             return (0, _utils.loadGetInitialProps)(App, appCtx);
 
-          case 6:
+          case 7:
             props = _context4.sent;
 
-          case 7:
+          case 8:
             Component = Component || lastAppProps.Component;
             props = props || lastAppProps.props;
             appProps = (0, _extends2["default"])({}, props, {
@@ -852,7 +856,7 @@ function _doRender() {
               appProps: appProps
             });
 
-          case 14:
+          case 15:
           case "end":
             return _context4.stop();
         }

@timneutkens
Copy link
Member

Screenshot 2019-08-06 at 15 43 37

I guess those two null declarations are not really needed 🤔

@ijjk
Copy link
Member Author

ijjk commented Aug 6, 2019

Stats from current PR

Click to expand stats ⚠️ Total Bundle Size Increase ⚠️
zeit/next.js canary ijjk/next.js add-apptree-ctx Change
Build Duration 13.8s 13.7s -133ms
node_modules Size 43.6 MB 43.6 MB ⚠️ +724 B
Total Bundle (main, webpack, commons) Size 206 kB 206 kB ⚠️ +68 B
Total Bundle (main, webpack, commons) gzip Size 67.8 kB 67.8 kB ⚠️ +21 B
Client _app Size 2.39 kB 2.39 kB
Client _app gzip Size 1.08 kB 1.08 kB -1 B
Client _error Size 8.22 kB 8.22 kB
Client _error gzip Size 3.16 kB 3.16 kB
Client pages/index Size 343 B 343 B
Client pages/index gzip Size 246 B 246 B
Client pages/link Size 4.08 kB 4.08 kB
Client pages/link gzip Size 1.8 kB 1.8 kB
Client pages/routerDirect Size 423 B 423 B
Client pages/routerDirect gzip Size 306 B 306 B
Client pages/withRouter Size 435 B 435 B
Client pages/withRouter gzip Size 301 B 300 B -1 B
Client main Size 15.4 kB 15.4 kB ⚠️ +32 B
Client main gzip Size 5.35 kB 5.36 kB ⚠️ +11 B
Client commons Size 188 kB 188 kB ⚠️ +36 B
Client commons gzip Size 61.1 kB 61.1 kB ⚠️ +11 B
Client webpack Size 1.53 kB 1.53 kB
Client webpack gzip Size 778 B 778 B
Base Rendered Size 1.35 kB 1.35 kB
Build Dir Size 700 kB 701 kB ⚠️ +519 B
Click to expand serverless stats ⚠️ Total Bundle Size Increase ⚠️
zeit/next.js canary ijjk/next.js add-apptree-ctx Change
Build Duration 14.8s 15.2s ⚠️ +470ms
node_modules Size 43.6 MB 43.6 MB ⚠️ +724 B
Total Bundle (main, webpack, commons) Size 206 kB 206 kB ⚠️ +68 B
Total Bundle (main, webpack, commons) gzip Size 67.8 kB 67.8 kB ⚠️ +22 B
Client _app Size 2.39 kB 2.39 kB
Client _app gzip Size 1.08 kB 1.08 kB
Client _error Size 8.22 kB 8.22 kB
Client _error gzip Size 3.16 kB 3.16 kB
Client pages/index Size 343 B 343 B
Client pages/index gzip Size 246 B 246 B
Client pages/link Size 4.08 kB 4.08 kB
Client pages/link gzip Size 1.8 kB 1.8 kB
Client pages/routerDirect Size 423 B 423 B
Client pages/routerDirect gzip Size 306 B 306 B
Client pages/withRouter Size 435 B 435 B
Client pages/withRouter gzip Size 301 B 301 B
Client main Size 15.4 kB 15.4 kB ⚠️ +32 B
Client main gzip Size 5.35 kB 5.36 kB ⚠️ +11 B
Client commons Size 188 kB 188 kB ⚠️ +36 B
Client commons gzip Size 61.1 kB 61.1 kB ⚠️ +11 B
Client webpack Size 1.53 kB 1.53 kB
Client webpack gzip Size 778 B 778 B
Serverless pages/link Size 251 kB 251 kB ⚠️ +174 B
Serverless pages/link gzip Size 67.8 kB 67.8 kB ⚠️ +63 B
Serverless pages/index Size 243 kB 244 kB ⚠️ +174 B
Serverless pages/index gzip Size 65.6 kB 65.7 kB ⚠️ +63 B
Serverless pages/_error Size 243 kB 243 kB ⚠️ +174 B
Serverless pages/_error gzip Size 65.3 kB 65.4 kB ⚠️ +61 B
Serverless pages/routerDirect Size 244 kB 244 kB ⚠️ +174 B
Serverless pages/routerDirect gzip Size 65.5 kB 65.6 kB ⚠️ +61 B
Serverless pages/withRouter Size 244 kB 244 kB ⚠️ +174 B
Serverless pages/withRouter gzip Size 65.7 kB 65.7 kB ⚠️ +62 B
Build Dir Size 1.88 MB 1.89 MB ⚠️ +1.56 kB
Diff for commons.js
@@ -3333,6 +3333,7 @@ function () {
         if (false) { var _require, isValidElementType; }
 
         return new _promise["default"](function (resolve, reject) {
+          // we provide AppTree later so this needs to be `any`
           var ctx = {
             pathname: pathname,
             query: query,
@@ -3374,7 +3375,8 @@ function () {
             var routeInfo = {
               Component: Component,
               err: err
-            };
+            }; // AppTree provided later
+
             var ctx = {
               err: err,
               pathname: pathname,
@@ -3563,7 +3565,7 @@ function () {
       var _getInitialProps = (0, _asyncToGenerator2["default"])(
       /*#__PURE__*/
       _regenerator["default"].mark(function _callee2(Component, ctx) {
-        var cancelled, cancel, App, props, err;
+        var cancelled, cancel, App, AppTree, props, err;
         return _regenerator["default"].wrap(function _callee2$(_context2) {
           while (1) {
             switch (_context2.prev = _context2.next) {
@@ -3576,15 +3578,18 @@ function () {
 
                 this.clc = cancel;
                 App = this.components['/_app'].Component;
-                _context2.next = 6;
+                AppTree = this._wrapApp(App);
+                _context2.next = 7;
                 return utils_1.loadGetInitialProps(App, {
-                  AppTree: this._wrapApp(App),
+                  AppTree: AppTree,
                   Component: Component,
                   router: this,
-                  ctx: ctx
+                  ctx: (0, _assign["default"])({}, ctx, {
+                    AppTree: AppTree
+                  })
                 });
 
-              case 6:
+              case 7:
                 props = _context2.sent;
 
                 if (cancel === this.clc) {
@@ -3592,7 +3597,7 @@ function () {
                 }
 
                 if (!cancelled) {
-                  _context2.next = 12;
+                  _context2.next = 13;
                   break;
                 }
 
@@ -3600,10 +3605,10 @@ function () {
                 err.cancelled = true;
                 throw err;
 
-              case 12:
+              case 13:
                 return _context2.abrupt("return", props);
 
-              case 13:
+              case 14:
               case "end":
                 return _context2.stop();
             }
Diff for main.js
@@ -670,7 +670,7 @@ function _renderError() {
   _renderError = (0, _asyncToGenerator2["default"])(
   /*#__PURE__*/
   _regenerator["default"].mark(function _callee3(props) {
-    var App, err, appCtx, initProps;
+    var App, err, AppTree, appCtx, initProps;
     return _regenerator["default"].wrap(function _callee3$(_context3) {
       while (1) {
         switch (_context3.prev = _context3.next) {
@@ -696,44 +696,46 @@ function _renderError() {
             // In production we do a normal render with the `ErrorComponent` as component.
             // If we've gotten here upon initial render, we can use the props from the server.
             // Otherwise, we need to call `getInitialProps` on `App` before mounting.
+            AppTree = wrapApp(App);
             appCtx = {
-              AppTree: wrapApp(App),
               Component: ErrorComponent,
+              AppTree: AppTree,
               router: router,
               ctx: {
                 err: err,
                 pathname: page,
                 query: query,
-                asPath: asPath
+                asPath: asPath,
+                AppTree: AppTree
               }
             };
 
             if (!props.props) {
-              _context3.next = 12;
+              _context3.next = 13;
               break;
             }
 
             _context3.t0 = props.props;
-            _context3.next = 15;
+            _context3.next = 16;
             break;
 
-          case 12:
-            _context3.next = 14;
+          case 13:
+            _context3.next = 15;
             return (0, _utils.loadGetInitialProps)(App, appCtx);
 
-          case 14:
+          case 15:
             _context3.t0 = _context3.sent;
 
-          case 15:
+          case 16:
             initProps = _context3.t0;
-            _context3.next = 18;
+            _context3.next = 19;
             return doRender((0, _extends2["default"])({}, props, {
               err: err,
               Component: ErrorComponent,
               props: initProps
             }));
 
-          case 18:
+          case 19:
           case "end":
             return _context3.stop();
         }
@@ -797,7 +799,7 @@ function _doRender() {
   _doRender = (0, _asyncToGenerator2["default"])(
   /*#__PURE__*/
   _regenerator["default"].mark(function _callee4(_ref5) {
-    var App, Component, props, err, _router2, pathname, _query, _asPath, appCtx, appProps;
+    var App, Component, props, err, _router2, pathname, _query, _asPath, AppTree, appCtx, appProps;
 
     return _regenerator["default"].wrap(function _callee4$(_context4) {
       while (1) {
@@ -807,29 +809,31 @@ function _doRender() {
             // this is for when ErrorComponent gets replaced by Component by HMR
 
             if (!(!props && Component && Component !== ErrorComponent && lastAppProps.Component === ErrorComponent)) {
-              _context4.next = 7;
+              _context4.next = 8;
               break;
             }
 
             _router2 = router, pathname = _router2.pathname, _query = _router2.query, _asPath = _router2.asPath;
+            AppTree = wrapApp(App);
             appCtx = {
               router: router,
-              AppTree: wrapApp(App),
+              AppTree: AppTree,
               Component: ErrorComponent,
               ctx: {
                 err: err,
                 pathname: pathname,
                 query: _query,
-                asPath: _asPath
+                asPath: _asPath,
+                AppTree: AppTree
               }
             };
-            _context4.next = 6;
+            _context4.next = 7;
             return (0, _utils.loadGetInitialProps)(App, appCtx);
 
-          case 6:
+          case 7:
             props = _context4.sent;
 
-          case 7:
+          case 8:
             Component = Component || lastAppProps.Component;
             props = props || lastAppProps.props;
             appProps = (0, _extends2["default"])({}, props, {
@@ -852,7 +856,7 @@ function _doRender() {
               appProps: appProps
             });
 
-          case 14:
+          case 15:
           case "end":
             return _context4.stop();
         }

@ijjk
Copy link
Member Author

ijjk commented Aug 8, 2019

Stats from current PR

Click to expand stats ⚠️ Total Bundle Size Increase ⚠️
zeit/next.js canary ijjk/next.js add-apptree-ctx Change
Build Duration 22.6s 22.7s ⚠️ +118ms
node_modules Size 43.6 MB 43.6 MB ⚠️ +712 B
Total Bundle (main, webpack, commons) Size 207 kB 207 kB ⚠️ +68 B
Total Bundle (main, webpack, commons) gzip Size 68.1 kB 68.1 kB ⚠️ +24 B
Total Bundle (main, webpack, commons) Modern Size 182 kB 182 kB ⚠️ +68 B
Total Bundle (main, webpack, commons) Modern gzip Size 59.9 kB 59.9 kB ⚠️ +28 B
Client _app Size 2.39 kB 2.39 kB
Client _app gzip Size 1.08 kB 1.08 kB ⚠️ +1 B
Client _app Modern Size 1.83 kB 1.83 kB
Client _app gzip Modern Size 890 B 890 B
Client _error Size 8.22 kB 8.22 kB
Client _error gzip Size 3.16 kB 3.16 kB
Client _error Modern Size 5.85 kB 5.85 kB
Client _error gzip Modern Size 2.33 kB 2.33 kB
Client pages/index Size 343 B 343 B
Client pages/index gzip Size 246 B 246 B
Client pages/index Modern Size 319 B 319 B
Client pages/index gzip Modern Size 254 B 254 B
Client pages/link Size 4.08 kB 4.08 kB
Client pages/link gzip Size 1.8 kB 1.8 kB
Client pages/link Modern Size 3.7 kB 3.7 kB
Client pages/link gzip Modern Size 1.7 kB 1.7 kB
Client pages/routerDirect Size 423 B 423 B
Client pages/routerDirect gzip Size 306 B 306 B
Client pages/routerDirect Modern Size 411 B 411 B
Client pages/routerDirect gzip Modern Size 314 B 314 B
Client pages/withRouter Size 435 B 435 B
Client pages/withRouter gzip Size 300 B 301 B ⚠️ +1 B
Client pages/withRouter Modern Size 423 B 423 B
Client pages/withRouter gzip Modern Size 309 B 309 B
Client main Size 15.8 kB 15.8 kB ⚠️ +32 B
Client main gzip Size 5.46 kB 5.48 kB ⚠️ +17 B
Client main Modern Size 12.8 kB 12.9 kB ⚠️ +28 B
Client main Modern gzip Size 4.83 kB 4.85 kB ⚠️ +17 B
Client commons Size 188 kB 188 kB ⚠️ +36 B
Client commons gzip Size 61.3 kB 61.3 kB ⚠️ +6 B
Client commons Modern Size 169 kB 169 kB ⚠️ +40 B
Client commons Modern gzip Size 55.1 kB 55.1 kB ⚠️ +11 B
Client webpack Size 1.53 kB 1.53 kB
Client webpack gzip Size 778 B 778 B
Client webpack Modern Size 1.53 kB 1.53 kB
Client webpack Modern gzip Size 785 B 785 B
Base Rendered Size 2.76 kB 2.76 kB
Build Dir Size 1.39 MB 1.39 MB ⚠️ +985 B
Click to expand serverless stats ⚠️ Total Bundle Size Increase ⚠️
zeit/next.js canary ijjk/next.js add-apptree-ctx Change
Build Duration 23.8s 23.6s -237ms
node_modules Size 43.6 MB 43.6 MB ⚠️ +712 B
Total Bundle (main, webpack, commons) Size 207 kB 207 kB ⚠️ +68 B
Total Bundle (main, webpack, commons) gzip Size 68.1 kB 68.1 kB ⚠️ +25 B
Total Bundle (main, webpack, commons) Modern Size 182 kB 182 kB ⚠️ +68 B
Total Bundle (main, webpack, commons) Modern gzip Size 59.9 kB 59.9 kB ⚠️ +28 B
Client _app Size 2.39 kB 2.39 kB
Client _app gzip Size 1.08 kB 1.08 kB
Client _app Modern Size 1.83 kB 1.83 kB
Client _app gzip Modern Size 890 B 890 B
Client _error Size 8.22 kB 8.22 kB
Client _error gzip Size 3.16 kB 3.16 kB
Client _error Modern Size 5.85 kB 5.85 kB
Client _error gzip Modern Size 2.33 kB 2.33 kB
Client pages/index Size 343 B 343 B
Client pages/index gzip Size 246 B 246 B
Client pages/index Modern Size 319 B 319 B
Client pages/index gzip Modern Size 254 B 254 B
Client pages/link Size 4.08 kB 4.08 kB
Client pages/link gzip Size 1.8 kB 1.8 kB
Client pages/link Modern Size 3.7 kB 3.7 kB
Client pages/link gzip Modern Size 1.7 kB 1.7 kB
Client pages/routerDirect Size 423 B 423 B
Client pages/routerDirect gzip Size 306 B 306 B
Client pages/routerDirect Modern Size 411 B 411 B
Client pages/routerDirect gzip Modern Size 314 B 314 B
Client pages/withRouter Size 435 B 435 B
Client pages/withRouter gzip Size 301 B 301 B
Client pages/withRouter Modern Size 423 B 423 B
Client pages/withRouter gzip Modern Size 309 B 309 B
Client main Size 15.8 kB 15.8 kB ⚠️ +32 B
Client main gzip Size 5.46 kB 5.48 kB ⚠️ +19 B
Client main Modern Size 12.8 kB 12.9 kB ⚠️ +28 B
Client main Modern gzip Size 4.83 kB 4.85 kB ⚠️ +17 B
Client commons Size 188 kB 188 kB ⚠️ +36 B
Client commons gzip Size 61.3 kB 61.3 kB ⚠️ +6 B
Client commons Modern Size 169 kB 169 kB ⚠️ +40 B
Client commons Modern gzip Size 55.1 kB 55.1 kB ⚠️ +11 B
Client webpack Size 1.53 kB 1.53 kB
Client webpack gzip Size 778 B 778 B
Client webpack Modern Size 1.53 kB 1.53 kB
Client webpack Modern gzip Size 785 B 785 B
Serverless pages/link Size 255 kB 255 kB ⚠️ +173 B
Serverless pages/link gzip Size 68.6 kB 68.6 kB ⚠️ +60 B
Serverless pages/index Size 248 kB 248 kB ⚠️ +173 B
Serverless pages/index gzip Size 66.4 kB 66.4 kB ⚠️ +60 B
Serverless pages/_error Size 247 kB 247 kB ⚠️ +173 B
Serverless pages/_error gzip Size 66.1 kB 66.2 kB ⚠️ +59 B
Serverless pages/routerDirect Size 248 kB 248 kB ⚠️ +173 B
Serverless pages/routerDirect gzip Size 66.3 kB 66.4 kB ⚠️ +59 B
Serverless pages/withRouter Size 248 kB 248 kB ⚠️ +173 B
Serverless pages/withRouter gzip Size 66.4 kB 66.5 kB ⚠️ +74 B
Build Dir Size 2.59 MB 2.6 MB ⚠️ +2.03 kB
Diff for main.js
@@ -695,7 +695,7 @@ function _renderError() {
   _renderError = (0, _asyncToGenerator2["default"])(
   /*#__PURE__*/
   _regenerator["default"].mark(function _callee3(props) {
-    var App, err, appCtx, initProps;
+    var App, err, AppTree, appCtx, initProps;
     return _regenerator["default"].wrap(function _callee3$(_context3) {
       while (1) {
         switch (_context3.prev = _context3.next) {
@@ -721,44 +721,46 @@ function _renderError() {
             // In production we do a normal render with the `ErrorComponent` as component.
             // If we've gotten here upon initial render, we can use the props from the server.
             // Otherwise, we need to call `getInitialProps` on `App` before mounting.
+            AppTree = wrapApp(App);
             appCtx = {
-              AppTree: wrapApp(App),
               Component: ErrorComponent,
+              AppTree: AppTree,
               router: router,
               ctx: {
                 err: err,
                 pathname: page,
                 query: query,
-                asPath: asPath
+                asPath: asPath,
+                AppTree: AppTree
               }
             };
 
             if (!props.props) {
-              _context3.next = 12;
+              _context3.next = 13;
               break;
             }
 
             _context3.t0 = props.props;
-            _context3.next = 15;
+            _context3.next = 16;
             break;
 
-          case 12:
-            _context3.next = 14;
+          case 13:
+            _context3.next = 15;
             return (0, _utils.loadGetInitialProps)(App, appCtx);
 
-          case 14:
+          case 15:
             _context3.t0 = _context3.sent;
 
-          case 15:
+          case 16:
             initProps = _context3.t0;
-            _context3.next = 18;
+            _context3.next = 19;
             return doRender((0, _extends2["default"])({}, props, {
               err: err,
               Component: ErrorComponent,
               props: initProps
             }));
 
-          case 18:
+          case 19:
           case "end":
             return _context3.stop();
         }
@@ -822,7 +824,7 @@ function _doRender() {
   _doRender = (0, _asyncToGenerator2["default"])(
   /*#__PURE__*/
   _regenerator["default"].mark(function _callee4(_ref5) {
-    var App, Component, props, err, _router2, pathname, _query, _asPath, appCtx, appProps;
+    var App, Component, props, err, _router2, pathname, _query, _asPath, AppTree, appCtx, appProps;
 
     return _regenerator["default"].wrap(function _callee4$(_context4) {
       while (1) {
@@ -832,29 +834,31 @@ function _doRender() {
             // this is for when ErrorComponent gets replaced by Component by HMR
 
             if (!(!props && Component && Component !== ErrorComponent && lastAppProps.Component === ErrorComponent)) {
-              _context4.next = 7;
+              _context4.next = 8;
               break;
             }
 
             _router2 = router, pathname = _router2.pathname, _query = _router2.query, _asPath = _router2.asPath;
+            AppTree = wrapApp(App);
             appCtx = {
               router: router,
-              AppTree: wrapApp(App),
+              AppTree: AppTree,
               Component: ErrorComponent,
               ctx: {
                 err: err,
                 pathname: pathname,
                 query: _query,
-                asPath: _asPath
+                asPath: _asPath,
+                AppTree: AppTree
               }
             };
-            _context4.next = 6;
+            _context4.next = 7;
             return (0, _utils.loadGetInitialProps)(App, appCtx);
 
-          case 6:
+          case 7:
             props = _context4.sent;
 
-          case 7:
+          case 8:
             Component = Component || lastAppProps.Component;
             props = props || lastAppProps.props;
             appProps = (0, _extends2["default"])({}, props, {
@@ -877,7 +881,7 @@ function _doRender() {
               appProps: appProps
             });
 
-          case 14:
+          case 15:
           case "end":
             return _context4.stop();
         }
Diff for commons.js
@@ -3340,6 +3340,7 @@ function () {
         if (false) { var _require, isValidElementType; }
 
         return new _promise["default"](function (resolve, reject) {
+          // we provide AppTree later so this needs to be `any`
           var ctx = {
             pathname: pathname,
             query: query,
@@ -3381,7 +3382,8 @@ function () {
             var routeInfo = {
               Component: Component,
               err: err
-            };
+            }; // AppTree provided later
+
             var ctx = {
               err: err,
               pathname: pathname,
@@ -3576,7 +3578,7 @@ function () {
       var _getInitialProps = (0, _asyncToGenerator2["default"])(
       /*#__PURE__*/
       _regenerator["default"].mark(function _callee2(Component, ctx) {
-        var cancelled, cancel, App, props, url, res, err;
+        var cancelled, cancel, App, props, url, res, AppTree, err;
         return _regenerator["default"].wrap(function _callee2$(_context2) {
           while (1) {
             switch (_context2.prev = _context2.next) {
@@ -3637,28 +3639,31 @@ function () {
                 props = {
                   pageProps: _context2.t1
                 };
-                _context2.next = 23;
+                _context2.next = 24;
                 break;
 
               case 20:
-                _context2.next = 22;
+                AppTree = this._wrapApp(App);
+                _context2.next = 23;
                 return utils_1.loadGetInitialProps(App, {
-                  AppTree: this._wrapApp(App),
+                  AppTree: AppTree,
                   Component: Component,
                   router: this,
-                  ctx: ctx
+                  ctx: (0, _assign["default"])({}, ctx, {
+                    AppTree: AppTree
+                  })
                 });
 
-              case 22:
+              case 23:
                 props = _context2.sent;
 
-              case 23:
+              case 24:
                 if (cancel === this.clc) {
                   this.clc = null;
                 }
 
                 if (!cancelled) {
-                  _context2.next = 28;
+                  _context2.next = 29;
                   break;
                 }
 
@@ -3666,10 +3671,10 @@ function () {
                 err.cancelled = true;
                 throw err;
 
-              case 28:
+              case 29:
                 return _context2.abrupt("return", props);
 
-              case 29:
+              case 30:
               case "end":
                 return _context2.stop();
             }
Diff for mainModern.js
@@ -575,15 +575,17 @@ function _renderError() {
     // If we've gotten here upon initial render, we can use the props from the server.
     // Otherwise, we need to call `getInitialProps` on `App` before mounting.
 
+    const AppTree = wrapApp(App);
     const appCtx = {
-      AppTree: wrapApp(App),
       Component: ErrorComponent,
+      AppTree,
       router,
       ctx: {
         err,
         pathname: page,
         query,
-        asPath
+        asPath,
+        AppTree
       }
     };
     const initProps = props.props ? props.props : yield (0, _utils.loadGetInitialProps)(App, appCtx);
@@ -658,15 +660,17 @@ function _doRender() {
         query,
         asPath
       } = router;
+      const AppTree = wrapApp(App);
       const appCtx = {
         router,
-        AppTree: wrapApp(App),
+        AppTree,
         Component: ErrorComponent,
         ctx: {
           err,
           pathname,
           query,
-          asPath
+          asPath,
+          AppTree
         }
       };
       props = yield (0, _utils.loadGetInitialProps)(App, appCtx);
Diff for commonsModern.js
@@ -2815,6 +2815,7 @@ class Router {
       if (false) {}
 
       return new _promise.default((resolve, reject) => {
+        // we provide AppTree later so this needs to be `any`
         const ctx = {
           pathname,
           query,
@@ -2855,7 +2856,8 @@ class Router {
           const routeInfo = {
             Component,
             err
-          };
+          }; // AppTree provided later
+
           const ctx = {
             err,
             pathname,
@@ -3026,11 +3028,15 @@ class Router {
         }
       };
     } else {
+      const AppTree = this._wrapApp(App);
+
       props = await utils_1.loadGetInitialProps(App, {
-        AppTree: this._wrapApp(App),
+        AppTree,
         Component,
         router: this,
-        ctx
+        ctx: (0, _assign.default)({}, ctx, {
+          AppTree
+        })
       });
     }
 

@ijjk
Copy link
Member Author

ijjk commented Aug 11, 2019

Stats from current PR

Click to expand stats ✅ Total Bundle Size Decrease ✅
zeit/next.js canary ijjk/next.js add-apptree-ctx Change
Build Duration 23s 23.2s ⚠️ +210ms
node_modules Size 41.6 MB 41.6 MB -13.8 kB
Total Bundle (main, webpack, commons) Size 214 kB 214 kB -659 B
Total Bundle (main, webpack, commons) gzip Size 70.6 kB 70.3 kB -318 B
Total Bundle (main, webpack, commons) Modern Size 189 kB 189 kB -491 B
Total Bundle (main, webpack, commons) Modern gzip Size 62.4 kB 62.1 kB -236 B
Client _app Size 2.35 kB 2.39 kB ⚠️ +35 B
Client _app gzip Size 1.07 kB 1.08 kB ⚠️ +8 B
Client _app Modern Size 1.79 kB 1.83 kB ⚠️ +35 B
Client _app gzip Modern Size 880 B 890 B ⚠️ +10 B
Client _error Size 8.22 kB 8.22 kB
Client _error gzip Size 3.16 kB 3.16 kB
Client _error Modern Size 5.85 kB 5.85 kB
Client _error gzip Modern Size 2.33 kB 2.33 kB
Client pages/index Size 343 B 343 B
Client pages/index gzip Size 246 B 246 B
Client pages/index Modern Size 319 B 319 B
Client pages/index gzip Modern Size 254 B 254 B
Client pages/link Size 4.18 kB 4.08 kB -104 B
Client pages/link gzip Size 1.82 kB 1.8 kB -26 B
Client pages/link Modern Size 3.81 kB 3.7 kB -113 B
Client pages/link gzip Modern Size 1.72 kB 1.7 kB -28 B
Client pages/routerDirect Size 423 B 423 B
Client pages/routerDirect gzip Size 306 B 306 B
Client pages/routerDirect Modern Size 411 B 411 B
Client pages/routerDirect gzip Modern Size 314 B 314 B
Client pages/withRouter Size 435 B 435 B
Client pages/withRouter gzip Size 301 B 301 B
Client pages/withRouter Modern Size 423 B 423 B
Client pages/withRouter gzip Modern Size 309 B 309 B
Client main Size 16.3 kB 15.8 kB -439 B
Client main gzip Size 5.73 kB 5.48 kB -250 B
Client main Modern Size 13.1 kB 12.9 kB -238 B
Client main Modern gzip Size 4.99 kB 4.85 kB -144 B
Client commons Size 195 kB 195 kB -255 B
Client commons gzip Size 63.6 kB 63.5 kB -76 B
Client commons Modern Size 176 kB 176 kB -253 B
Client commons Modern gzip Size 57.4 kB 57.3 kB -92 B
Client webpack Size 1.53 kB 1.53 kB
Client webpack gzip Size 778 B 778 B
Client webpack Modern Size 1.53 kB 1.53 kB
Client webpack Modern gzip Size 785 B 785 B
Base Rendered Size 2.76 kB 2.76 kB
Build Dir Size 1.44 MB 1.43 MB -10.1 kB
Click to expand serverless stats ✅ Total Bundle Size Decrease ✅
zeit/next.js canary ijjk/next.js add-apptree-ctx Change
Build Duration 25.4s 24.6s -814ms
node_modules Size 41.6 MB 41.6 MB -13.8 kB
Total Bundle (main, webpack, commons) Size 214 kB 214 kB -659 B
Total Bundle (main, webpack, commons) gzip Size 70.6 kB 70.3 kB -319 B
Total Bundle (main, webpack, commons) Modern Size 189 kB 189 kB -491 B
Total Bundle (main, webpack, commons) Modern gzip Size 62.4 kB 62.1 kB -236 B
Client _app Size 2.35 kB 2.39 kB ⚠️ +35 B
Client _app gzip Size 1.07 kB 1.08 kB ⚠️ +7 B
Client _app Modern Size 1.79 kB 1.83 kB ⚠️ +35 B
Client _app gzip Modern Size 880 B 890 B ⚠️ +10 B
Client _error Size 8.22 kB 8.22 kB
Client _error gzip Size 3.16 kB 3.16 kB
Client _error Modern Size 5.85 kB 5.85 kB
Client _error gzip Modern Size 2.33 kB 2.33 kB
Client pages/index Size 343 B 343 B
Client pages/index gzip Size 246 B 246 B
Client pages/index Modern Size 319 B 319 B
Client pages/index gzip Modern Size 254 B 254 B
Client pages/link Size 4.18 kB 4.08 kB -104 B
Client pages/link gzip Size 1.82 kB 1.8 kB -26 B
Client pages/link Modern Size 3.81 kB 3.7 kB -113 B
Client pages/link gzip Modern Size 1.72 kB 1.7 kB -28 B
Client pages/routerDirect Size 423 B 423 B
Client pages/routerDirect gzip Size 306 B 306 B
Client pages/routerDirect Modern Size 411 B 411 B
Client pages/routerDirect gzip Modern Size 314 B 314 B
Client pages/withRouter Size 435 B 435 B
Client pages/withRouter gzip Size 301 B 300 B -1 B
Client pages/withRouter Modern Size 423 B 423 B
Client pages/withRouter gzip Modern Size 309 B 309 B
Client main Size 16.3 kB 15.8 kB -439 B
Client main gzip Size 5.73 kB 5.48 kB -250 B
Client main Modern Size 13.1 kB 12.9 kB -238 B
Client main Modern gzip Size 4.99 kB 4.85 kB -144 B
Client commons Size 195 kB 195 kB -255 B
Client commons gzip Size 63.6 kB 63.5 kB -76 B
Client commons Modern Size 176 kB 176 kB -253 B
Client commons Modern gzip Size 57.4 kB 57.3 kB -92 B
Client webpack Size 1.53 kB 1.53 kB
Client webpack gzip Size 778 B 778 B
Client webpack Modern Size 1.53 kB 1.53 kB
Client webpack Modern gzip Size 785 B 785 B
Serverless pages/link Size 256 kB 256 kB -514 B
Serverless pages/link gzip Size 68.8 kB 68.7 kB -145 B
Serverless pages/index Size 249 kB 248 kB -269 B
Serverless pages/index gzip Size 66.6 kB 66.5 kB -90 B
Serverless pages/_error Size 248 kB 248 kB -269 B
Serverless pages/_error gzip Size 66.3 kB 66.2 kB -84 B
Serverless pages/routerDirect Size 249 kB 249 kB -269 B
Serverless pages/routerDirect gzip Size 66.5 kB 66.4 kB -84 B
Serverless pages/withRouter Size 249 kB 249 kB -269 B
Serverless pages/withRouter gzip Size 66.6 kB 66.5 kB -74 B
Build Dir Size 2.64 MB 2.63 MB -11.8 kB
Diff for main.js
@@ -1,5 +1,20 @@
 (window["webpackJsonp"] = window["webpackJsonp"] || []).push([[8],{
 
+/***/ "+iuc":
+/***/ (function(module, exports, __webpack_require__) {
+
+__webpack_require__("wgeU");
+__webpack_require__("FlQf");
+__webpack_require__("bBy9");
+__webpack_require__("B9jh");
+__webpack_require__("dL40");
+__webpack_require__("xvv9");
+__webpack_require__("V+O7");
+module.exports = __webpack_require__("WEpk").Set;
+
+
+/***/ }),
+
 /***/ "+oT+":
 /***/ (function(module, exports, __webpack_require__) {
 
@@ -54,6 +69,28 @@ __webpack_require__("cHUd")('Map');
 
 /***/ }),
 
+/***/ "B9jh":
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+var strong = __webpack_require__("Wu5q");
+var validate = __webpack_require__("n3ko");
+var SET = 'Set';
+
+// 23.2 Set Objects
+module.exports = __webpack_require__("raTm")(SET, function (get) {
+  return function Set() { return get(this, arguments.length > 0 ? arguments[0] : undefined); };
+}, {
+  // 23.2.3.1 Set.prototype.add(value)
+  add: function add(value) {
+    return strong.def(validate(this, SET), value = value === 0 ? 0 : value, value);
+  }
+}, strong);
+
+
+/***/ }),
+
 /***/ "BMP1":
 /***/ (function(module, exports, __webpack_require__) {
 
@@ -658,7 +695,7 @@ function _renderError() {
   _renderError = (0, _asyncToGenerator2["default"])(
   /*#__PURE__*/
   _regenerator["default"].mark(function _callee3(props) {
-    var App, err, appCtx, initProps;
+    var App, err, AppTree, appCtx, initProps;
     return _regenerator["default"].wrap(function _callee3$(_context3) {
       while (1) {
         switch (_context3.prev = _context3.next) {
@@ -684,44 +721,46 @@ function _renderError() {
             // In production we do a normal render with the `ErrorComponent` as component.
             // If we've gotten here upon initial render, we can use the props from the server.
             // Otherwise, we need to call `getInitialProps` on `App` before mounting.
+            AppTree = wrapApp(App);
             appCtx = {
-              AppTree: wrapApp(App),
               Component: ErrorComponent,
+              AppTree: AppTree,
               router: router,
               ctx: {
                 err: err,
                 pathname: page,
                 query: query,
-                asPath: asPath
+                asPath: asPath,
+                AppTree: AppTree
               }
             };
 
             if (!props.props) {
-              _context3.next = 12;
+              _context3.next = 13;
               break;
             }
 
             _context3.t0 = props.props;
-            _context3.next = 15;
+            _context3.next = 16;
             break;
 
-          case 12:
-            _context3.next = 14;
+          case 13:
+            _context3.next = 15;
             return (0, _utils.loadGetInitialProps)(App, appCtx);
 
-          case 14:
+          case 15:
             _context3.t0 = _context3.sent;
 
-          case 15:
+          case 16:
             initProps = _context3.t0;
-            _context3.next = 18;
+            _context3.next = 19;
             return doRender((0, _extends2["default"])({}, props, {
               err: err,
               Component: ErrorComponent,
               props: initProps
             }));
 
-          case 18:
+          case 19:
           case "end":
             return _context3.stop();
         }
@@ -734,50 +773,16 @@ function _renderError() {
 var isInitialRender = typeof _reactDom["default"].hydrate === 'function';
 
 function renderReactElement(reactEl, domEl) {
-  // mark start of hydrate/render
-  if (_utils.SUPPORTS_PERFORMANCE_USER_TIMING) {
-    performance.mark('beforeRender');
-  } // The check for `.hydrate` is there to support React alternatives like preact
-
-
+  // The check for `.hydrate` is there to support React alternatives like preact
   if (isInitialRender) {
-    _reactDom["default"].hydrate(reactEl, domEl, markHydrateComplete);
+    _reactDom["default"].hydrate(reactEl, domEl);
 
     isInitialRender = false;
   } else {
-    _reactDom["default"].render(reactEl, domEl, markRenderComplete);
+    _reactDom["default"].render(reactEl, domEl);
   }
 }
 
-function markHydrateComplete() {
-  if (!_utils.SUPPORTS_PERFORMANCE_USER_TIMING) return;
-  performance.mark('afterHydrate'); // mark end of hydration
-
-  performance.measure('Next.js-before-hydration', null, 'beforeRender');
-  performance.measure('Next.js-hydration', 'beforeRender', 'afterHydrate');
-  clearMarks();
-}
-
-function markRenderComplete() {
-  if (!_utils.SUPPORTS_PERFORMANCE_USER_TIMING) return;
-  performance.mark('afterRender'); // mark end of render
-
-  var navStartEntries = performance.getEntriesByName('routeChange', 'mark');
-
-  if (!navStartEntries.length) {
-    return;
-  }
-
-  performance.measure('Next.js-route-change-to-render', navStartEntries[0].name, 'beforeRender');
-  performance.measure('Next.js-render', 'beforeRender', 'afterRender');
-  clearMarks();
-}
-
-function clearMarks() {
-  performance.clearMarks();
-  performance.clearMeasures();
-}
-
 function AppContainer(_ref4) {
   var children = _ref4.children;
   return _react["default"].createElement(Container, {
@@ -819,7 +824,7 @@ function _doRender() {
   _doRender = (0, _asyncToGenerator2["default"])(
   /*#__PURE__*/
   _regenerator["default"].mark(function _callee4(_ref5) {
-    var App, Component, props, err, _router2, pathname, _query, _asPath, appCtx, appProps;
+    var App, Component, props, err, _router2, pathname, _query, _asPath, AppTree, appCtx, appProps;
 
     return _regenerator["default"].wrap(function _callee4$(_context4) {
       while (1) {
@@ -829,29 +834,31 @@ function _doRender() {
             // this is for when ErrorComponent gets replaced by Component by HMR
 
             if (!(!props && Component && Component !== ErrorComponent && lastAppProps.Component === ErrorComponent)) {
-              _context4.next = 7;
+              _context4.next = 8;
               break;
             }
 
             _router2 = router, pathname = _router2.pathname, _query = _router2.query, _asPath = _router2.asPath;
+            AppTree = wrapApp(App);
             appCtx = {
               router: router,
-              AppTree: wrapApp(App),
+              AppTree: AppTree,
               Component: ErrorComponent,
               ctx: {
                 err: err,
                 pathname: pathname,
                 query: _query,
-                asPath: _asPath
+                asPath: _asPath,
+                AppTree: AppTree
               }
             };
-            _context4.next = 6;
+            _context4.next = 7;
             return (0, _utils.loadGetInitialProps)(App, appCtx);
 
-          case 6:
+          case 7:
             props = _context4.sent;
 
-          case 7:
+          case 8:
             Component = Component || lastAppProps.Component;
             props = props || lastAppProps.props;
             appProps = (0, _extends2["default"])({}, props, {
@@ -874,7 +881,7 @@ function _doRender() {
               appProps: appProps
             });
 
-          case 14:
+          case 15:
           case "end":
             return _context4.stop();
         }
@@ -916,6 +923,15 @@ module.exports = __webpack_require__("WEpk").Map;
 
 /***/ }),
 
+/***/ "V+O7":
+/***/ (function(module, exports, __webpack_require__) {
+
+// https://tc39.github.io/proposal-setmap-offrom/#sec-set.from
+__webpack_require__("aPfg")('Set');
+
+
+/***/ }),
+
 /***/ "XLbu":
 /***/ (function(module, exports, __webpack_require__) {
 
@@ -983,6 +999,17 @@ exports.DataManager = DataManager;
 
 /***/ }),
 
+/***/ "dL40":
+/***/ (function(module, exports, __webpack_require__) {
+
+// https://github.com/DavidBruant/Map-Set.prototype.toJSON
+var $export = __webpack_require__("Y7ZC");
+
+$export($export.P + $export.R, 'Set', { toJSON: __webpack_require__("8iia")('Set') });
+
+
+/***/ }),
+
 /***/ "dVTT":
 /***/ (function(module, exports, __webpack_require__) {
 
@@ -1060,6 +1087,22 @@ exports.DataManagerContext = React.createContext(null);
 
 /***/ }),
 
+/***/ "ttDY":
+/***/ (function(module, exports, __webpack_require__) {
+
+module.exports = __webpack_require__("+iuc");
+
+/***/ }),
+
+/***/ "xvv9":
+/***/ (function(module, exports, __webpack_require__) {
+
+// https://tc39.github.io/proposal-setmap-offrom/#sec-set.of
+__webpack_require__("cHUd")('Set');
+
+
+/***/ }),
+
 /***/ "zmvN":
 /***/ (function(module, exports, __webpack_require__) {
 
@@ -1083,10 +1126,12 @@ var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__("+oT+"));
 
 var _promise = _interopRequireDefault(__webpack_require__("eVuF"));
 
+var _set = _interopRequireDefault(__webpack_require__("ttDY"));
+
 var _mitt = _interopRequireDefault(__webpack_require__("kiME"));
 
 var _unfetch = _interopRequireDefault(__webpack_require__("m/Gl"));
-/* global document, window */
+/* global document */
 
 
 function supportsPreload(el) {
@@ -1116,24 +1161,13 @@ function () {
     this.buildId = buildId;
     this.assetPrefix = assetPrefix;
     this.pageCache = {};
+    this.prefetchCache = new _set["default"]();
     this.pageRegisterEvents = (0, _mitt["default"])();
     this.loadingRoutes = {};
     this.promisedBuildId = _promise["default"].resolve();
-
-    if (false) {}
-  } // Returns a promise for the dependencies for a particular route
-
+  }
 
   (0, _createClass2["default"])(PageLoader, [{
-    key: "getDependencies",
-    value: function getDependencies(route) {
-      return this.promisedBuildManifest.then(function (man) {
-        return man[route] && man[route].map(function (url) {
-          return "/_next/" + url;
-        }) || [];
-      });
-    }
-  }, {
     key: "normalizeRoute",
     value: function normalizeRoute(route) {
       if (route[0] !== '/') {
@@ -1183,14 +1217,13 @@ function () {
 
         if (document.getElementById("__NEXT_PAGE__" + route)) {
           return;
-        }
+        } // Load the script if not asked to load yet.
+
 
         if (!_this3.loadingRoutes[route]) {
-          if (false) {} else {
-            _this3.loadRoute(route);
+          _this3.loadScript(route);
 
-            _this3.loadingRoutes[route] = true;
-          }
+          _this3.loadingRoutes[route] = true;
         }
       });
     }
@@ -1220,14 +1253,14 @@ function () {
       });
     }
   }, {
-    key: "loadRoute",
-    value: function loadRoute(route) {
+    key: "loadScript",
+    value: function loadScript(route) {
       var _this = this;
 
       return (0, _asyncToGenerator2["default"])(
       /*#__PURE__*/
       _regenerator["default"].mark(function _callee() {
-        var scriptRoute, url;
+        var scriptRoute, script, url;
         return _regenerator["default"].wrap(function _callee$(_context) {
           while (1) {
             switch (_context.prev = _context.next) {
@@ -1238,51 +1271,41 @@ function () {
               case 2:
                 route = _this.normalizeRoute(route);
                 scriptRoute = route === '/' ? '/index.js' : route + ".js";
+                script = document.createElement('script');
+
+                if ( true && 'noModule' in script) {
+                  script.type = 'module';
+                  scriptRoute = scriptRoute.replace(/\.js$/, '.module.js');
+                }
+
                 url = _this.assetPrefix + "/_next/static/" + encodeURIComponent(_this.buildId) + "/pages" + scriptRoute;
+                script.crossOrigin = "anonymous";
+                script.src = url;
+
+                script.onerror = function () {
+                  var error = new Error("Error loading script " + url);
+                  error.code = 'PAGE_LOAD_ERROR';
+
+                  _this.pageRegisterEvents.emit(route, {
+                    error: error
+                  });
+                };
 
-                _this.loadScript(url, route, true);
+                document.body.appendChild(script);
 
-              case 6:
+              case 11:
               case "end":
                 return _context.stop();
             }
           }
         }, _callee);
       }))();
-    }
-  }, {
-    key: "loadScript",
-    value: function loadScript(url, route, isPage) {
-      var _this5 = this;
-
-      var script = document.createElement('script');
-
-      if ( true && 'noModule' in script) {
-        script.type = 'module'; // Only page bundle scripts need to have .module added to url,
-        // dependencies already have it added during build manifest creation
-
-        if (isPage) url = url.replace(/\.js$/, '.module.js');
-      }
-
-      script.crossOrigin = "anonymous";
-      script.src = url;
-
-      script.onerror = function () {
-        var error = new Error("Error loading script " + url);
-        error.code = 'PAGE_LOAD_ERROR';
-
-        _this5.pageRegisterEvents.emit(route, {
-          error: error
-        });
-      };
-
-      document.body.appendChild(script);
     } // This method if called by the route code.
 
   }, {
     key: "registerPage",
     value: function registerPage(route, regFn) {
-      var _this6 = this;
+      var _this5 = this;
 
       var register = function register() {
         try {
@@ -1290,21 +1313,21 @@ function () {
               error = _regFn.error,
               page = _regFn.page;
 
-          _this6.pageCache[route] = {
+          _this5.pageCache[route] = {
             error: error,
             page: page
           };
 
-          _this6.pageRegisterEvents.emit(route, {
+          _this5.pageRegisterEvents.emit(route, {
             error: error,
             page: page
           });
         } catch (error) {
-          _this6.pageCache[route] = {
+          _this5.pageCache[route] = {
             error: error
           };
 
-          _this6.pageRegisterEvents.emit(route, {
+          _this5.pageRegisterEvents.emit(route, {
             error: error
           });
         }
@@ -1316,21 +1339,17 @@ function () {
     }
   }, {
     key: "prefetch",
-    value: function prefetch(route, isDependency) {
+    value: function prefetch(route) {
       var _this2 = this;
 
       return (0, _asyncToGenerator2["default"])(
       /*#__PURE__*/
       _regenerator["default"].mark(function _callee2() {
-        var scriptRoute, url, cn;
+        var scriptRoute, cn;
         return _regenerator["default"].wrap(function _callee2$(_context2) {
           while (1) {
             switch (_context2.prev = _context2.next) {
               case 0:
-                _context2.next = 2;
-                return _this2.promisedBuildId;
-
-              case 2:
                 route = _this2.normalizeRoute(route);
                 scriptRoute = (route === '/' ? '/index' : route) + ".js";
 
@@ -1338,72 +1357,51 @@ function () {
                   scriptRoute = scriptRoute.replace(/\.js$/, '.module.js');
                 }
 
-                url = isDependency ? route : _this2.assetPrefix + "/_next/static/" + encodeURIComponent(_this2.buildId) + "/pages" + scriptRoute; // n.b. If preload is not supported, we fall back to `loadPage` which has
-                // its own deduping mechanism.
-
-                if (!(document.querySelector("link[rel=\"preload\"][href^=\"" + url + "\"]") || document.getElementById("__NEXT_PAGE__" + route))) {
-                  _context2.next = 8;
+                if (!(_this2.prefetchCache.has(scriptRoute) || document.getElementById("__NEXT_PAGE__" + route))) {
+                  _context2.next = 5;
                   break;
                 }
 
                 return _context2.abrupt("return");
 
-              case 8:
+              case 5:
+                _this2.prefetchCache.add(scriptRoute); // Inspired by quicklink, license: https://github.com/GoogleChromeLabs/quicklink/blob/master/LICENSE
+
+
                 if (!(cn = navigator.connection)) {
-                  _context2.next = 11;
+                  _context2.next = 9;
                   break;
                 }
 
                 if (!((cn.effectiveType || '').indexOf('2g') !== -1 || cn.saveData)) {
-                  _context2.next = 11;
+                  _context2.next = 9;
                   break;
                 }
 
                 return _context2.abrupt("return");
 
-              case 11:
-                if (true) {
-                  _context2.next = 17;
-                  break;
-                }
-
-                ;
-                _context2.next = 15;
-                return _this2.getDependencies(route);
-
-              case 15:
-                _context2.t0 = function (url) {
-                  _this2.prefetch(url, true);
-                };
-
-                _context2.sent.forEach(_context2.t0);
-
-              case 17:
+              case 9:
                 if (!hasPreload) {
-                  _context2.next = 20;
+                  _context2.next = 14;
                   break;
                 }
 
-                preloadScript(url);
-                return _context2.abrupt("return");
-
-              case 20:
-                if (!isDependency) {
-                  _context2.next = 22;
-                  break;
-                }
+                _context2.next = 12;
+                return _this2.promisedBuildId;
 
+              case 12:
+                preloadScript(_this2.assetPrefix + "/_next/static/" + encodeURIComponent(_this2.buildId) + "/pages" + scriptRoute);
                 return _context2.abrupt("return");
 
-              case 22:
+              case 14:
                 if (!(document.readyState === 'complete')) {
-                  _context2.next = 26;
+                  _context2.next = 18;
                   break;
                 }
 
                 return _context2.abrupt("return", _this2.loadPage(route)["catch"](function () {}));
 
-              case 26:
+              case 18:
                 return _context2.abrupt("return", new _promise["default"](function (resolve) {
                   window.addEventListener('load', function () {
                     _this2.loadPage(route).then(function () {
@@ -1414,7 +1412,7 @@ function () {
                   });
                 }));
 
-              case 27:
+              case 19:
               case "end":
                 return _context2.stop();
             }
Diff for commons.js
@@ -1244,8 +1244,6 @@ function formatWithValidation(url, options) {
 }
 
 exports.formatWithValidation = formatWithValidation;
-exports.SUPPORTS_PERFORMANCE = typeof performance !== 'undefined';
-exports.SUPPORTS_PERFORMANCE_USER_TIMING = exports.SUPPORTS_PERFORMANCE && typeof performance.mark === 'function' && typeof performance.measure === 'function';
 
 /***/ }),
 
@@ -3198,13 +3196,8 @@ function () {
       var _this2 = this;
 
       return new _promise["default"](function (resolve, reject) {
-        // marking route changes as a navigation start entry
-        if (utils_1.SUPPORTS_PERFORMANCE_USER_TIMING) {
-          performance.mark('routeChange');
-        } // If url and as provided as an object representation,
+        // If url and as provided as an object representation,
         // we'll format them into the string version here.
-
-
         var url = typeof _url === 'object' ? utils_1.formatWithValidation(_url) : _url;
         var as = typeof _as === 'object' ? utils_1.formatWithValidation(_as) : _as; // Add the ending slash to the paths. So, we can serve the
         // "<page>/index.html" directly for the SSR page.
@@ -3349,13 +3342,12 @@ function () {
         if (false) { var _require, isValidElementType; }
 
         return new _promise["default"](function (resolve, reject) {
-          var ctx = {
+          // we provide AppTree later so this needs to be `any`
+          _this3.getInitialProps(Component, {
             pathname: pathname,
             query: query,
             asPath: as
-          };
-
-          _this3.getInitialProps(Component, ctx).then(function (props) {
+          }).then(function (props) {
             routeInfo.props = props;
             _this3.components[route] = routeInfo;
             resolve(routeInfo);
@@ -3391,13 +3383,12 @@ function () {
               Component: Component,
               err: err
             };
-            var ctx = {
-              err: err,
-              pathname: pathname,
-              query: query
-            };
             return new _promise["default"](function (resolve) {
-              _this3.getInitialProps(Component, ctx).then(function (props) {
+              _this3.getInitialProps(Component, {
+                err: err,
+                pathname: pathname,
+                query: query
+              }).then(function (props) {
                 routeInfo.props = props;
                 routeInfo.error = err;
                 resolve(routeInfo);
@@ -3585,7 +3576,7 @@ function () {
       var _getInitialProps = (0, _asyncToGenerator2["default"])(
       /*#__PURE__*/
       _regenerator["default"].mark(function _callee2(Component, ctx) {
-        var cancelled, cancel, App, props, url, res, err;
+        var cancelled, cancel, App, props, url, res, AppTree, err;
         return _regenerator["default"].wrap(function _callee2$(_context2) {
           while (1) {
             switch (_context2.prev = _context2.next) {
@@ -3646,28 +3637,30 @@ function () {
                 props = {
                   pageProps: _context2.t1
                 };
-                _context2.next = 23;
+                _context2.next = 25;
                 break;
 
               case 20:
-                _context2.next = 22;
+                AppTree = this._wrapApp(App);
+                ctx.AppTree = AppTree;
+                _context2.next = 24;
                 return utils_1.loadGetInitialProps(App, {
-                  AppTree: this._wrapApp(App),
+                  AppTree: AppTree,
                   Component: Component,
                   router: this,
                   ctx: ctx
                 });
 
-              case 22:
+              case 24:
                 props = _context2.sent;
 
-              case 23:
+              case 25:
                 if (cancel === this.clc) {
                   this.clc = null;
                 }
 
                 if (!cancelled) {
-                  _context2.next = 28;
+                  _context2.next = 30;
                   break;
                 }
 
@@ -3675,10 +3668,10 @@ function () {
                 err.cancelled = true;
                 throw err;
 
-              case 28:
+              case 30:
                 return _context2.abrupt("return", props);
 
-              case 29:
+              case 31:
               case "end":
                 return _context2.stop();
             }
Diff for mainModern.js
@@ -1,5 +1,20 @@
 (window["webpackJsonp"] = window["webpackJsonp"] || []).push([[8],{
 
+/***/ "+iuc":
+/***/ (function(module, exports, __webpack_require__) {
+
+__webpack_require__("wgeU");
+__webpack_require__("FlQf");
+__webpack_require__("bBy9");
+__webpack_require__("B9jh");
+__webpack_require__("dL40");
+__webpack_require__("xvv9");
+__webpack_require__("V+O7");
+module.exports = __webpack_require__("WEpk").Set;
+
+
+/***/ }),
+
 /***/ "+oT+":
 /***/ (function(module, exports, __webpack_require__) {
 
@@ -54,6 +69,28 @@ __webpack_require__("cHUd")('Map');
 
 /***/ }),
 
+/***/ "B9jh":
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+var strong = __webpack_require__("Wu5q");
+var validate = __webpack_require__("n3ko");
+var SET = 'Set';
+
+// 23.2 Set Objects
+module.exports = __webpack_require__("raTm")(SET, function (get) {
+  return function Set() { return get(this, arguments.length > 0 ? arguments[0] : undefined); };
+}, {
+  // 23.2.3.1 Set.prototype.add(value)
+  add: function add(value) {
+    return strong.def(validate(this, SET), value = value === 0 ? 0 : value, value);
+  }
+}, strong);
+
+
+/***/ }),
+
 /***/ "BMP1":
 /***/ (function(module, exports, __webpack_require__) {
 
@@ -538,15 +575,17 @@ function _renderError() {
     // If we've gotten here upon initial render, we can use the props from the server.
     // Otherwise, we need to call `getInitialProps` on `App` before mounting.
 
+    const AppTree = wrapApp(App);
     const appCtx = {
-      AppTree: wrapApp(App),
       Component: ErrorComponent,
+      AppTree,
       router,
       ctx: {
         err,
         pathname: page,
         query,
-        asPath
+        asPath,
+        AppTree
       }
     };
     const initProps = props.props ? props.props : yield (0, _utils.loadGetInitialProps)(App, appCtx);
@@ -562,48 +601,14 @@ function _renderError() {
 let isInitialRender = typeof _reactDom.default.hydrate === 'function';
 
 function renderReactElement(reactEl, domEl) {
-  // mark start of hydrate/render
-  if (_utils.SUPPORTS_PERFORMANCE_USER_TIMING) {
-    performance.mark('beforeRender');
-  } // The check for `.hydrate` is there to support React alternatives like preact
-
-
+  // The check for `.hydrate` is there to support React alternatives like preact
   if (isInitialRender) {
-    _reactDom.default.hydrate(reactEl, domEl, markHydrateComplete);
+    _reactDom.default.hydrate(reactEl, domEl);
 
     isInitialRender = false;
   } else {
-    _reactDom.default.render(reactEl, domEl, markRenderComplete);
-  }
-}
-
-function markHydrateComplete() {
-  if (!_utils.SUPPORTS_PERFORMANCE_USER_TIMING) return;
-  performance.mark('afterHydrate'); // mark end of hydration
-
-  performance.measure('Next.js-before-hydration', null, 'beforeRender');
-  performance.measure('Next.js-hydration', 'beforeRender', 'afterHydrate');
-  clearMarks();
-}
-
-function markRenderComplete() {
-  if (!_utils.SUPPORTS_PERFORMANCE_USER_TIMING) return;
-  performance.mark('afterRender'); // mark end of render
-
-  const navStartEntries = performance.getEntriesByName('routeChange', 'mark');
-
-  if (!navStartEntries.length) {
-    return;
+    _reactDom.default.render(reactEl, domEl);
   }
-
-  performance.measure('Next.js-route-change-to-render', navStartEntries[0].name, 'beforeRender');
-  performance.measure('Next.js-render', 'beforeRender', 'afterRender');
-  clearMarks();
-}
-
-function clearMarks() {
-  performance.clearMarks();
-  performance.clearMeasures();
 }
 
 function AppContainer(_ref4) {
@@ -655,15 +660,17 @@ function _doRender() {
         query,
         asPath
       } = router;
+      const AppTree = wrapApp(App);
       const appCtx = {
         router,
-        AppTree: wrapApp(App),
+        AppTree,
         Component: ErrorComponent,
         ctx: {
           err,
           pathname,
           query,
-          asPath
+          asPath,
+          AppTree
         }
       };
       props = yield (0, _utils.loadGetInitialProps)(App, appCtx);
@@ -726,6 +733,15 @@ module.exports = __webpack_require__("WEpk").Map;
 
 /***/ }),
 
+/***/ "V+O7":
+/***/ (function(module, exports, __webpack_require__) {
+
+// https://tc39.github.io/proposal-setmap-offrom/#sec-set.from
+__webpack_require__("aPfg")('Set');
+
+
+/***/ }),
+
 /***/ "XLbu":
 /***/ (function(module, exports, __webpack_require__) {
 
@@ -780,6 +796,17 @@ exports.DataManager = DataManager;
 
 /***/ }),
 
+/***/ "dL40":
+/***/ (function(module, exports, __webpack_require__) {
+
+// https://github.com/DavidBruant/Map-Set.prototype.toJSON
+var $export = __webpack_require__("Y7ZC");
+
+$export($export.P + $export.R, 'Set', { toJSON: __webpack_require__("8iia")('Set') });
+
+
+/***/ }),
+
 /***/ "dVTT":
 /***/ (function(module, exports, __webpack_require__) {
 
@@ -855,6 +882,22 @@ exports.DataManagerContext = React.createContext(null);
 
 /***/ }),
 
+/***/ "ttDY":
+/***/ (function(module, exports, __webpack_require__) {
+
+module.exports = __webpack_require__("+iuc");
+
+/***/ }),
+
+/***/ "xvv9":
+/***/ (function(module, exports, __webpack_require__) {
+
+// https://tc39.github.io/proposal-setmap-offrom/#sec-set.of
+__webpack_require__("cHUd")('Set');
+
+
+/***/ }),
+
 /***/ "zmvN":
 /***/ (function(module, exports, __webpack_require__) {
 
@@ -870,10 +913,12 @@ var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__("+oT+"));
 
 var _promise = _interopRequireDefault(__webpack_require__("eVuF"));
 
+var _set = _interopRequireDefault(__webpack_require__("ttDY"));
+
 var _mitt = _interopRequireDefault(__webpack_require__("kiME"));
 
 var _unfetch = _interopRequireDefault(__webpack_require__("m/Gl"));
-/* global document, window */
+/* global document */
 
 
 function supportsPreload(el) {
@@ -900,16 +945,10 @@ class PageLoader {
     this.buildId = buildId;
     this.assetPrefix = assetPrefix;
     this.pageCache = {};
+    this.prefetchCache = new _set.default();
     this.pageRegisterEvents = (0, _mitt.default)();
     this.loadingRoutes = {};
     this.promisedBuildId = _promise.default.resolve();
-
-    if (false) {}
-  } // Returns a promise for the dependencies for a particular route
-
-
-  getDependencies(route) {
-    return this.promisedBuildManifest.then(man => man[route] && man[route].map(url => "/_next/" + url) || []);
   }
 
   normalizeRoute(route) {
@@ -958,13 +997,12 @@ class PageLoader {
 
       if (document.getElementById("__NEXT_PAGE__" + route)) {
         return;
-      }
+      } // Load the script if not asked to load yet.
+
 
       if (!this.loadingRoutes[route]) {
-        if (false) {} else {
-          this.loadRoute(route);
-          this.loadingRoutes[route] = true;
-        }
+        this.loadScript(route);
+        this.loadingRoutes[route] = true;
       }
     });
   }
@@ -989,41 +1027,35 @@ class PageLoader {
     });
   }
 
-  loadRoute(route) {
+  loadScript(route) {
     var _this = this;
 
     return (0, _asyncToGenerator2.default)(function* () {
       yield _this.promisedBuildId;
       route = _this.normalizeRoute(route);
       let scriptRoute = route === '/' ? '/index.js' : route + ".js";
-      const url = _this.assetPrefix + "/_next/static/" + encodeURIComponent(_this.buildId) + "/pages" + scriptRoute;
-
-      _this.loadScript(url, route, true);
-    })();
-  }
-
-  loadScript(url, route, isPage) {
-    const script = document.createElement('script');
+      const script = document.createElement('script');
 
-    if ( true && 'noModule' in script) {
-      script.type = 'module'; // Only page bundle scripts need to have .module added to url,
-      // dependencies already have it added during build manifest creation
+      if ( true && 'noModule' in script) {
+        script.type = 'module';
+        scriptRoute = scriptRoute.replace(/\.js$/, '.module.js');
+      }
 
-      if (isPage) url = url.replace(/\.js$/, '.module.js');
-    }
+      const url = _this.assetPrefix + "/_next/static/" + encodeURIComponent(_this.buildId) + "/pages" + scriptRoute;
+      script.crossOrigin = "anonymous";
+      script.src = url;
 
-    script.crossOrigin = "anonymous";
-    script.src = url;
+      script.onerror = () => {
+        const error = new Error("Error loading script " + url);
+        error.code = 'PAGE_LOAD_ERROR';
 
-    script.onerror = () => {
-      const error = new Error("Error loading script " + url);
-      error.code = 'PAGE_LOAD_ERROR';
-      this.pageRegisterEvents.emit(route, {
-        error
-      });
-    };
+        _this.pageRegisterEvents.emit(route, {
+          error
+        });
+      };
 
-    document.body.appendChild(script);
+      document.body.appendChild(script);
+    })();
   } // This method if called by the route code.
 
 
@@ -1057,11 +1089,10 @@ class PageLoader {
     register();
   }
 
-  prefetch(route, isDependency) {
+  prefetch(route) {
     var _this2 = this;
 
     return (0, _asyncToGenerator2.default)(function* () {
-      yield _this2.promisedBuildId;
       route = _this2.normalizeRoute(route);
       let scriptRoute = (route === '/' ? '/index' : route) + ".js";
 
@@ -1069,12 +1100,11 @@ class PageLoader {
         scriptRoute = scriptRoute.replace(/\.js$/, '.module.js');
       }
 
-      const url = isDependency ? route : _this2.assetPrefix + "/_next/static/" + encodeURIComponent(_this2.buildId) + "/pages" + scriptRoute; // n.b. If preload is not supported, we fall back to `loadPage` which has
-      // its own deduping mechanism.
-
-      if (document.querySelector("link[rel=\"preload\"][href^=\"" + url + "\"]") || document.getElementById("__NEXT_PAGE__" + route)) {
+      if (_this2.prefetchCache.has(scriptRoute) || document.getElementById("__NEXT_PAGE__" + route)) {
         return;
-      } // Inspired by quicklink, license: https://github.com/GoogleChromeLabs/quicklink/blob/master/LICENSE
+      }
+
+      _this2.prefetchCache.add(scriptRoute); // Inspired by quicklink, license: https://github.com/GoogleChromeLabs/quicklink/blob/master/LICENSE
 
 
       let cn;
@@ -1084,21 +1114,14 @@ class PageLoader {
         if ((cn.effectiveType || '').indexOf('2g') !== -1 || cn.saveData) {
           return;
         }
-      }
-
-      if (false) {} // Feature detection is used to see if preload is supported
+      } // Feature detection is used to see if preload is supported
       // If not fall back to loading script tags before the page is loaded
       // https://caniuse.com/#feat=link-rel-preload
 
 
       if (hasPreload) {
-        preloadScript(url);
-        return;
-      }
-
-      if (isDependency) {
-        // loadPage will automatically handle depencies, so no need to
-        // preload them manually
+        yield _this2.promisedBuildId;
+        preloadScript(_this2.assetPrefix + "/_next/static/" + encodeURIComponent(_this2.buildId) + "/pages" + scriptRoute);
         return;
       }
 
Diff for commonsModern.js
@@ -763,8 +763,6 @@ function formatWithValidation(url, options) {
 }
 
 exports.formatWithValidation = formatWithValidation;
-exports.SUPPORTS_PERFORMANCE = typeof performance !== 'undefined';
-exports.SUPPORTS_PERFORMANCE_USER_TIMING = exports.SUPPORTS_PERFORMANCE && typeof performance.mark === 'function' && typeof performance.measure === 'function';
 
 /***/ }),
 
@@ -2679,13 +2677,8 @@ class Router {
 
   change(method, _url, _as, options) {
     return new _promise.default((resolve, reject) => {
-      // marking route changes as a navigation start entry
-      if (utils_1.SUPPORTS_PERFORMANCE_USER_TIMING) {
-        performance.mark('routeChange');
-      } // If url and as provided as an object representation,
+      // If url and as provided as an object representation,
       // we'll format them into the string version here.
-
-
       const url = typeof _url === 'object' ? utils_1.formatWithValidation(_url) : _url;
       let as = typeof _as === 'object' ? utils_1.formatWithValidation(_as) : _as; // Add the ending slash to the paths. So, we can serve the
       // "<page>/index.html" directly for the SSR page.
@@ -2824,12 +2817,12 @@ class Router {
       if (false) {}
 
       return new _promise.default((resolve, reject) => {
-        const ctx = {
+        // we provide AppTree later so this needs to be `any`
+        this.getInitialProps(Component, {
           pathname,
           query,
           asPath: as
-        };
-        this.getInitialProps(Component, ctx).then(props => {
+        }).then(props => {
           routeInfo.props = props;
           this.components[route] = routeInfo;
           resolve(routeInfo);
@@ -2865,13 +2858,12 @@ class Router {
             Component,
             err
           };
-          const ctx = {
-            err,
-            pathname,
-            query
-          };
           return new _promise.default(resolve => {
-            this.getInitialProps(Component, ctx).then(props => {
+            this.getInitialProps(Component, {
+              err,
+              pathname,
+              query
+            }).then(props => {
               routeInfo.props = props;
               routeInfo.error = err;
               resolve(routeInfo);
@@ -3035,8 +3027,11 @@ class Router {
         }
       };
     } else {
+      const AppTree = this._wrapApp(App);
+
+      ctx.AppTree = AppTree;
       props = await utils_1.loadGetInitialProps(App, {
-        AppTree: this._wrapApp(App),
+        AppTree,
         Component,
         router: this,
         ctx

@ijjk
Copy link
Member Author

ijjk commented Aug 11, 2019

Stats from current PR

Click to expand stats ✅ Total Bundle Size Decrease ✅
zeit/next.js canary ijjk/next.js add-apptree-ctx Change
Build Duration 22.6s 22.6s -80ms
node_modules Size 41.6 MB 41.6 MB -13.8 kB
Total Bundle (main, webpack, commons) Size 214 kB 214 kB -659 B
Total Bundle (main, webpack, commons) gzip Size 70.6 kB 70.3 kB -318 B
Total Bundle (main, webpack, commons) Modern Size 189 kB 189 kB -491 B
Total Bundle (main, webpack, commons) Modern gzip Size 62.4 kB 62.1 kB -236 B
Client _app Size 2.35 kB 2.39 kB ⚠️ +35 B
Client _app gzip Size 1.07 kB 1.08 kB ⚠️ +8 B
Client _app Modern Size 1.79 kB 1.83 kB ⚠️ +35 B
Client _app gzip Modern Size 880 B 890 B ⚠️ +10 B
Client _error Size 8.22 kB 8.22 kB
Client _error gzip Size 3.16 kB 3.16 kB
Client _error Modern Size 5.85 kB 5.85 kB
Client _error gzip Modern Size 2.33 kB 2.33 kB
Client pages/index Size 343 B 343 B
Client pages/index gzip Size 246 B 246 B
Client pages/index Modern Size 319 B 319 B
Client pages/index gzip Modern Size 254 B 254 B
Client pages/link Size 4.18 kB 4.08 kB -104 B
Client pages/link gzip Size 1.82 kB 1.8 kB -26 B
Client pages/link Modern Size 3.81 kB 3.7 kB -113 B
Client pages/link gzip Modern Size 1.72 kB 1.7 kB -28 B
Client pages/routerDirect Size 423 B 423 B
Client pages/routerDirect gzip Size 306 B 306 B
Client pages/routerDirect Modern Size 411 B 411 B
Client pages/routerDirect gzip Modern Size 314 B 314 B
Client pages/withRouter Size 435 B 435 B
Client pages/withRouter gzip Size 301 B 301 B
Client pages/withRouter Modern Size 423 B 423 B
Client pages/withRouter gzip Modern Size 309 B 309 B
Client main Size 16.3 kB 15.8 kB -439 B
Client main gzip Size 5.73 kB 5.48 kB -250 B
Client main Modern Size 13.1 kB 12.9 kB -238 B
Client main Modern gzip Size 4.99 kB 4.85 kB -144 B
Client commons Size 195 kB 195 kB -255 B
Client commons gzip Size 63.6 kB 63.5 kB -76 B
Client commons Modern Size 176 kB 176 kB -253 B
Client commons Modern gzip Size 57.4 kB 57.3 kB -92 B
Client webpack Size 1.53 kB 1.53 kB
Client webpack gzip Size 778 B 778 B
Client webpack Modern Size 1.53 kB 1.53 kB
Client webpack Modern gzip Size 785 B 785 B
Base Rendered Size 2.76 kB 2.76 kB
Build Dir Size 1.44 MB 1.43 MB -10.1 kB
Click to expand serverless stats ✅ Total Bundle Size Decrease ✅
zeit/next.js canary ijjk/next.js add-apptree-ctx Change
Build Duration 23.8s 24s ⚠️ +165ms
node_modules Size 41.6 MB 41.6 MB -13.8 kB
Total Bundle (main, webpack, commons) Size 214 kB 214 kB -659 B
Total Bundle (main, webpack, commons) gzip Size 70.6 kB 70.3 kB -318 B
Total Bundle (main, webpack, commons) Modern Size 189 kB 189 kB -491 B
Total Bundle (main, webpack, commons) Modern gzip Size 62.4 kB 62.1 kB -236 B
Client _app Size 2.35 kB 2.39 kB ⚠️ +35 B
Client _app gzip Size 1.07 kB 1.08 kB ⚠️ +8 B
Client _app Modern Size 1.79 kB 1.83 kB ⚠️ +35 B
Client _app gzip Modern Size 880 B 890 B ⚠️ +10 B
Client _error Size 8.22 kB 8.22 kB
Client _error gzip Size 3.16 kB 3.16 kB
Client _error Modern Size 5.85 kB 5.85 kB
Client _error gzip Modern Size 2.33 kB 2.33 kB
Client pages/index Size 343 B 343 B
Client pages/index gzip Size 246 B 246 B
Client pages/index Modern Size 319 B 319 B
Client pages/index gzip Modern Size 254 B 254 B
Client pages/link Size 4.18 kB 4.08 kB -104 B
Client pages/link gzip Size 1.82 kB 1.8 kB -26 B
Client pages/link Modern Size 3.81 kB 3.7 kB -113 B
Client pages/link gzip Modern Size 1.72 kB 1.7 kB -28 B
Client pages/routerDirect Size 423 B 423 B
Client pages/routerDirect gzip Size 306 B 306 B
Client pages/routerDirect Modern Size 411 B 411 B
Client pages/routerDirect gzip Modern Size 314 B 314 B
Client pages/withRouter Size 435 B 435 B
Client pages/withRouter gzip Size 301 B 301 B
Client pages/withRouter Modern Size 423 B 423 B
Client pages/withRouter gzip Modern Size 309 B 309 B
Client main Size 16.3 kB 15.8 kB -439 B
Client main gzip Size 5.73 kB 5.48 kB -250 B
Client main Modern Size 13.1 kB 12.9 kB -238 B
Client main Modern gzip Size 4.99 kB 4.85 kB -144 B
Client commons Size 195 kB 195 kB -255 B
Client commons gzip Size 63.6 kB 63.5 kB -76 B
Client commons Modern Size 176 kB 176 kB -253 B
Client commons Modern gzip Size 57.4 kB 57.3 kB -92 B
Client webpack Size 1.53 kB 1.53 kB
Client webpack gzip Size 778 B 778 B
Client webpack Modern Size 1.53 kB 1.53 kB
Client webpack Modern gzip Size 785 B 785 B
Serverless pages/link Size 256 kB 255 kB -544 B
Serverless pages/link gzip Size 68.8 kB 68.7 kB -157 B
Serverless pages/index Size 249 kB 248 kB -299 B
Serverless pages/index gzip Size 66.6 kB 66.5 kB -103 B
Serverless pages/_error Size 248 kB 248 kB -299 B
Serverless pages/_error gzip Size 66.3 kB 66.2 kB -97 B
Serverless pages/routerDirect Size 249 kB 249 kB -299 B
Serverless pages/routerDirect gzip Size 66.5 kB 66.4 kB -98 B
Serverless pages/withRouter Size 249 kB 249 kB -299 B
Serverless pages/withRouter gzip Size 66.6 kB 66.5 kB -88 B
Build Dir Size 2.64 MB 2.63 MB -12 kB
Diff for main.js
@@ -1,5 +1,20 @@
 (window["webpackJsonp"] = window["webpackJsonp"] || []).push([[8],{
 
+/***/ "+iuc":
+/***/ (function(module, exports, __webpack_require__) {
+
+__webpack_require__("wgeU");
+__webpack_require__("FlQf");
+__webpack_require__("bBy9");
+__webpack_require__("B9jh");
+__webpack_require__("dL40");
+__webpack_require__("xvv9");
+__webpack_require__("V+O7");
+module.exports = __webpack_require__("WEpk").Set;
+
+
+/***/ }),
+
 /***/ "+oT+":
 /***/ (function(module, exports, __webpack_require__) {
 
@@ -54,6 +69,28 @@ __webpack_require__("cHUd")('Map');
 
 /***/ }),
 
+/***/ "B9jh":
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+var strong = __webpack_require__("Wu5q");
+var validate = __webpack_require__("n3ko");
+var SET = 'Set';
+
+// 23.2 Set Objects
+module.exports = __webpack_require__("raTm")(SET, function (get) {
+  return function Set() { return get(this, arguments.length > 0 ? arguments[0] : undefined); };
+}, {
+  // 23.2.3.1 Set.prototype.add(value)
+  add: function add(value) {
+    return strong.def(validate(this, SET), value = value === 0 ? 0 : value, value);
+  }
+}, strong);
+
+
+/***/ }),
+
 /***/ "BMP1":
 /***/ (function(module, exports, __webpack_require__) {
 
@@ -658,7 +695,7 @@ function _renderError() {
   _renderError = (0, _asyncToGenerator2["default"])(
   /*#__PURE__*/
   _regenerator["default"].mark(function _callee3(props) {
-    var App, err, appCtx, initProps;
+    var App, err, AppTree, appCtx, initProps;
     return _regenerator["default"].wrap(function _callee3$(_context3) {
       while (1) {
         switch (_context3.prev = _context3.next) {
@@ -684,44 +721,46 @@ function _renderError() {
             // In production we do a normal render with the `ErrorComponent` as component.
             // If we've gotten here upon initial render, we can use the props from the server.
             // Otherwise, we need to call `getInitialProps` on `App` before mounting.
+            AppTree = wrapApp(App);
             appCtx = {
-              AppTree: wrapApp(App),
               Component: ErrorComponent,
+              AppTree: AppTree,
               router: router,
               ctx: {
                 err: err,
                 pathname: page,
                 query: query,
-                asPath: asPath
+                asPath: asPath,
+                AppTree: AppTree
               }
             };
 
             if (!props.props) {
-              _context3.next = 12;
+              _context3.next = 13;
               break;
             }
 
             _context3.t0 = props.props;
-            _context3.next = 15;
+            _context3.next = 16;
             break;
 
-          case 12:
-            _context3.next = 14;
+          case 13:
+            _context3.next = 15;
             return (0, _utils.loadGetInitialProps)(App, appCtx);
 
-          case 14:
+          case 15:
             _context3.t0 = _context3.sent;
 
-          case 15:
+          case 16:
             initProps = _context3.t0;
-            _context3.next = 18;
+            _context3.next = 19;
             return doRender((0, _extends2["default"])({}, props, {
               err: err,
               Component: ErrorComponent,
               props: initProps
             }));
 
-          case 18:
+          case 19:
           case "end":
             return _context3.stop();
         }
@@ -734,50 +773,16 @@ function _renderError() {
 var isInitialRender = typeof _reactDom["default"].hydrate === 'function';
 
 function renderReactElement(reactEl, domEl) {
-  // mark start of hydrate/render
-  if (_utils.SUPPORTS_PERFORMANCE_USER_TIMING) {
-    performance.mark('beforeRender');
-  } // The check for `.hydrate` is there to support React alternatives like preact
-
-
+  // The check for `.hydrate` is there to support React alternatives like preact
   if (isInitialRender) {
-    _reactDom["default"].hydrate(reactEl, domEl, markHydrateComplete);
+    _reactDom["default"].hydrate(reactEl, domEl);
 
     isInitialRender = false;
   } else {
-    _reactDom["default"].render(reactEl, domEl, markRenderComplete);
+    _reactDom["default"].render(reactEl, domEl);
   }
 }
 
-function markHydrateComplete() {
-  if (!_utils.SUPPORTS_PERFORMANCE_USER_TIMING) return;
-  performance.mark('afterHydrate'); // mark end of hydration
-
-  performance.measure('Next.js-before-hydration', null, 'beforeRender');
-  performance.measure('Next.js-hydration', 'beforeRender', 'afterHydrate');
-  clearMarks();
-}
-
-function markRenderComplete() {
-  if (!_utils.SUPPORTS_PERFORMANCE_USER_TIMING) return;
-  performance.mark('afterRender'); // mark end of render
-
-  var navStartEntries = performance.getEntriesByName('routeChange', 'mark');
-
-  if (!navStartEntries.length) {
-    return;
-  }
-
-  performance.measure('Next.js-route-change-to-render', navStartEntries[0].name, 'beforeRender');
-  performance.measure('Next.js-render', 'beforeRender', 'afterRender');
-  clearMarks();
-}
-
-function clearMarks() {
-  performance.clearMarks();
-  performance.clearMeasures();
-}
-
 function AppContainer(_ref4) {
   var children = _ref4.children;
   return _react["default"].createElement(Container, {
@@ -819,7 +824,7 @@ function _doRender() {
   _doRender = (0, _asyncToGenerator2["default"])(
   /*#__PURE__*/
   _regenerator["default"].mark(function _callee4(_ref5) {
-    var App, Component, props, err, _router2, pathname, _query, _asPath, appCtx, appProps;
+    var App, Component, props, err, _router2, pathname, _query, _asPath, AppTree, appCtx, appProps;
 
     return _regenerator["default"].wrap(function _callee4$(_context4) {
       while (1) {
@@ -829,29 +834,31 @@ function _doRender() {
             // this is for when ErrorComponent gets replaced by Component by HMR
 
             if (!(!props && Component && Component !== ErrorComponent && lastAppProps.Component === ErrorComponent)) {
-              _context4.next = 7;
+              _context4.next = 8;
               break;
             }
 
             _router2 = router, pathname = _router2.pathname, _query = _router2.query, _asPath = _router2.asPath;
+            AppTree = wrapApp(App);
             appCtx = {
               router: router,
-              AppTree: wrapApp(App),
+              AppTree: AppTree,
               Component: ErrorComponent,
               ctx: {
                 err: err,
                 pathname: pathname,
                 query: _query,
-                asPath: _asPath
+                asPath: _asPath,
+                AppTree: AppTree
               }
             };
-            _context4.next = 6;
+            _context4.next = 7;
             return (0, _utils.loadGetInitialProps)(App, appCtx);
 
-          case 6:
+          case 7:
             props = _context4.sent;
 
-          case 7:
+          case 8:
             Component = Component || lastAppProps.Component;
             props = props || lastAppProps.props;
             appProps = (0, _extends2["default"])({}, props, {
@@ -874,7 +881,7 @@ function _doRender() {
               appProps: appProps
             });
 
-          case 14:
+          case 15:
           case "end":
             return _context4.stop();
         }
@@ -916,6 +923,15 @@ module.exports = __webpack_require__("WEpk").Map;
 
 /***/ }),
 
+/***/ "V+O7":
+/***/ (function(module, exports, __webpack_require__) {
+
+// https://tc39.github.io/proposal-setmap-offrom/#sec-set.from
+__webpack_require__("aPfg")('Set');
+
+
+/***/ }),
+
 /***/ "XLbu":
 /***/ (function(module, exports, __webpack_require__) {
 
@@ -983,6 +999,17 @@ exports.DataManager = DataManager;
 
 /***/ }),
 
+/***/ "dL40":
+/***/ (function(module, exports, __webpack_require__) {
+
+// https://github.com/DavidBruant/Map-Set.prototype.toJSON
+var $export = __webpack_require__("Y7ZC");
+
+$export($export.P + $export.R, 'Set', { toJSON: __webpack_require__("8iia")('Set') });
+
+
+/***/ }),
+
 /***/ "dVTT":
 /***/ (function(module, exports, __webpack_require__) {
 
@@ -1060,6 +1087,22 @@ exports.DataManagerContext = React.createContext(null);
 
 /***/ }),
 
+/***/ "ttDY":
+/***/ (function(module, exports, __webpack_require__) {
+
+module.exports = __webpack_require__("+iuc");
+
+/***/ }),
+
+/***/ "xvv9":
+/***/ (function(module, exports, __webpack_require__) {
+
+// https://tc39.github.io/proposal-setmap-offrom/#sec-set.of
+__webpack_require__("cHUd")('Set');
+
+
+/***/ }),
+
 /***/ "zmvN":
 /***/ (function(module, exports, __webpack_require__) {
 
@@ -1083,10 +1126,12 @@ var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__("+oT+"));
 
 var _promise = _interopRequireDefault(__webpack_require__("eVuF"));
 
+var _set = _interopRequireDefault(__webpack_require__("ttDY"));
+
 var _mitt = _interopRequireDefault(__webpack_require__("kiME"));
 
 var _unfetch = _interopRequireDefault(__webpack_require__("m/Gl"));
-/* global document, window */
+/* global document */
 
 
 function supportsPreload(el) {
@@ -1116,24 +1161,13 @@ function () {
     this.buildId = buildId;
     this.assetPrefix = assetPrefix;
     this.pageCache = {};
+    this.prefetchCache = new _set["default"]();
     this.pageRegisterEvents = (0, _mitt["default"])();
     this.loadingRoutes = {};
     this.promisedBuildId = _promise["default"].resolve();
-
-    if (false) {}
-  } // Returns a promise for the dependencies for a particular route
-
+  }
 
   (0, _createClass2["default"])(PageLoader, [{
-    key: "getDependencies",
-    value: function getDependencies(route) {
-      return this.promisedBuildManifest.then(function (man) {
-        return man[route] && man[route].map(function (url) {
-          return "/_next/" + url;
-        }) || [];
-      });
-    }
-  }, {
     key: "normalizeRoute",
     value: function normalizeRoute(route) {
       if (route[0] !== '/') {
@@ -1183,14 +1217,13 @@ function () {
 
         if (document.getElementById("__NEXT_PAGE__" + route)) {
           return;
-        }
+        } // Load the script if not asked to load yet.
+
 
         if (!_this3.loadingRoutes[route]) {
-          if (false) {} else {
-            _this3.loadRoute(route);
+          _this3.loadScript(route);
 
-            _this3.loadingRoutes[route] = true;
-          }
+          _this3.loadingRoutes[route] = true;
         }
       });
     }
@@ -1220,14 +1253,14 @@ function () {
       });
     }
   }, {
-    key: "loadRoute",
-    value: function loadRoute(route) {
+    key: "loadScript",
+    value: function loadScript(route) {
       var _this = this;
 
       return (0, _asyncToGenerator2["default"])(
       /*#__PURE__*/
       _regenerator["default"].mark(function _callee() {
-        var scriptRoute, url;
+        var scriptRoute, script, url;
         return _regenerator["default"].wrap(function _callee$(_context) {
           while (1) {
             switch (_context.prev = _context.next) {
@@ -1238,51 +1271,41 @@ function () {
               case 2:
                 route = _this.normalizeRoute(route);
                 scriptRoute = route === '/' ? '/index.js' : route + ".js";
+                script = document.createElement('script');
+
+                if ( true && 'noModule' in script) {
+                  script.type = 'module';
+                  scriptRoute = scriptRoute.replace(/\.js$/, '.module.js');
+                }
+
                 url = _this.assetPrefix + "/_next/static/" + encodeURIComponent(_this.buildId) + "/pages" + scriptRoute;
+                script.crossOrigin = "anonymous";
+                script.src = url;
+
+                script.onerror = function () {
+                  var error = new Error("Error loading script " + url);
+                  error.code = 'PAGE_LOAD_ERROR';
+
+                  _this.pageRegisterEvents.emit(route, {
+                    error: error
+                  });
+                };
 
-                _this.loadScript(url, route, true);
+                document.body.appendChild(script);
 
-              case 6:
+              case 11:
               case "end":
                 return _context.stop();
             }
           }
         }, _callee);
       }))();
-    }
-  }, {
-    key: "loadScript",
-    value: function loadScript(url, route, isPage) {
-      var _this5 = this;
-
-      var script = document.createElement('script');
-
-      if ( true && 'noModule' in script) {
-        script.type = 'module'; // Only page bundle scripts need to have .module added to url,
-        // dependencies already have it added during build manifest creation
-
-        if (isPage) url = url.replace(/\.js$/, '.module.js');
-      }
-
-      script.crossOrigin = "anonymous";
-      script.src = url;
-
-      script.onerror = function () {
-        var error = new Error("Error loading script " + url);
-        error.code = 'PAGE_LOAD_ERROR';
-
-        _this5.pageRegisterEvents.emit(route, {
-          error: error
-        });
-      };
-
-      document.body.appendChild(script);
     } // This method if called by the route code.
 
   }, {
     key: "registerPage",
     value: function registerPage(route, regFn) {
-      var _this6 = this;
+      var _this5 = this;
 
       var register = function register() {
         try {
@@ -1290,21 +1313,21 @@ function () {
               error = _regFn.error,
               page = _regFn.page;
 
-          _this6.pageCache[route] = {
+          _this5.pageCache[route] = {
             error: error,
             page: page
           };
 
-          _this6.pageRegisterEvents.emit(route, {
+          _this5.pageRegisterEvents.emit(route, {
             error: error,
             page: page
           });
         } catch (error) {
-          _this6.pageCache[route] = {
+          _this5.pageCache[route] = {
             error: error
           };
 
-          _this6.pageRegisterEvents.emit(route, {
+          _this5.pageRegisterEvents.emit(route, {
             error: error
           });
         }
@@ -1316,21 +1339,17 @@ function () {
     }
   }, {
     key: "prefetch",
-    value: function prefetch(route, isDependency) {
+    value: function prefetch(route) {
       var _this2 = this;
 
       return (0, _asyncToGenerator2["default"])(
       /*#__PURE__*/
       _regenerator["default"].mark(function _callee2() {
-        var scriptRoute, url, cn;
+        var scriptRoute, cn;
         return _regenerator["default"].wrap(function _callee2$(_context2) {
           while (1) {
             switch (_context2.prev = _context2.next) {
               case 0:
-                _context2.next = 2;
-                return _this2.promisedBuildId;
-
-              case 2:
                 route = _this2.normalizeRoute(route);
                 scriptRoute = (route === '/' ? '/index' : route) + ".js";
 
@@ -1338,72 +1357,51 @@ function () {
                   scriptRoute = scriptRoute.replace(/\.js$/, '.module.js');
                 }
 
-                url = isDependency ? route : _this2.assetPrefix + "/_next/static/" + encodeURIComponent(_this2.buildId) + "/pages" + scriptRoute; // n.b. If preload is not supported, we fall back to `loadPage` which has
-                // its own deduping mechanism.
-
-                if (!(document.querySelector("link[rel=\"preload\"][href^=\"" + url + "\"]") || document.getElementById("__NEXT_PAGE__" + route))) {
-                  _context2.next = 8;
+                if (!(_this2.prefetchCache.has(scriptRoute) || document.getElementById("__NEXT_PAGE__" + route))) {
+                  _context2.next = 5;
                   break;
                 }
 
                 return _context2.abrupt("return");
 
-              case 8:
+              case 5:
+                _this2.prefetchCache.add(scriptRoute); // Inspired by quicklink, license: https://github.com/GoogleChromeLabs/quicklink/blob/master/LICENSE
+
+
                 if (!(cn = navigator.connection)) {
-                  _context2.next = 11;
+                  _context2.next = 9;
                   break;
                 }
 
                 if (!((cn.effectiveType || '').indexOf('2g') !== -1 || cn.saveData)) {
-                  _context2.next = 11;
+                  _context2.next = 9;
                   break;
                 }
 
                 return _context2.abrupt("return");
 
-              case 11:
-                if (true) {
-                  _context2.next = 17;
-                  break;
-                }
-
-                ;
-                _context2.next = 15;
-                return _this2.getDependencies(route);
-
-              case 15:
-                _context2.t0 = function (url) {
-                  _this2.prefetch(url, true);
-                };
-
-                _context2.sent.forEach(_context2.t0);
-
-              case 17:
+              case 9:
                 if (!hasPreload) {
-                  _context2.next = 20;
+                  _context2.next = 14;
                   break;
                 }
 
-                preloadScript(url);
-                return _context2.abrupt("return");
-
-              case 20:
-                if (!isDependency) {
-                  _context2.next = 22;
-                  break;
-                }
+                _context2.next = 12;
+                return _this2.promisedBuildId;
 
+              case 12:
+                preloadScript(_this2.assetPrefix + "/_next/static/" + encodeURIComponent(_this2.buildId) + "/pages" + scriptRoute);
                 return _context2.abrupt("return");
 
-              case 22:
+              case 14:
                 if (!(document.readyState === 'complete')) {
-                  _context2.next = 26;
+                  _context2.next = 18;
                   break;
                 }
 
                 return _context2.abrupt("return", _this2.loadPage(route)["catch"](function () {}));
 
-              case 26:
+              case 18:
                 return _context2.abrupt("return", new _promise["default"](function (resolve) {
                   window.addEventListener('load', function () {
                     _this2.loadPage(route).then(function () {
@@ -1414,7 +1412,7 @@ function () {
                   });
                 }));
 
-              case 27:
+              case 19:
               case "end":
                 return _context2.stop();
             }
Diff for commons.js
@@ -1244,8 +1244,6 @@ function formatWithValidation(url, options) {
 }
 
 exports.formatWithValidation = formatWithValidation;
-exports.SUPPORTS_PERFORMANCE = typeof performance !== 'undefined';
-exports.SUPPORTS_PERFORMANCE_USER_TIMING = exports.SUPPORTS_PERFORMANCE && typeof performance.mark === 'function' && typeof performance.measure === 'function';
 
 /***/ }),
 
@@ -3198,13 +3196,8 @@ function () {
       var _this2 = this;
 
       return new _promise["default"](function (resolve, reject) {
-        // marking route changes as a navigation start entry
-        if (utils_1.SUPPORTS_PERFORMANCE_USER_TIMING) {
-          performance.mark('routeChange');
-        } // If url and as provided as an object representation,
+        // If url and as provided as an object representation,
         // we'll format them into the string version here.
-
-
         var url = typeof _url === 'object' ? utils_1.formatWithValidation(_url) : _url;
         var as = typeof _as === 'object' ? utils_1.formatWithValidation(_as) : _as; // Add the ending slash to the paths. So, we can serve the
         // "<page>/index.html" directly for the SSR page.
@@ -3349,13 +3342,12 @@ function () {
         if (false) { var _require, isValidElementType; }
 
         return new _promise["default"](function (resolve, reject) {
-          var ctx = {
+          // we provide AppTree later so this needs to be `any`
+          _this3.getInitialProps(Component, {
             pathname: pathname,
             query: query,
             asPath: as
-          };
-
-          _this3.getInitialProps(Component, ctx).then(function (props) {
+          }).then(function (props) {
             routeInfo.props = props;
             _this3.components[route] = routeInfo;
             resolve(routeInfo);
@@ -3391,13 +3383,12 @@ function () {
               Component: Component,
               err: err
             };
-            var ctx = {
-              err: err,
-              pathname: pathname,
-              query: query
-            };
             return new _promise["default"](function (resolve) {
-              _this3.getInitialProps(Component, ctx).then(function (props) {
+              _this3.getInitialProps(Component, {
+                err: err,
+                pathname: pathname,
+                query: query
+              }).then(function (props) {
                 routeInfo.props = props;
                 routeInfo.error = err;
                 resolve(routeInfo);
@@ -3585,7 +3576,7 @@ function () {
       var _getInitialProps = (0, _asyncToGenerator2["default"])(
       /*#__PURE__*/
       _regenerator["default"].mark(function _callee2(Component, ctx) {
-        var cancelled, cancel, App, props, url, res, err;
+        var cancelled, cancel, App, props, url, res, AppTree, err;
         return _regenerator["default"].wrap(function _callee2$(_context2) {
           while (1) {
             switch (_context2.prev = _context2.next) {
@@ -3646,28 +3637,30 @@ function () {
                 props = {
                   pageProps: _context2.t1
                 };
-                _context2.next = 23;
+                _context2.next = 25;
                 break;
 
               case 20:
-                _context2.next = 22;
+                AppTree = this._wrapApp(App);
+                ctx.AppTree = AppTree;
+                _context2.next = 24;
                 return utils_1.loadGetInitialProps(App, {
-                  AppTree: this._wrapApp(App),
+                  AppTree: AppTree,
                   Component: Component,
                   router: this,
                   ctx: ctx
                 });
 
-              case 22:
+              case 24:
                 props = _context2.sent;
 
-              case 23:
+              case 25:
                 if (cancel === this.clc) {
                   this.clc = null;
                 }
 
                 if (!cancelled) {
-                  _context2.next = 28;
+                  _context2.next = 30;
                   break;
                 }
 
@@ -3675,10 +3668,10 @@ function () {
                 err.cancelled = true;
                 throw err;
 
-              case 28:
+              case 30:
                 return _context2.abrupt("return", props);
 
-              case 29:
+              case 31:
               case "end":
                 return _context2.stop();
             }
Diff for mainModern.js
@@ -1,5 +1,20 @@
 (window["webpackJsonp"] = window["webpackJsonp"] || []).push([[8],{
 
+/***/ "+iuc":
+/***/ (function(module, exports, __webpack_require__) {
+
+__webpack_require__("wgeU");
+__webpack_require__("FlQf");
+__webpack_require__("bBy9");
+__webpack_require__("B9jh");
+__webpack_require__("dL40");
+__webpack_require__("xvv9");
+__webpack_require__("V+O7");
+module.exports = __webpack_require__("WEpk").Set;
+
+
+/***/ }),
+
 /***/ "+oT+":
 /***/ (function(module, exports, __webpack_require__) {
 
@@ -54,6 +69,28 @@ __webpack_require__("cHUd")('Map');
 
 /***/ }),
 
+/***/ "B9jh":
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+var strong = __webpack_require__("Wu5q");
+var validate = __webpack_require__("n3ko");
+var SET = 'Set';
+
+// 23.2 Set Objects
+module.exports = __webpack_require__("raTm")(SET, function (get) {
+  return function Set() { return get(this, arguments.length > 0 ? arguments[0] : undefined); };
+}, {
+  // 23.2.3.1 Set.prototype.add(value)
+  add: function add(value) {
+    return strong.def(validate(this, SET), value = value === 0 ? 0 : value, value);
+  }
+}, strong);
+
+
+/***/ }),
+
 /***/ "BMP1":
 /***/ (function(module, exports, __webpack_require__) {
 
@@ -538,15 +575,17 @@ function _renderError() {
     // If we've gotten here upon initial render, we can use the props from the server.
     // Otherwise, we need to call `getInitialProps` on `App` before mounting.
 
+    const AppTree = wrapApp(App);
     const appCtx = {
-      AppTree: wrapApp(App),
       Component: ErrorComponent,
+      AppTree,
       router,
       ctx: {
         err,
         pathname: page,
         query,
-        asPath
+        asPath,
+        AppTree
       }
     };
     const initProps = props.props ? props.props : yield (0, _utils.loadGetInitialProps)(App, appCtx);
@@ -562,48 +601,14 @@ function _renderError() {
 let isInitialRender = typeof _reactDom.default.hydrate === 'function';
 
 function renderReactElement(reactEl, domEl) {
-  // mark start of hydrate/render
-  if (_utils.SUPPORTS_PERFORMANCE_USER_TIMING) {
-    performance.mark('beforeRender');
-  } // The check for `.hydrate` is there to support React alternatives like preact
-
-
+  // The check for `.hydrate` is there to support React alternatives like preact
   if (isInitialRender) {
-    _reactDom.default.hydrate(reactEl, domEl, markHydrateComplete);
+    _reactDom.default.hydrate(reactEl, domEl);
 
     isInitialRender = false;
   } else {
-    _reactDom.default.render(reactEl, domEl, markRenderComplete);
-  }
-}
-
-function markHydrateComplete() {
-  if (!_utils.SUPPORTS_PERFORMANCE_USER_TIMING) return;
-  performance.mark('afterHydrate'); // mark end of hydration
-
-  performance.measure('Next.js-before-hydration', null, 'beforeRender');
-  performance.measure('Next.js-hydration', 'beforeRender', 'afterHydrate');
-  clearMarks();
-}
-
-function markRenderComplete() {
-  if (!_utils.SUPPORTS_PERFORMANCE_USER_TIMING) return;
-  performance.mark('afterRender'); // mark end of render
-
-  const navStartEntries = performance.getEntriesByName('routeChange', 'mark');
-
-  if (!navStartEntries.length) {
-    return;
+    _reactDom.default.render(reactEl, domEl);
   }
-
-  performance.measure('Next.js-route-change-to-render', navStartEntries[0].name, 'beforeRender');
-  performance.measure('Next.js-render', 'beforeRender', 'afterRender');
-  clearMarks();
-}
-
-function clearMarks() {
-  performance.clearMarks();
-  performance.clearMeasures();
 }
 
 function AppContainer(_ref4) {
@@ -655,15 +660,17 @@ function _doRender() {
         query,
         asPath
       } = router;
+      const AppTree = wrapApp(App);
       const appCtx = {
         router,
-        AppTree: wrapApp(App),
+        AppTree,
         Component: ErrorComponent,
         ctx: {
           err,
           pathname,
           query,
-          asPath
+          asPath,
+          AppTree
         }
       };
       props = yield (0, _utils.loadGetInitialProps)(App, appCtx);
@@ -726,6 +733,15 @@ module.exports = __webpack_require__("WEpk").Map;
 
 /***/ }),
 
+/***/ "V+O7":
+/***/ (function(module, exports, __webpack_require__) {
+
+// https://tc39.github.io/proposal-setmap-offrom/#sec-set.from
+__webpack_require__("aPfg")('Set');
+
+
+/***/ }),
+
 /***/ "XLbu":
 /***/ (function(module, exports, __webpack_require__) {
 
@@ -780,6 +796,17 @@ exports.DataManager = DataManager;
 
 /***/ }),
 
+/***/ "dL40":
+/***/ (function(module, exports, __webpack_require__) {
+
+// https://github.com/DavidBruant/Map-Set.prototype.toJSON
+var $export = __webpack_require__("Y7ZC");
+
+$export($export.P + $export.R, 'Set', { toJSON: __webpack_require__("8iia")('Set') });
+
+
+/***/ }),
+
 /***/ "dVTT":
 /***/ (function(module, exports, __webpack_require__) {
 
@@ -855,6 +882,22 @@ exports.DataManagerContext = React.createContext(null);
 
 /***/ }),
 
+/***/ "ttDY":
+/***/ (function(module, exports, __webpack_require__) {
+
+module.exports = __webpack_require__("+iuc");
+
+/***/ }),
+
+/***/ "xvv9":
+/***/ (function(module, exports, __webpack_require__) {
+
+// https://tc39.github.io/proposal-setmap-offrom/#sec-set.of
+__webpack_require__("cHUd")('Set');
+
+
+/***/ }),
+
 /***/ "zmvN":
 /***/ (function(module, exports, __webpack_require__) {
 
@@ -870,10 +913,12 @@ var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__("+oT+"));
 
 var _promise = _interopRequireDefault(__webpack_require__("eVuF"));
 
+var _set = _interopRequireDefault(__webpack_require__("ttDY"));
+
 var _mitt = _interopRequireDefault(__webpack_require__("kiME"));
 
 var _unfetch = _interopRequireDefault(__webpack_require__("m/Gl"));
-/* global document, window */
+/* global document */
 
 
 function supportsPreload(el) {
@@ -900,16 +945,10 @@ class PageLoader {
     this.buildId = buildId;
     this.assetPrefix = assetPrefix;
     this.pageCache = {};
+    this.prefetchCache = new _set.default();
     this.pageRegisterEvents = (0, _mitt.default)();
     this.loadingRoutes = {};
     this.promisedBuildId = _promise.default.resolve();
-
-    if (false) {}
-  } // Returns a promise for the dependencies for a particular route
-
-
-  getDependencies(route) {
-    return this.promisedBuildManifest.then(man => man[route] && man[route].map(url => "/_next/" + url) || []);
   }
 
   normalizeRoute(route) {
@@ -958,13 +997,12 @@ class PageLoader {
 
       if (document.getElementById("__NEXT_PAGE__" + route)) {
         return;
-      }
+      } // Load the script if not asked to load yet.
+
 
       if (!this.loadingRoutes[route]) {
-        if (false) {} else {
-          this.loadRoute(route);
-          this.loadingRoutes[route] = true;
-        }
+        this.loadScript(route);
+        this.loadingRoutes[route] = true;
       }
     });
   }
@@ -989,41 +1027,35 @@ class PageLoader {
     });
   }
 
-  loadRoute(route) {
+  loadScript(route) {
     var _this = this;
 
     return (0, _asyncToGenerator2.default)(function* () {
       yield _this.promisedBuildId;
       route = _this.normalizeRoute(route);
       let scriptRoute = route === '/' ? '/index.js' : route + ".js";
-      const url = _this.assetPrefix + "/_next/static/" + encodeURIComponent(_this.buildId) + "/pages" + scriptRoute;
-
-      _this.loadScript(url, route, true);
-    })();
-  }
-
-  loadScript(url, route, isPage) {
-    const script = document.createElement('script');
+      const script = document.createElement('script');
 
-    if ( true && 'noModule' in script) {
-      script.type = 'module'; // Only page bundle scripts need to have .module added to url,
-      // dependencies already have it added during build manifest creation
+      if ( true && 'noModule' in script) {
+        script.type = 'module';
+        scriptRoute = scriptRoute.replace(/\.js$/, '.module.js');
+      }
 
-      if (isPage) url = url.replace(/\.js$/, '.module.js');
-    }
+      const url = _this.assetPrefix + "/_next/static/" + encodeURIComponent(_this.buildId) + "/pages" + scriptRoute;
+      script.crossOrigin = "anonymous";
+      script.src = url;
 
-    script.crossOrigin = "anonymous";
-    script.src = url;
+      script.onerror = () => {
+        const error = new Error("Error loading script " + url);
+        error.code = 'PAGE_LOAD_ERROR';
 
-    script.onerror = () => {
-      const error = new Error("Error loading script " + url);
-      error.code = 'PAGE_LOAD_ERROR';
-      this.pageRegisterEvents.emit(route, {
-        error
-      });
-    };
+        _this.pageRegisterEvents.emit(route, {
+          error
+        });
+      };
 
-    document.body.appendChild(script);
+      document.body.appendChild(script);
+    })();
   } // This method if called by the route code.
 
 
@@ -1057,11 +1089,10 @@ class PageLoader {
     register();
   }
 
-  prefetch(route, isDependency) {
+  prefetch(route) {
     var _this2 = this;
 
     return (0, _asyncToGenerator2.default)(function* () {
-      yield _this2.promisedBuildId;
       route = _this2.normalizeRoute(route);
       let scriptRoute = (route === '/' ? '/index' : route) + ".js";
 
@@ -1069,12 +1100,11 @@ class PageLoader {
         scriptRoute = scriptRoute.replace(/\.js$/, '.module.js');
       }
 
-      const url = isDependency ? route : _this2.assetPrefix + "/_next/static/" + encodeURIComponent(_this2.buildId) + "/pages" + scriptRoute; // n.b. If preload is not supported, we fall back to `loadPage` which has
-      // its own deduping mechanism.
-
-      if (document.querySelector("link[rel=\"preload\"][href^=\"" + url + "\"]") || document.getElementById("__NEXT_PAGE__" + route)) {
+      if (_this2.prefetchCache.has(scriptRoute) || document.getElementById("__NEXT_PAGE__" + route)) {
         return;
-      } // Inspired by quicklink, license: https://github.com/GoogleChromeLabs/quicklink/blob/master/LICENSE
+      }
+
+      _this2.prefetchCache.add(scriptRoute); // Inspired by quicklink, license: https://github.com/GoogleChromeLabs/quicklink/blob/master/LICENSE
 
 
       let cn;
@@ -1084,21 +1114,14 @@ class PageLoader {
         if ((cn.effectiveType || '').indexOf('2g') !== -1 || cn.saveData) {
           return;
         }
-      }
-
-      if (false) {} // Feature detection is used to see if preload is supported
+      } // Feature detection is used to see if preload is supported
       // If not fall back to loading script tags before the page is loaded
       // https://caniuse.com/#feat=link-rel-preload
 
 
       if (hasPreload) {
-        preloadScript(url);
-        return;
-      }
-
-      if (isDependency) {
-        // loadPage will automatically handle depencies, so no need to
-        // preload them manually
+        yield _this2.promisedBuildId;
+        preloadScript(_this2.assetPrefix + "/_next/static/" + encodeURIComponent(_this2.buildId) + "/pages" + scriptRoute);
         return;
       }
 
Diff for commonsModern.js
@@ -763,8 +763,6 @@ function formatWithValidation(url, options) {
 }
 
 exports.formatWithValidation = formatWithValidation;
-exports.SUPPORTS_PERFORMANCE = typeof performance !== 'undefined';
-exports.SUPPORTS_PERFORMANCE_USER_TIMING = exports.SUPPORTS_PERFORMANCE && typeof performance.mark === 'function' && typeof performance.measure === 'function';
 
 /***/ }),
 
@@ -2679,13 +2677,8 @@ class Router {
 
   change(method, _url, _as, options) {
     return new _promise.default((resolve, reject) => {
-      // marking route changes as a navigation start entry
-      if (utils_1.SUPPORTS_PERFORMANCE_USER_TIMING) {
-        performance.mark('routeChange');
-      } // If url and as provided as an object representation,
+      // If url and as provided as an object representation,
       // we'll format them into the string version here.
-
-
       const url = typeof _url === 'object' ? utils_1.formatWithValidation(_url) : _url;
       let as = typeof _as === 'object' ? utils_1.formatWithValidation(_as) : _as; // Add the ending slash to the paths. So, we can serve the
       // "<page>/index.html" directly for the SSR page.
@@ -2824,12 +2817,12 @@ class Router {
       if (false) {}
 
       return new _promise.default((resolve, reject) => {
-        const ctx = {
+        // we provide AppTree later so this needs to be `any`
+        this.getInitialProps(Component, {
           pathname,
           query,
           asPath: as
-        };
-        this.getInitialProps(Component, ctx).then(props => {
+        }).then(props => {
           routeInfo.props = props;
           this.components[route] = routeInfo;
           resolve(routeInfo);
@@ -2865,13 +2858,12 @@ class Router {
             Component,
             err
           };
-          const ctx = {
-            err,
-            pathname,
-            query
-          };
           return new _promise.default(resolve => {
-            this.getInitialProps(Component, ctx).then(props => {
+            this.getInitialProps(Component, {
+              err,
+              pathname,
+              query
+            }).then(props => {
               routeInfo.props = props;
               routeInfo.error = err;
               resolve(routeInfo);
@@ -3035,8 +3027,11 @@ class Router {
         }
       };
     } else {
+      const AppTree = this._wrapApp(App);
+
+      ctx.AppTree = AppTree;
       props = await utils_1.loadGetInitialProps(App, {
-        AppTree: this._wrapApp(App),
+        AppTree,
         Component,
         router: this,
         ctx

@ijjk
Copy link
Member Author

ijjk commented Aug 11, 2019

Stats from current PR

Click to expand stats ⚠️ Total Bundle Size Increase ⚠️
zeit/next.js canary ijjk/next.js add-apptree-ctx Change
Build Duration 21.6s 22.2s ⚠️ +597ms
node_modules Size 41.6 MB 41.6 MB ⚠️ +740 B
Total Bundle (main, webpack, commons) Size 214 kB 214 kB ⚠️ +38 B
Total Bundle (main, webpack, commons) gzip Size 70.6 kB 70.6 kB ⚠️ +11 B
Total Bundle (main, webpack, commons) Modern Size 189 kB 189 kB ⚠️ +36 B
Total Bundle (main, webpack, commons) Modern gzip Size 62.4 kB 62.4 kB ⚠️ +12 B
Client _app Size 2.35 kB 2.35 kB
Client _app gzip Size 1.07 kB 1.07 kB
Client _app Modern Size 1.79 kB 1.79 kB
Client _app gzip Modern Size 880 B 880 B
Client _error Size 8.22 kB 8.22 kB
Client _error gzip Size 3.16 kB 3.16 kB
Client _error Modern Size 5.85 kB 5.85 kB
Client _error gzip Modern Size 2.33 kB 2.33 kB
Client pages/index Size 343 B 343 B
Client pages/index gzip Size 246 B 246 B
Client pages/index Modern Size 319 B 319 B
Client pages/index gzip Modern Size 254 B 254 B
Client pages/link Size 4.18 kB 4.18 kB
Client pages/link gzip Size 1.82 kB 1.82 kB
Client pages/link Modern Size 3.81 kB 3.81 kB
Client pages/link gzip Modern Size 1.72 kB 1.72 kB ⚠️ +1 B
Client pages/routerDirect Size 423 B 423 B
Client pages/routerDirect gzip Size 306 B 306 B
Client pages/routerDirect Modern Size 411 B 411 B
Client pages/routerDirect gzip Modern Size 314 B 314 B
Client pages/withRouter Size 435 B 435 B
Client pages/withRouter gzip Size 300 B 301 B ⚠️ +1 B
Client pages/withRouter Modern Size 423 B 423 B
Client pages/withRouter gzip Modern Size 309 B 309 B
Client main Size 16.3 kB 16.3 kB ⚠️ +32 B
Client main gzip Size 5.73 kB 5.74 kB ⚠️ +14 B
Client main Modern Size 13.1 kB 13.1 kB ⚠️ +28 B
Client main Modern gzip Size 4.99 kB 5.01 kB ⚠️ +16 B
Client commons Size 195 kB 195 kB ⚠️ +6 B
Client commons gzip Size 63.6 kB 63.6 kB -3 B
Client commons Modern Size 176 kB 176 kB ⚠️ +8 B
Client commons Modern gzip Size 57.4 kB 57.4 kB -4 B
Client webpack Size 1.53 kB 1.53 kB
Client webpack gzip Size 778 B 778 B
Client webpack Modern Size 1.53 kB 1.53 kB
Client webpack Modern gzip Size 785 B 785 B
Base Rendered Size 2.76 kB 2.76 kB
Build Dir Size 1.44 MB 1.44 MB ⚠️ +592 B
Click to expand serverless stats ⚠️ Total Bundle Size Increase ⚠️
zeit/next.js canary ijjk/next.js add-apptree-ctx Change
Build Duration 25.5s 25s -516ms
node_modules Size 41.6 MB 41.6 MB ⚠️ +740 B
Total Bundle (main, webpack, commons) Size 214 kB 214 kB ⚠️ +38 B
Total Bundle (main, webpack, commons) gzip Size 70.6 kB 70.6 kB ⚠️ +11 B
Total Bundle (main, webpack, commons) Modern Size 189 kB 189 kB ⚠️ +36 B
Total Bundle (main, webpack, commons) Modern gzip Size 62.4 kB 62.4 kB ⚠️ +12 B
Client _app Size 2.35 kB 2.35 kB
Client _app gzip Size 1.07 kB 1.07 kB
Client _app Modern Size 1.79 kB 1.79 kB
Client _app gzip Modern Size 880 B 880 B
Client _error Size 8.22 kB 8.22 kB
Client _error gzip Size 3.16 kB 3.16 kB
Client _error Modern Size 5.85 kB 5.85 kB
Client _error gzip Modern Size 2.33 kB 2.33 kB
Client pages/index Size 343 B 343 B
Client pages/index gzip Size 246 B 246 B
Client pages/index Modern Size 319 B 319 B
Client pages/index gzip Modern Size 254 B 254 B
Client pages/link Size 4.18 kB 4.18 kB
Client pages/link gzip Size 1.82 kB 1.82 kB
Client pages/link Modern Size 3.81 kB 3.81 kB
Client pages/link gzip Modern Size 1.72 kB 1.72 kB
Client pages/routerDirect Size 423 B 423 B
Client pages/routerDirect gzip Size 306 B 306 B
Client pages/routerDirect Modern Size 411 B 411 B
Client pages/routerDirect gzip Modern Size 314 B 314 B
Client pages/withRouter Size 435 B 435 B
Client pages/withRouter gzip Size 301 B 301 B
Client pages/withRouter Modern Size 423 B 423 B
Client pages/withRouter gzip Modern Size 309 B 309 B
Client main Size 16.3 kB 16.3 kB ⚠️ +32 B
Client main gzip Size 5.73 kB 5.74 kB ⚠️ +14 B
Client main Modern Size 13.1 kB 13.1 kB ⚠️ +28 B
Client main Modern gzip Size 4.99 kB 5.01 kB ⚠️ +16 B
Client commons Size 195 kB 195 kB ⚠️ +6 B
Client commons gzip Size 63.6 kB 63.6 kB -3 B
Client commons Modern Size 176 kB 176 kB ⚠️ +8 B
Client commons Modern gzip Size 57.4 kB 57.4 kB -4 B
Client webpack Size 1.53 kB 1.53 kB
Client webpack gzip Size 778 B 778 B
Client webpack Modern Size 1.53 kB 1.53 kB
Client webpack Modern gzip Size 785 B 785 B
Serverless pages/link Size 256 kB 256 kB ⚠️ +39 B
Serverless pages/link gzip Size 68.8 kB 68.9 kB ⚠️ +32 B
Serverless pages/index Size 249 kB 249 kB ⚠️ +39 B
Serverless pages/index gzip Size 66.6 kB 66.6 kB ⚠️ +34 B
Serverless pages/_error Size 248 kB 248 kB ⚠️ +39 B
Serverless pages/_error gzip Size 66.3 kB 66.3 kB ⚠️ +34 B
Serverless pages/routerDirect Size 249 kB 249 kB ⚠️ +39 B
Serverless pages/routerDirect gzip Size 66.5 kB 66.6 kB ⚠️ +33 B
Serverless pages/withRouter Size 249 kB 249 kB ⚠️ +39 B
Serverless pages/withRouter gzip Size 66.6 kB 66.6 kB ⚠️ +41 B
Build Dir Size 2.64 MB 2.65 MB ⚠️ +859 B
Diff for main.js
@@ -658,7 +658,7 @@ function _renderError() {
   _renderError = (0, _asyncToGenerator2["default"])(
   /*#__PURE__*/
   _regenerator["default"].mark(function _callee3(props) {
-    var App, err, appCtx, initProps;
+    var App, err, AppTree, appCtx, initProps;
     return _regenerator["default"].wrap(function _callee3$(_context3) {
       while (1) {
         switch (_context3.prev = _context3.next) {
@@ -684,44 +684,46 @@ function _renderError() {
             // In production we do a normal render with the `ErrorComponent` as component.
             // If we've gotten here upon initial render, we can use the props from the server.
             // Otherwise, we need to call `getInitialProps` on `App` before mounting.
+            AppTree = wrapApp(App);
             appCtx = {
-              AppTree: wrapApp(App),
               Component: ErrorComponent,
+              AppTree: AppTree,
               router: router,
               ctx: {
                 err: err,
                 pathname: page,
                 query: query,
-                asPath: asPath
+                asPath: asPath,
+                AppTree: AppTree
               }
             };
 
             if (!props.props) {
-              _context3.next = 12;
+              _context3.next = 13;
               break;
             }
 
             _context3.t0 = props.props;
-            _context3.next = 15;
+            _context3.next = 16;
             break;
 
-          case 12:
-            _context3.next = 14;
+          case 13:
+            _context3.next = 15;
             return (0, _utils.loadGetInitialProps)(App, appCtx);
 
-          case 14:
+          case 15:
             _context3.t0 = _context3.sent;
 
-          case 15:
+          case 16:
             initProps = _context3.t0;
-            _context3.next = 18;
+            _context3.next = 19;
             return doRender((0, _extends2["default"])({}, props, {
               err: err,
               Component: ErrorComponent,
               props: initProps
             }));
 
-          case 18:
+          case 19:
           case "end":
             return _context3.stop();
         }
@@ -819,7 +821,7 @@ function _doRender() {
   _doRender = (0, _asyncToGenerator2["default"])(
   /*#__PURE__*/
   _regenerator["default"].mark(function _callee4(_ref5) {
-    var App, Component, props, err, _router2, pathname, _query, _asPath, appCtx, appProps;
+    var App, Component, props, err, _router2, pathname, _query, _asPath, AppTree, appCtx, appProps;
 
     return _regenerator["default"].wrap(function _callee4$(_context4) {
       while (1) {
@@ -829,29 +831,31 @@ function _doRender() {
             // this is for when ErrorComponent gets replaced by Component by HMR
 
             if (!(!props && Component && Component !== ErrorComponent && lastAppProps.Component === ErrorComponent)) {
-              _context4.next = 7;
+              _context4.next = 8;
               break;
             }
 
             _router2 = router, pathname = _router2.pathname, _query = _router2.query, _asPath = _router2.asPath;
+            AppTree = wrapApp(App);
             appCtx = {
               router: router,
-              AppTree: wrapApp(App),
+              AppTree: AppTree,
               Component: ErrorComponent,
               ctx: {
                 err: err,
                 pathname: pathname,
                 query: _query,
-                asPath: _asPath
+                asPath: _asPath,
+                AppTree: AppTree
               }
             };
-            _context4.next = 6;
+            _context4.next = 7;
             return (0, _utils.loadGetInitialProps)(App, appCtx);
 
-          case 6:
+          case 7:
             props = _context4.sent;
 
-          case 7:
+          case 8:
             Component = Component || lastAppProps.Component;
             props = props || lastAppProps.props;
             appProps = (0, _extends2["default"])({}, props, {
@@ -874,7 +878,7 @@ function _doRender() {
               appProps: appProps
             });
 
-          case 14:
+          case 15:
           case "end":
             return _context4.stop();
         }
Diff for commons.js
@@ -3349,13 +3349,12 @@ function () {
         if (false) { var _require, isValidElementType; }
 
         return new _promise["default"](function (resolve, reject) {
-          var ctx = {
+          // we provide AppTree later so this needs to be `any`
+          _this3.getInitialProps(Component, {
             pathname: pathname,
             query: query,
             asPath: as
-          };
-
-          _this3.getInitialProps(Component, ctx).then(function (props) {
+          }).then(function (props) {
             routeInfo.props = props;
             _this3.components[route] = routeInfo;
             resolve(routeInfo);
@@ -3391,13 +3390,12 @@ function () {
               Component: Component,
               err: err
             };
-            var ctx = {
-              err: err,
-              pathname: pathname,
-              query: query
-            };
             return new _promise["default"](function (resolve) {
-              _this3.getInitialProps(Component, ctx).then(function (props) {
+              _this3.getInitialProps(Component, {
+                err: err,
+                pathname: pathname,
+                query: query
+              }).then(function (props) {
                 routeInfo.props = props;
                 routeInfo.error = err;
                 resolve(routeInfo);
@@ -3585,7 +3583,7 @@ function () {
       var _getInitialProps = (0, _asyncToGenerator2["default"])(
       /*#__PURE__*/
       _regenerator["default"].mark(function _callee2(Component, ctx) {
-        var cancelled, cancel, App, props, url, res, err;
+        var cancelled, cancel, App, props, url, res, AppTree, err;
         return _regenerator["default"].wrap(function _callee2$(_context2) {
           while (1) {
             switch (_context2.prev = _context2.next) {
@@ -3646,28 +3644,30 @@ function () {
                 props = {
                   pageProps: _context2.t1
                 };
-                _context2.next = 23;
+                _context2.next = 25;
                 break;
 
               case 20:
-                _context2.next = 22;
+                AppTree = this._wrapApp(App);
+                ctx.AppTree = AppTree;
+                _context2.next = 24;
                 return utils_1.loadGetInitialProps(App, {
-                  AppTree: this._wrapApp(App),
+                  AppTree: AppTree,
                   Component: Component,
                   router: this,
                   ctx: ctx
                 });
 
-              case 22:
+              case 24:
                 props = _context2.sent;
 
-              case 23:
+              case 25:
                 if (cancel === this.clc) {
                   this.clc = null;
                 }
 
                 if (!cancelled) {
-                  _context2.next = 28;
+                  _context2.next = 30;
                   break;
                 }
 
@@ -3675,10 +3675,10 @@ function () {
                 err.cancelled = true;
                 throw err;
 
-              case 28:
+              case 30:
                 return _context2.abrupt("return", props);
 
-              case 29:
+              case 31:
               case "end":
                 return _context2.stop();
             }
Diff for mainModern.js
@@ -538,15 +538,17 @@ function _renderError() {
     // If we've gotten here upon initial render, we can use the props from the server.
     // Otherwise, we need to call `getInitialProps` on `App` before mounting.
 
+    const AppTree = wrapApp(App);
     const appCtx = {
-      AppTree: wrapApp(App),
       Component: ErrorComponent,
+      AppTree,
       router,
       ctx: {
         err,
         pathname: page,
         query,
-        asPath
+        asPath,
+        AppTree
       }
     };
     const initProps = props.props ? props.props : yield (0, _utils.loadGetInitialProps)(App, appCtx);
@@ -655,15 +657,17 @@ function _doRender() {
         query,
         asPath
       } = router;
+      const AppTree = wrapApp(App);
       const appCtx = {
         router,
-        AppTree: wrapApp(App),
+        AppTree,
         Component: ErrorComponent,
         ctx: {
           err,
           pathname,
           query,
-          asPath
+          asPath,
+          AppTree
         }
       };
       props = yield (0, _utils.loadGetInitialProps)(App, appCtx);
Diff for commonsModern.js
@@ -2824,12 +2824,12 @@ class Router {
       if (false) {}
 
       return new _promise.default((resolve, reject) => {
-        const ctx = {
+        // we provide AppTree later so this needs to be `any`
+        this.getInitialProps(Component, {
           pathname,
           query,
           asPath: as
-        };
-        this.getInitialProps(Component, ctx).then(props => {
+        }).then(props => {
           routeInfo.props = props;
           this.components[route] = routeInfo;
           resolve(routeInfo);
@@ -2865,13 +2865,12 @@ class Router {
             Component,
             err
           };
-          const ctx = {
-            err,
-            pathname,
-            query
-          };
           return new _promise.default(resolve => {
-            this.getInitialProps(Component, ctx).then(props => {
+            this.getInitialProps(Component, {
+              err,
+              pathname,
+              query
+            }).then(props => {
               routeInfo.props = props;
               routeInfo.error = err;
               resolve(routeInfo);
@@ -3035,8 +3034,11 @@ class Router {
         }
       };
     } else {
+      const AppTree = this._wrapApp(App);
+
+      ctx.AppTree = AppTree;
       props = await utils_1.loadGetInitialProps(App, {
-        AppTree: this._wrapApp(App),
+        AppTree,
         Component,
         router: this,
         ctx

Copy link
Member

@timneutkens timneutkens left a comment

Choose a reason for hiding this comment

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

@ijjk could you add a test for this?

@ijjk
Copy link
Member Author

ijjk commented Aug 11, 2019

Added a test for it in the app-tree suite

@ijjk
Copy link
Member Author

ijjk commented Aug 12, 2019

Stats from current PR

Click to expand stats ⚠️ Total Bundle Size Increase ⚠️
zeit/next.js canary ijjk/next.js add-apptree-ctx Change
Build Duration 22.2s 22.8s ⚠️ +644ms
node_modules Size 41.6 MB 41.6 MB ⚠️ +740 B
Total Bundle (main, webpack, commons) Size 213 kB 213 kB ⚠️ +38 B
Total Bundle (main, webpack, commons) gzip Size 70 kB 70 kB ⚠️ +16 B
Total Bundle (main, webpack, commons) Modern Size 188 kB 188 kB ⚠️ +36 B
Total Bundle (main, webpack, commons) Modern gzip Size 61.8 kB 61.8 kB ⚠️ +11 B
Client _app Size 2.35 kB 2.35 kB
Client _app gzip Size 1.07 kB 1.07 kB
Client _app Modern Size 1.79 kB 1.79 kB
Client _app gzip Modern Size 880 B 880 B
Client _error Size 8.22 kB 8.22 kB
Client _error gzip Size 3.16 kB 3.16 kB
Client _error Modern Size 5.85 kB 5.85 kB
Client _error gzip Modern Size 2.33 kB 2.33 kB
Client pages/index Size 343 B 343 B
Client pages/index gzip Size 246 B 246 B
Client pages/index Modern Size 319 B 319 B
Client pages/index gzip Modern Size 254 B 254 B
Client pages/link Size 4.18 kB 4.18 kB
Client pages/link gzip Size 1.82 kB 1.82 kB
Client pages/link Modern Size 3.81 kB 3.81 kB
Client pages/link gzip Modern Size 1.72 kB 1.72 kB
Client pages/routerDirect Size 423 B 423 B
Client pages/routerDirect gzip Size 306 B 306 B
Client pages/routerDirect Modern Size 411 B 411 B
Client pages/routerDirect gzip Modern Size 314 B 314 B
Client pages/withRouter Size 435 B 435 B
Client pages/withRouter gzip Size 301 B 301 B
Client pages/withRouter Modern Size 423 B 423 B
Client pages/withRouter gzip Modern Size 309 B 309 B
Client main Size 14.7 kB 14.7 kB ⚠️ +32 B
Client main gzip Size 5.08 kB 5.1 kB ⚠️ +19 B
Client main Modern Size 11.6 kB 11.7 kB ⚠️ +28 B
Client main Modern gzip Size 4.37 kB 4.38 kB ⚠️ +15 B
Client commons Size 195 kB 195 kB ⚠️ +6 B
Client commons gzip Size 63.6 kB 63.6 kB -3 B
Client commons Modern Size 176 kB 176 kB ⚠️ +8 B
Client commons Modern gzip Size 57.4 kB 57.4 kB -4 B
Client webpack Size 1.53 kB 1.53 kB
Client webpack gzip Size 778 B 778 B
Client webpack Modern Size 1.53 kB 1.53 kB
Client webpack Modern gzip Size 785 B 785 B
Base Rendered Size 2.76 kB 2.76 kB
Build Dir Size 1.43 MB 1.43 MB ⚠️ +592 B
Click to expand serverless stats ⚠️ Total Bundle Size Increase ⚠️
zeit/next.js canary ijjk/next.js add-apptree-ctx Change
Build Duration 24.2s 24.5s ⚠️ +360ms
node_modules Size 41.6 MB 41.6 MB ⚠️ +740 B
Total Bundle (main, webpack, commons) Size 213 kB 213 kB ⚠️ +38 B
Total Bundle (main, webpack, commons) gzip Size 70 kB 70 kB ⚠️ +16 B
Total Bundle (main, webpack, commons) Modern Size 188 kB 188 kB ⚠️ +36 B
Total Bundle (main, webpack, commons) Modern gzip Size 61.8 kB 61.8 kB ⚠️ +11 B
Client _app Size 2.35 kB 2.35 kB
Client _app gzip Size 1.07 kB 1.07 kB
Client _app Modern Size 1.79 kB 1.79 kB
Client _app gzip Modern Size 880 B 880 B
Client _error Size 8.22 kB 8.22 kB
Client _error gzip Size 3.16 kB 3.16 kB
Client _error Modern Size 5.85 kB 5.85 kB
Client _error gzip Modern Size 2.33 kB 2.33 kB
Client pages/index Size 343 B 343 B
Client pages/index gzip Size 246 B 246 B
Client pages/index Modern Size 319 B 319 B
Client pages/index gzip Modern Size 254 B 254 B
Client pages/link Size 4.18 kB 4.18 kB
Client pages/link gzip Size 1.82 kB 1.82 kB
Client pages/link Modern Size 3.81 kB 3.81 kB
Client pages/link gzip Modern Size 1.72 kB 1.72 kB
Client pages/routerDirect Size 423 B 423 B
Client pages/routerDirect gzip Size 306 B 306 B
Client pages/routerDirect Modern Size 411 B 411 B
Client pages/routerDirect gzip Modern Size 314 B 314 B
Client pages/withRouter Size 435 B 435 B
Client pages/withRouter gzip Size 301 B 301 B
Client pages/withRouter Modern Size 423 B 423 B
Client pages/withRouter gzip Modern Size 309 B 309 B
Client main Size 14.7 kB 14.7 kB ⚠️ +32 B
Client main gzip Size 5.08 kB 5.1 kB ⚠️ +19 B
Client main Modern Size 11.6 kB 11.7 kB ⚠️ +28 B
Client main Modern gzip Size 4.37 kB 4.38 kB ⚠️ +15 B
Client commons Size 195 kB 195 kB ⚠️ +6 B
Client commons gzip Size 63.6 kB 63.6 kB -3 B
Client commons Modern Size 176 kB 176 kB ⚠️ +8 B
Client commons Modern gzip Size 57.4 kB 57.4 kB -4 B
Client webpack Size 1.53 kB 1.53 kB
Client webpack gzip Size 778 B 778 B
Client webpack Modern Size 1.53 kB 1.53 kB
Client webpack Modern gzip Size 785 B 785 B
Serverless pages/link Size 256 kB 256 kB ⚠️ +39 B
Serverless pages/link gzip Size 68.9 kB 68.9 kB ⚠️ +34 B
Serverless pages/index Size 249 kB 249 kB ⚠️ +39 B
Serverless pages/index gzip Size 66.6 kB 66.6 kB ⚠️ +33 B
Serverless pages/_error Size 248 kB 248 kB ⚠️ +39 B
Serverless pages/_error gzip Size 66.3 kB 66.4 kB ⚠️ +32 B
Serverless pages/routerDirect Size 249 kB 249 kB ⚠️ +39 B
Serverless pages/routerDirect gzip Size 66.6 kB 66.6 kB ⚠️ +32 B
Serverless pages/withRouter Size 249 kB 249 kB ⚠️ +39 B
Serverless pages/withRouter gzip Size 66.6 kB 66.7 kB ⚠️ +38 B
Build Dir Size 2.64 MB 2.64 MB ⚠️ +859 B
Diff for main.js
@@ -656,7 +656,7 @@ function _renderError() {
   _renderError = (0, _asyncToGenerator2["default"])(
   /*#__PURE__*/
   _regenerator["default"].mark(function _callee3(props) {
-    var App, err, appCtx, initProps;
+    var App, err, AppTree, appCtx, initProps;
     return _regenerator["default"].wrap(function _callee3$(_context3) {
       while (1) {
         switch (_context3.prev = _context3.next) {
@@ -682,44 +682,46 @@ function _renderError() {
             // In production we do a normal render with the `ErrorComponent` as component.
             // If we've gotten here upon initial render, we can use the props from the server.
             // Otherwise, we need to call `getInitialProps` on `App` before mounting.
+            AppTree = wrapApp(App);
             appCtx = {
-              AppTree: wrapApp(App),
               Component: ErrorComponent,
+              AppTree: AppTree,
               router: router,
               ctx: {
                 err: err,
                 pathname: page,
                 query: query,
-                asPath: asPath
+                asPath: asPath,
+                AppTree: AppTree
               }
             };
 
             if (!props.props) {
-              _context3.next = 12;
+              _context3.next = 13;
               break;
             }
 
             _context3.t0 = props.props;
-            _context3.next = 15;
+            _context3.next = 16;
             break;
 
-          case 12:
-            _context3.next = 14;
+          case 13:
+            _context3.next = 15;
             return (0, _utils.loadGetInitialProps)(App, appCtx);
 
-          case 14:
+          case 15:
             _context3.t0 = _context3.sent;
 
-          case 15:
+          case 16:
             initProps = _context3.t0;
-            _context3.next = 18;
+            _context3.next = 19;
             return doRender((0, _extends2["default"])({}, props, {
               err: err,
               Component: ErrorComponent,
               props: initProps
             }));
 
-          case 18:
+          case 19:
           case "end":
             return _context3.stop();
         }
@@ -817,7 +819,7 @@ function _doRender() {
   _doRender = (0, _asyncToGenerator2["default"])(
   /*#__PURE__*/
   _regenerator["default"].mark(function _callee4(_ref5) {
-    var App, Component, props, err, _router2, pathname, _query, _asPath, appCtx, appProps;
+    var App, Component, props, err, _router2, pathname, _query, _asPath, AppTree, appCtx, appProps;
 
     return _regenerator["default"].wrap(function _callee4$(_context4) {
       while (1) {
@@ -827,29 +829,31 @@ function _doRender() {
             // this is for when ErrorComponent gets replaced by Component by HMR
 
             if (!(!props && Component && Component !== ErrorComponent && lastAppProps.Component === ErrorComponent)) {
-              _context4.next = 7;
+              _context4.next = 8;
               break;
             }
 
             _router2 = router, pathname = _router2.pathname, _query = _router2.query, _asPath = _router2.asPath;
+            AppTree = wrapApp(App);
             appCtx = {
               router: router,
-              AppTree: wrapApp(App),
+              AppTree: AppTree,
               Component: ErrorComponent,
               ctx: {
                 err: err,
                 pathname: pathname,
                 query: _query,
-                asPath: _asPath
+                asPath: _asPath,
+                AppTree: AppTree
               }
             };
-            _context4.next = 6;
+            _context4.next = 7;
             return (0, _utils.loadGetInitialProps)(App, appCtx);
 
-          case 6:
+          case 7:
             props = _context4.sent;
 
-          case 7:
+          case 8:
             Component = Component || lastAppProps.Component;
             props = props || lastAppProps.props;
             appProps = (0, _extends2["default"])({}, props, {
@@ -872,7 +876,7 @@ function _doRender() {
               appProps: appProps
             });
 
-          case 14:
+          case 15:
           case "end":
             return _context4.stop();
         }
Diff for commons.js
@@ -3350,13 +3350,12 @@ function () {
         if (false) { var _require, isValidElementType; }
 
         return new _promise["default"](function (resolve, reject) {
-          var ctx = {
+          // we provide AppTree later so this needs to be `any`
+          _this3.getInitialProps(Component, {
             pathname: pathname,
             query: query,
             asPath: as
-          };
-
-          _this3.getInitialProps(Component, ctx).then(function (props) {
+          }).then(function (props) {
             routeInfo.props = props;
             _this3.components[route] = routeInfo;
             resolve(routeInfo);
@@ -3392,13 +3391,12 @@ function () {
               Component: Component,
               err: err
             };
-            var ctx = {
-              err: err,
-              pathname: pathname,
-              query: query
-            };
             return new _promise["default"](function (resolve) {
-              _this3.getInitialProps(Component, ctx).then(function (props) {
+              _this3.getInitialProps(Component, {
+                err: err,
+                pathname: pathname,
+                query: query
+              }).then(function (props) {
                 routeInfo.props = props;
                 routeInfo.error = err;
                 resolve(routeInfo);
@@ -3586,7 +3584,7 @@ function () {
       var _getInitialProps = (0, _asyncToGenerator2["default"])(
       /*#__PURE__*/
       _regenerator["default"].mark(function _callee2(Component, ctx) {
-        var cancelled, cancel, App, props, url, res, err;
+        var cancelled, cancel, App, props, url, res, AppTree, err;
         return _regenerator["default"].wrap(function _callee2$(_context2) {
           while (1) {
             switch (_context2.prev = _context2.next) {
@@ -3647,28 +3645,30 @@ function () {
                 props = {
                   pageProps: _context2.t1
                 };
-                _context2.next = 23;
+                _context2.next = 25;
                 break;
 
               case 20:
-                _context2.next = 22;
+                AppTree = this._wrapApp(App);
+                ctx.AppTree = AppTree;
+                _context2.next = 24;
                 return utils_1.loadGetInitialProps(App, {
-                  AppTree: this._wrapApp(App),
+                  AppTree: AppTree,
                   Component: Component,
                   router: this,
                   ctx: ctx
                 });
 
-              case 22:
+              case 24:
                 props = _context2.sent;
 
-              case 23:
+              case 25:
                 if (cancel === this.clc) {
                   this.clc = null;
                 }
 
                 if (!cancelled) {
-                  _context2.next = 28;
+                  _context2.next = 30;
                   break;
                 }
 
@@ -3676,10 +3676,10 @@ function () {
                 err.cancelled = true;
                 throw err;
 
-              case 28:
+              case 30:
                 return _context2.abrupt("return", props);
 
-              case 29:
+              case 31:
               case "end":
                 return _context2.stop();
             }
Diff for mainModern.js
@@ -536,15 +536,17 @@ function _renderError() {
     // If we've gotten here upon initial render, we can use the props from the server.
     // Otherwise, we need to call `getInitialProps` on `App` before mounting.
 
+    const AppTree = wrapApp(App);
     const appCtx = {
-      AppTree: wrapApp(App),
       Component: ErrorComponent,
+      AppTree,
       router,
       ctx: {
         err,
         pathname: page,
         query,
-        asPath
+        asPath,
+        AppTree
       }
     };
     const initProps = props.props ? props.props : yield (0, _utils.loadGetInitialProps)(App, appCtx);
@@ -653,15 +655,17 @@ function _doRender() {
         query,
         asPath
       } = router;
+      const AppTree = wrapApp(App);
       const appCtx = {
         router,
-        AppTree: wrapApp(App),
+        AppTree,
         Component: ErrorComponent,
         ctx: {
           err,
           pathname,
           query,
-          asPath
+          asPath,
+          AppTree
         }
       };
       props = yield (0, _utils.loadGetInitialProps)(App, appCtx);
Diff for commonsModern.js
@@ -2825,12 +2825,12 @@ class Router {
       if (false) {}
 
       return new _promise.default((resolve, reject) => {
-        const ctx = {
+        // we provide AppTree later so this needs to be `any`
+        this.getInitialProps(Component, {
           pathname,
           query,
           asPath: as
-        };
-        this.getInitialProps(Component, ctx).then(props => {
+        }).then(props => {
           routeInfo.props = props;
           this.components[route] = routeInfo;
           resolve(routeInfo);
@@ -2866,13 +2866,12 @@ class Router {
             Component,
             err
           };
-          const ctx = {
-            err,
-            pathname,
-            query
-          };
           return new _promise.default(resolve => {
-            this.getInitialProps(Component, ctx).then(props => {
+            this.getInitialProps(Component, {
+              err,
+              pathname,
+              query
+            }).then(props => {
               routeInfo.props = props;
               routeInfo.error = err;
               resolve(routeInfo);
@@ -3036,8 +3035,11 @@ class Router {
         }
       };
     } else {
+      const AppTree = this._wrapApp(App);
+
+      ctx.AppTree = AppTree;
       props = await utils_1.loadGetInitialProps(App, {
-        AppTree: this._wrapApp(App),
+        AppTree,
         Component,
         router: this,
         ctx

@ijjk
Copy link
Member Author

ijjk commented Aug 12, 2019

Stats from current PR

Click to expand stats ⚠️ Total Bundle Size Increase ⚠️
zeit/next.js canary ijjk/next.js add-apptree-ctx Change
Build Duration 20.6s 19.7s -878ms
node_modules Size 41.6 MB 41.6 MB -2.21 kB
Total Bundle (main, webpack, commons) Size 210 kB 213 kB ⚠️ +2.81 kB
Total Bundle (main, webpack, commons) gzip Size 69.3 kB 70 kB ⚠️ +684 B
Total Bundle (main, webpack, commons) Modern Size 187 kB 188 kB ⚠️ +798 B
Total Bundle (main, webpack, commons) Modern gzip Size 61.6 kB 61.8 kB ⚠️ +178 B
Client _app Size 1.9 kB 2.35 kB ⚠️ +455 B
Client _app gzip Size 913 B 1.07 kB ⚠️ +161 B
Client _app Modern Size 1.79 kB 1.79 kB
Client _app gzip Modern Size 880 B 880 B
Client _error Size 8.02 kB 8.22 kB ⚠️ +199 B
Client _error gzip Size 3.13 kB 3.16 kB ⚠️ +29 B
Client _error Modern Size 5.82 kB 5.85 kB ⚠️ +23 B
Client _error gzip Modern Size 2.35 kB 2.33 kB -13 B
Client pages/index Size 343 B 343 B
Client pages/index gzip Size 246 B 246 B
Client pages/index Modern Size 319 B 319 B
Client pages/index gzip Modern Size 254 B 254 B
Client pages/link Size 4.1 kB 4.18 kB ⚠️ +85 B
Client pages/link gzip Size 1.8 kB 1.82 kB ⚠️ +22 B
Client pages/link Modern Size 3.81 kB 3.81 kB
Client pages/link gzip Modern Size 1.72 kB 1.72 kB -1 B
Client pages/routerDirect Size 423 B 423 B
Client pages/routerDirect gzip Size 306 B 306 B
Client pages/routerDirect Modern Size 411 B 411 B
Client pages/routerDirect gzip Modern Size 314 B 314 B
Client pages/withRouter Size 435 B 435 B
Client pages/withRouter gzip Size 301 B 300 B -1 B
Client pages/withRouter Modern Size 423 B 423 B
Client pages/withRouter gzip Modern Size 309 B 309 B
Client main Size 13.8 kB 14.7 kB ⚠️ +978 B
Client main gzip Size 4.88 kB 5.1 kB ⚠️ +225 B
Client main Modern Size 11.4 kB 11.7 kB ⚠️ +255 B
Client main Modern gzip Size 4.32 kB 4.38 kB ⚠️ +58 B
Client commons Size 194 kB 195 kB ⚠️ +1.37 kB
Client commons gzip Size 63.3 kB 63.6 kB ⚠️ +298 B
Client commons Modern Size 175 kB 176 kB ⚠️ +543 B
Client commons Modern gzip Size 57.3 kB 57.4 kB ⚠️ +120 B
Client webpack Size 1.53 kB 1.53 kB
Client webpack gzip Size 778 B 778 B
Client webpack Modern Size 1.53 kB 1.53 kB
Client webpack Modern gzip Size 785 B 785 B
Base Rendered Size 2.76 kB 2.76 kB
Build Dir Size 1.41 MB 1.43 MB ⚠️ +17.8 kB
Click to expand serverless stats ⚠️ Total Bundle Size Increase ⚠️
zeit/next.js canary ijjk/next.js add-apptree-ctx Change
Build Duration 22.1s 22s -61ms
node_modules Size 41.6 MB 41.6 MB -2.21 kB
Total Bundle (main, webpack, commons) Size 210 kB 213 kB ⚠️ +2.81 kB
Total Bundle (main, webpack, commons) gzip Size 69.3 kB 70 kB ⚠️ +684 B
Total Bundle (main, webpack, commons) Modern Size 187 kB 188 kB ⚠️ +798 B
Total Bundle (main, webpack, commons) Modern gzip Size 61.6 kB 61.8 kB ⚠️ +179 B
Client _app Size 1.9 kB 2.35 kB ⚠️ +455 B
Client _app gzip Size 913 B 1.07 kB ⚠️ +161 B
Client _app Modern Size 1.79 kB 1.79 kB
Client _app gzip Modern Size 880 B 880 B
Client _error Size 8.02 kB 8.22 kB ⚠️ +199 B
Client _error gzip Size 3.13 kB 3.16 kB ⚠️ +29 B
Client _error Modern Size 5.82 kB 5.85 kB ⚠️ +23 B
Client _error gzip Modern Size 2.35 kB 2.33 kB -13 B
Client pages/index Size 343 B 343 B
Client pages/index gzip Size 246 B 246 B
Client pages/index Modern Size 319 B 319 B
Client pages/index gzip Modern Size 254 B 254 B
Client pages/link Size 4.1 kB 4.18 kB ⚠️ +85 B
Client pages/link gzip Size 1.8 kB 1.82 kB ⚠️ +22 B
Client pages/link Modern Size 3.81 kB 3.81 kB
Client pages/link gzip Modern Size 1.72 kB 1.72 kB
Client pages/routerDirect Size 423 B 423 B
Client pages/routerDirect gzip Size 306 B 306 B
Client pages/routerDirect Modern Size 411 B 411 B
Client pages/routerDirect gzip Modern Size 314 B 314 B
Client pages/withRouter Size 435 B 435 B
Client pages/withRouter gzip Size 301 B 301 B
Client pages/withRouter Modern Size 423 B 423 B
Client pages/withRouter gzip Modern Size 309 B 309 B
Client main Size 13.8 kB 14.7 kB ⚠️ +978 B
Client main gzip Size 4.88 kB 5.1 kB ⚠️ +225 B
Client main Modern Size 11.4 kB 11.7 kB ⚠️ +255 B
Client main Modern gzip Size 4.32 kB 4.38 kB ⚠️ +59 B
Client commons Size 194 kB 195 kB ⚠️ +1.37 kB
Client commons gzip Size 63.3 kB 63.6 kB ⚠️ +298 B
Client commons Modern Size 175 kB 176 kB ⚠️ +543 B
Client commons Modern gzip Size 57.3 kB 57.4 kB ⚠️ +120 B
Client webpack Size 1.53 kB 1.53 kB
Client webpack gzip Size 778 B 778 B
Client webpack Modern Size 1.53 kB 1.53 kB
Client webpack Modern gzip Size 785 B 785 B
Serverless pages/link Size 255 kB 256 kB ⚠️ +1.59 kB
Serverless pages/link gzip Size 68.8 kB 68.9 kB ⚠️ +45 B
Serverless pages/index Size 247 kB 249 kB ⚠️ +1.59 kB
Serverless pages/index gzip Size 66.6 kB 66.6 kB -4 B
Serverless pages/_error Size 247 kB 248 kB ⚠️ +1.59 kB
Serverless pages/_error gzip Size 66.3 kB 66.4 kB ⚠️ +38 B
Serverless pages/routerDirect Size 248 kB 249 kB ⚠️ +1.59 kB
Serverless pages/routerDirect gzip Size 66.6 kB 66.6 kB ⚠️ +13 B
Serverless pages/withRouter Size 248 kB 249 kB ⚠️ +1.59 kB
Serverless pages/withRouter gzip Size 66.6 kB 66.7 kB ⚠️ +30 B
Build Dir Size 2.61 MB 2.64 MB ⚠️ +28.3 kB
Diff for main.js
@@ -1,5 +1,50 @@
 (window["webpackJsonp"] = window["webpackJsonp"] || []).push([[2],{
 
+/***/ "+oT+":
+/***/ (function(module, exports, __webpack_require__) {
+
+var _Promise = __webpack_require__("eVuF");
+
+function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
+  try {
+    var info = gen[key](arg);
+    var value = info.value;
+  } catch (error) {
+    reject(error);
+    return;
+  }
+
+  if (info.done) {
+    resolve(value);
+  } else {
+    _Promise.resolve(value).then(_next, _throw);
+  }
+}
+
+function _asyncToGenerator(fn) {
+  return function () {
+    var self = this,
+        args = arguments;
+    return new _Promise(function (resolve, reject) {
+      var gen = fn.apply(self, args);
+
+      function _next(value) {
+        asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
+      }
+
+      function _throw(err) {
+        asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
+      }
+
+      _next(undefined);
+    });
+  };
+}
+
+module.exports = _asyncToGenerator;
+
+/***/ }),
+
 /***/ "/h46":
 /***/ (function(module, exports, __webpack_require__) {
 
@@ -32,9 +77,11 @@ window.next = next;
 "use strict";
 
 
-var _classCallCheck = __webpack_require__("/HRN");
+var _interopRequireDefault2 = __webpack_require__("KI45");
+
+var _classCallCheck2 = _interopRequireDefault2(__webpack_require__("0iUn"));
 
-var _createClass = __webpack_require__("WaGi");
+var _createClass2 = _interopRequireDefault2(__webpack_require__("sLSF"));
 
 var _interopRequireDefault = __webpack_require__("KI45");
 
@@ -56,7 +103,7 @@ function () {
   function HeadManager() {
     var _this = this;
 
-    _classCallCheck(this, HeadManager);
+    (0, _classCallCheck2["default"])(this, HeadManager);
 
     this.updateHead = function (head) {
       var promise = _this.updatePromise = _promise["default"].resolve().then(function () {
@@ -70,7 +117,7 @@ function () {
     this.updatePromise = null;
   }
 
-  _createClass(HeadManager, [{
+  (0, _createClass2["default"])(HeadManager, [{
     key: "doUpdateHead",
     value: function doUpdateHead(head) {
       var _this2 = this;
@@ -104,9 +151,6 @@ function () {
     value: function updateElements(type, components) {
       var headEl = document.getElementsByTagName('head')[0];
       var headCountEl = headEl.querySelector('meta[name=next-head-count]');
-
-      if (false) {}
-
       var headCount = Number(headCountEl.content);
       var oldTags = [];
 
@@ -137,7 +181,6 @@ function () {
       headCountEl.content = (headCount - oldTags.length + newTags.length).toString();
     }
   }]);
-
   return HeadManager;
 }();
 
@@ -175,12 +218,13 @@ function reactElementToDOM(_ref) {
 "use strict";
 
 
-var _Object$defineProperty = __webpack_require__("hfKm");
+var _interopRequireDefault = __webpack_require__("KI45");
+
+var _defineProperty = _interopRequireDefault(__webpack_require__("hfKm"));
 
-_Object$defineProperty(exports, "__esModule", {
+(0, _defineProperty["default"])(exports, "__esModule", {
   value: true
 });
-
 var runtimeConfig;
 
 exports["default"] = function () {
@@ -201,9 +245,11 @@ exports.setConfig = setConfig;
 "use strict";
 
 
-var _Object$defineProperty = __webpack_require__("hfKm");
+var _interopRequireDefault = __webpack_require__("KI45");
 
-var __importStar = this && this.__importStar || function (mod) {
+var _defineProperty = _interopRequireDefault(__webpack_require__("hfKm"));
+
+var __importStar = void 0 && (void 0).__importStar || function (mod) {
   if (mod && mod.__esModule) return mod;
   var result = {};
   if (mod != null) for (var k in mod) {
@@ -213,7 +259,7 @@ var __importStar = this && this.__importStar || function (mod) {
   return result;
 };
 
-_Object$defineProperty(exports, "__esModule", {
+(0, _defineProperty["default"])(exports, "__esModule", {
   value: true
 });
 
@@ -229,19 +275,21 @@ exports.HeadManagerContext = React.createContext(null);
 "use strict";
 
 
-var _regeneratorRuntime = __webpack_require__("ln6h");
+var _interopRequireDefault2 = __webpack_require__("KI45");
+
+var _regenerator = _interopRequireDefault2(__webpack_require__("ln6h"));
 
-var _classCallCheck = __webpack_require__("/HRN");
+var _classCallCheck2 = _interopRequireDefault2(__webpack_require__("0iUn"));
 
-var _createClass = __webpack_require__("WaGi");
+var _createClass2 = _interopRequireDefault2(__webpack_require__("sLSF"));
 
-var _possibleConstructorReturn = __webpack_require__("ZDA2");
+var _possibleConstructorReturn2 = _interopRequireDefault2(__webpack_require__("MI3g"));
 
-var _getPrototypeOf = __webpack_require__("/+P4");
+var _getPrototypeOf2 = _interopRequireDefault2(__webpack_require__("a7VT"));
 
-var _inherits = __webpack_require__("N9n2");
+var _inherits2 = _interopRequireDefault2(__webpack_require__("Tit0"));
 
-var _slicedToArray = __webpack_require__("8+Nu");
+var _slicedToArray2 = _interopRequireDefault2(__webpack_require__("doui"));
 
 var _interopRequireWildcard = __webpack_require__("5Uuq");
 
@@ -325,7 +373,7 @@ var asPath = (0, _utils.getURL)();
 var pageLoader = new _pageLoader["default"](buildId, prefix);
 
 var register = function register(_ref) {
-  var _ref2 = _slicedToArray(_ref, 2),
+  var _ref2 = (0, _slicedToArray2["default"])(_ref, 2),
       r = _ref2[0],
       f = _ref2[1];
 
@@ -352,15 +400,14 @@ var App;
 var Container =
 /*#__PURE__*/
 function (_react$default$Compon) {
-  _inherits(Container, _react$default$Compon);
+  (0, _inherits2["default"])(Container, _react$default$Compon);
 
   function Container() {
-    _classCallCheck(this, Container);
-
-    return _possibleConstructorReturn(this, _getPrototypeOf(Container).apply(this, arguments));
+    (0, _classCallCheck2["default"])(this, Container);
+    return (0, _possibleConstructorReturn2["default"])(this, (0, _getPrototypeOf2["default"])(Container).apply(this, arguments));
   }
 
-  _createClass(Container, [{
+  (0, _createClass2["default"])(Container, [{
     key: "componentDidCatch",
     value: function componentDidCatch(err, info) {
       this.props.fn(err, info);
@@ -371,7 +418,7 @@ function (_react$default$Compon) {
       this.scrollToHash(); // If page was exported and has a querystring
       // If it's a dynamic route or has a querystring
 
-      if (data.nextExport && ((0, _isDynamic.isDynamicRoute)(router.pathname) || location.search || data.skeleton)) {
+      if (data.nextExport && ((0, _isDynamic.isDynamicRoute)(router.pathname) || location.search)) {
         // update query on mount for exported pages
         router.replace(router.pathname + '?' + (0, _querystring.stringify)((0, _extends2["default"])({}, router.query, (0, _querystring.parse)(location.search.substr(1)))), asPath, {
           // WARNING: `_h` is an internal option for handing Next.js
@@ -407,7 +454,6 @@ function (_react$default$Compon) {
       return this.props.children;
     }
   }]);
-
   return Container;
 }(_react["default"].Component);
 
@@ -419,10 +465,10 @@ var _default =
 function () {
   var _ref2 = (0, _asyncToGenerator2["default"])(
   /*#__PURE__*/
-  _regeneratorRuntime.mark(function _callee(_temp) {
-    var _ref, passedWebpackHMR, initialErr, _require, isValidElementType, renderCtx;
+  _regenerator["default"].mark(function _callee(_temp) {
+    var _ref, passedWebpackHMR, initialErr, _require, isValidElementType, renderCtx, appCtx;
 
-    return _regeneratorRuntime.wrap(function _callee$(_context) {
+    return _regenerator["default"].wrap(function _callee$(_context) {
       while (1) {
         switch (_context.prev = _context.next) {
           case 0:
@@ -507,9 +553,33 @@ function () {
               emitter: emitter
             };
             render(renderCtx);
+
+            if (!(window.__NEXT_DATA__.skeleton && Component.getInitialProps)) {
+              _context.next = 32;
+              break;
+            }
+
+            appCtx = {
+              router: router,
+              AppTree: wrapApp(App),
+              Component: Component,
+              ctx: {
+                pathname: page,
+                asPath: asPath,
+                query: query
+              }
+            };
+            _context.next = 30;
+            return App.getInitialProps(appCtx);
+
+          case 30:
+            props.pageProps = _context.sent.pageProps;
+            render(renderCtx);
+
+          case 32:
             return _context.abrupt("return", emitter);
 
-          case 27:
+          case 33:
           case "end":
             return _context.stop();
         }
@@ -534,8 +604,8 @@ function render(_x2) {
 function _render() {
   _render = (0, _asyncToGenerator2["default"])(
   /*#__PURE__*/
-  _regeneratorRuntime.mark(function _callee2(props) {
-    return _regeneratorRuntime.wrap(function _callee2$(_context2) {
+  _regenerator["default"].mark(function _callee2(props) {
+    return _regenerator["default"].wrap(function _callee2$(_context2) {
       while (1) {
         switch (_context2.prev = _context2.next) {
           case 0:
@@ -585,9 +655,9 @@ function renderError(_x3) {
 function _renderError() {
   _renderError = (0, _asyncToGenerator2["default"])(
   /*#__PURE__*/
-  _regeneratorRuntime.mark(function _callee3(props) {
-    var App, err, appCtx, initProps;
-    return _regeneratorRuntime.wrap(function _callee3$(_context3) {
+  _regenerator["default"].mark(function _callee3(props) {
+    var App, err, AppTree, appCtx, initProps;
+    return _regenerator["default"].wrap(function _callee3$(_context3) {
       while (1) {
         switch (_context3.prev = _context3.next) {
           case 0:
@@ -612,44 +682,46 @@ function _renderError() {
             // In production we do a normal render with the `ErrorComponent` as component.
             // If we've gotten here upon initial render, we can use the props from the server.
             // Otherwise, we need to call `getInitialProps` on `App` before mounting.
+            AppTree = wrapApp(App);
             appCtx = {
-              AppTree: wrapApp(App),
               Component: ErrorComponent,
+              AppTree: AppTree,
               router: router,
               ctx: {
                 err: err,
                 pathname: page,
                 query: query,
-                asPath: asPath
+                asPath: asPath,
+                AppTree: AppTree
               }
             };
 
             if (!props.props) {
-              _context3.next = 12;
+              _context3.next = 13;
               break;
             }
 
             _context3.t0 = props.props;
-            _context3.next = 15;
+            _context3.next = 16;
             break;
 
-          case 12:
-            _context3.next = 14;
+          case 13:
+            _context3.next = 15;
             return (0, _utils.loadGetInitialProps)(App, appCtx);
 
-          case 14:
+          case 15:
             _context3.t0 = _context3.sent;
 
-          case 15:
+          case 16:
             initProps = _context3.t0;
-            _context3.next = 18;
+            _context3.next = 19;
             return doRender((0, _extends2["default"])({}, props, {
               err: err,
               Component: ErrorComponent,
               props: initProps
             }));
 
-          case 18:
+          case 19:
           case "end":
             return _context3.stop();
         }
@@ -746,10 +818,10 @@ function doRender(_x4) {
 function _doRender() {
   _doRender = (0, _asyncToGenerator2["default"])(
   /*#__PURE__*/
-  _regeneratorRuntime.mark(function _callee4(_ref5) {
-    var App, Component, props, err, _router2, pathname, _query, _asPath, appCtx, appProps;
+  _regenerator["default"].mark(function _callee4(_ref5) {
+    var App, Component, props, err, _router2, pathname, _query, _asPath, AppTree, appCtx, appProps;
 
-    return _regeneratorRuntime.wrap(function _callee4$(_context4) {
+    return _regenerator["default"].wrap(function _callee4$(_context4) {
       while (1) {
         switch (_context4.prev = _context4.next) {
           case 0:
@@ -757,29 +829,31 @@ function _doRender() {
             // this is for when ErrorComponent gets replaced by Component by HMR
 
             if (!(!props && Component && Component !== ErrorComponent && lastAppProps.Component === ErrorComponent)) {
-              _context4.next = 7;
+              _context4.next = 8;
               break;
             }
 
             _router2 = router, pathname = _router2.pathname, _query = _router2.query, _asPath = _router2.asPath;
+            AppTree = wrapApp(App);
             appCtx = {
               router: router,
-              AppTree: wrapApp(App),
+              AppTree: AppTree,
               Component: ErrorComponent,
               ctx: {
                 err: err,
                 pathname: pathname,
                 query: _query,
-                asPath: _asPath
+                asPath: _asPath,
+                AppTree: AppTree
               }
             };
-            _context4.next = 6;
+            _context4.next = 7;
             return (0, _utils.loadGetInitialProps)(App, appCtx);
 
-          case 6:
+          case 7:
             props = _context4.sent;
 
-          case 7:
+          case 8:
             Component = Component || lastAppProps.Component;
             props = props || lastAppProps.props;
             appProps = (0, _extends2["default"])({}, props, {
@@ -802,7 +876,7 @@ function _doRender() {
               appProps: appProps
             });
 
-          case 14:
+          case 15:
           case "end":
             return _context4.stop();
         }
@@ -861,15 +935,17 @@ $export($export.P + $export.R, 'Map', { toJSON: __webpack_require__("8iia")('Map
 "use strict";
 
 
-var _Map = __webpack_require__("LX0d");
+var _interopRequireDefault = __webpack_require__("KI45");
+
+var _map = _interopRequireDefault(__webpack_require__("LX0d"));
 
-var _classCallCheck = __webpack_require__("/HRN");
+var _classCallCheck2 = _interopRequireDefault(__webpack_require__("0iUn"));
 
-var _createClass = __webpack_require__("WaGi");
+var _createClass2 = _interopRequireDefault(__webpack_require__("sLSF"));
 
-var _Object$defineProperty = __webpack_require__("hfKm");
+var _defineProperty = _interopRequireDefault(__webpack_require__("hfKm"));
 
-_Object$defineProperty(exports, "__esModule", {
+(0, _defineProperty["default"])(exports, "__esModule", {
   value: true
 });
 
@@ -877,12 +953,11 @@ var DataManager =
 /*#__PURE__*/
 function () {
   function DataManager(data) {
-    _classCallCheck(this, DataManager);
-
-    this.data = new _Map(data);
+    (0, _classCallCheck2["default"])(this, DataManager);
+    this.data = new _map["default"](data);
   }
 
-  _createClass(DataManager, [{
+  (0, _createClass2["default"])(DataManager, [{
     key: "getData",
     value: function getData() {
       return this.data;
@@ -900,10 +975,9 @@ function () {
   }, {
     key: "overwrite",
     value: function overwrite(data) {
-      this.data = new _Map(data);
+      this.data = new _map["default"](data);
     }
   }]);
-
   return DataManager;
 }();
 
@@ -953,9 +1027,11 @@ module.exports = __webpack_require__("raTm")(MAP, function (get) {
 "use strict";
 
 
-var _Object$defineProperty = __webpack_require__("hfKm");
+var _interopRequireDefault = __webpack_require__("KI45");
 
-var __importStar = this && this.__importStar || function (mod) {
+var _defineProperty = _interopRequireDefault(__webpack_require__("hfKm"));
+
+var __importStar = void 0 && (void 0).__importStar || function (mod) {
   if (mod && mod.__esModule) return mod;
   var result = {};
   if (mod != null) for (var k in mod) {
@@ -965,7 +1041,7 @@ var __importStar = this && this.__importStar || function (mod) {
   return result;
 };
 
-_Object$defineProperty(exports, "__esModule", {
+(0, _defineProperty["default"])(exports, "__esModule", {
   value: true
 });
 
@@ -981,11 +1057,13 @@ exports.DataManagerContext = React.createContext(null);
 "use strict";
 
 
-var _regeneratorRuntime = __webpack_require__("ln6h");
+var _interopRequireDefault2 = __webpack_require__("KI45");
+
+var _regenerator = _interopRequireDefault2(__webpack_require__("ln6h"));
 
-var _classCallCheck = __webpack_require__("/HRN");
+var _classCallCheck2 = _interopRequireDefault2(__webpack_require__("0iUn"));
 
-var _createClass = __webpack_require__("WaGi");
+var _createClass2 = _interopRequireDefault2(__webpack_require__("sLSF"));
 
 var _interopRequireDefault = __webpack_require__("KI45");
 
@@ -1025,8 +1103,7 @@ function () {
   function PageLoader(buildId, assetPrefix) {
     var _this3 = this;
 
-    _classCallCheck(this, PageLoader);
-
+    (0, _classCallCheck2["default"])(this, PageLoader);
     this.buildId = buildId;
     this.assetPrefix = assetPrefix;
     this.pageCache = {};
@@ -1040,7 +1117,7 @@ function () {
   } // Returns a promise for the dependencies for a particular route
 
 
-  _createClass(PageLoader, [{
+  (0, _createClass2["default"])(PageLoader, [{
     key: "getDependencies",
     value: function getDependencies(route) {
       return this.promisedBuildManifest.then(function (man) {
@@ -1117,9 +1194,9 @@ function () {
 
       return (0, _asyncToGenerator2["default"])(
       /*#__PURE__*/
-      _regeneratorRuntime.mark(function _callee() {
+      _regenerator["default"].mark(function _callee() {
         var scriptRoute, url;
-        return _regeneratorRuntime.wrap(function _callee$(_context) {
+        return _regenerator["default"].wrap(function _callee$(_context) {
           while (1) {
             switch (_context.prev = _context.next) {
               case 0:
@@ -1217,9 +1294,9 @@ function () {
 
       return (0, _asyncToGenerator2["default"])(
       /*#__PURE__*/
-      _regeneratorRuntime.mark(function _callee2() {
+      _regenerator["default"].mark(function _callee2() {
         var scriptRoute, url, cn;
-        return _regeneratorRuntime.wrap(function _callee2$(_context2) {
+        return _regenerator["default"].wrap(function _callee2$(_context2) {
           while (1) {
             switch (_context2.prev = _context2.next) {
               case 0:
@@ -1324,7 +1401,6 @@ function () {
       }))();
     }
   }]);
-
   return PageLoader;
 }();
 
Diff for commons.js
@@ -12,51 +12,6 @@ module.exports = __webpack_require__("WEpk").Symbol;
 
 /***/ }),
 
-/***/ "+oT+":
-/***/ (function(module, exports, __webpack_require__) {
-
-var _Promise = __webpack_require__("eVuF");
-
-function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
-  try {
-    var info = gen[key](arg);
-    var value = info.value;
-  } catch (error) {
-    reject(error);
-    return;
-  }
-
-  if (info.done) {
-    resolve(value);
-  } else {
-    _Promise.resolve(value).then(_next, _throw);
-  }
-}
-
-function _asyncToGenerator(fn) {
-  return function () {
-    var self = this,
-        args = arguments;
-    return new _Promise(function (resolve, reject) {
-      var gen = fn.apply(self, args);
-
-      function _next(value) {
-        asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
-      }
-
-      function _throw(err) {
-        asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
-      }
-
-      _next(undefined);
-    });
-  };
-}
-
-module.exports = _asyncToGenerator;
-
-/***/ }),
-
 /***/ "+plK":
 /***/ (function(module, exports, __webpack_require__) {
 
@@ -97,37 +52,6 @@ exports.unstable_shouldYield=function(){var a=exports.unstable_now();U(a);return
 
 /***/ }),
 
-/***/ "/+P4":
-/***/ (function(module, exports, __webpack_require__) {
-
-var _Object$getPrototypeOf = __webpack_require__("Bhuq");
-
-var _Object$setPrototypeOf = __webpack_require__("TRZx");
-
-function _getPrototypeOf(o) {
-  module.exports = _getPrototypeOf = _Object$setPrototypeOf ? _Object$getPrototypeOf : function _getPrototypeOf(o) {
-    return o.__proto__ || _Object$getPrototypeOf(o);
-  };
-  return _getPrototypeOf(o);
-}
-
-module.exports = _getPrototypeOf;
-
-/***/ }),
-
-/***/ "/HRN":
-/***/ (function(module, exports) {
-
-function _classCallCheck(instance, Constructor) {
-  if (!(instance instanceof Constructor)) {
-    throw new TypeError("Cannot call a class as a function");
-  }
-}
-
-module.exports = _classCallCheck;
-
-/***/ }),
-
 /***/ "/eQG":
 /***/ (function(module, exports, __webpack_require__) {
 
@@ -146,15 +70,17 @@ module.exports = function getOwnPropertyDescriptor(it, key) {
 "use strict";
 
 
-var _classCallCheck = __webpack_require__("/HRN");
+var _interopRequireDefault2 = __webpack_require__("KI45");
+
+var _classCallCheck2 = _interopRequireDefault2(__webpack_require__("0iUn"));
 
-var _createClass = __webpack_require__("WaGi");
+var _createClass2 = _interopRequireDefault2(__webpack_require__("sLSF"));
 
-var _possibleConstructorReturn = __webpack_require__("ZDA2");
+var _possibleConstructorReturn2 = _interopRequireDefault2(__webpack_require__("MI3g"));
 
-var _getPrototypeOf = __webpack_require__("/+P4");
+var _getPrototypeOf2 = _interopRequireDefault2(__webpack_require__("a7VT"));
 
-var _inherits = __webpack_require__("N9n2");
+var _inherits2 = _interopRequireDefault2(__webpack_require__("Tit0"));
 
 var _interopRequireDefault = __webpack_require__("KI45");
 
@@ -171,19 +97,18 @@ function withRouter(ComposedComponent) {
   var WithRouteWrapper =
   /*#__PURE__*/
   function (_react$default$Compon) {
-    _inherits(WithRouteWrapper, _react$default$Compon);
+    (0, _inherits2["default"])(WithRouteWrapper, _react$default$Compon);
 
     function WithRouteWrapper() {
       var _this;
 
-      _classCallCheck(this, WithRouteWrapper);
-
-      _this = _possibleConstructorReturn(this, _getPrototypeOf(WithRouteWrapper).apply(this, arguments));
+      (0, _classCallCheck2["default"])(this, WithRouteWrapper);
+      _this = (0, _possibleConstructorReturn2["default"])(this, (0, _getPrototypeOf2["default"])(WithRouteWrapper).apply(this, arguments));
       _this.context = void 0;
       return _this;
     }
 
-    _createClass(WithRouteWrapper, [{
+    (0, _createClass2["default"])(WithRouteWrapper, [{
       key: "render",
       value: function render() {
         return _react["default"].createElement(ComposedComponent, (0, _extends2["default"])({
@@ -191,7 +116,6 @@ function withRouter(ComposedComponent) {
         }, this.props));
       }
     }]);
-
     return WithRouteWrapper;
   }(_react["default"].Component);
 
@@ -209,6 +133,20 @@ function withRouter(ComposedComponent) {
 
 /***/ }),
 
+/***/ "0iUn":
+/***/ (function(module, __webpack_exports__, __webpack_require__) {
+
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return _classCallCheck; });
+function _classCallCheck(instance, Constructor) {
+  if (!(instance instanceof Constructor)) {
+    throw new TypeError("Cannot call a class as a function");
+  }
+}
+
+/***/ }),
+
 /***/ "16Al":
 /***/ (function(module, exports, __webpack_require__) {
 
@@ -490,11 +428,13 @@ var objectKeys = Object.keys || function (obj) {
 "use strict";
 
 
-var _Object$keys = __webpack_require__("pLtp");
+var _interopRequireDefault = __webpack_require__("KI45");
 
-var _Object$defineProperty = __webpack_require__("hfKm");
+var _keys = _interopRequireDefault(__webpack_require__("pLtp"));
+
+var _defineProperty = _interopRequireDefault(__webpack_require__("hfKm"));
 
-_Object$defineProperty(exports, "__esModule", {
+(0, _defineProperty["default"])(exports, "__esModule", {
   value: true
 });
 
@@ -509,15 +449,13 @@ function getRouteMatcher(routeRegex) {
     }
 
     var params = {};
-
-    _Object$keys(groups).forEach(function (slugName) {
+    (0, _keys["default"])(groups).forEach(function (slugName) {
       var m = routeMatch[groups[slugName]];
 
       if (m !== undefined) {
         params[slugName] = decodeURIComponent(m);
       }
     });
-
     return params;
   };
 }
@@ -709,9 +647,11 @@ module.exports = {
 "use strict";
 
 
-var _Object$defineProperty = __webpack_require__("hfKm");
+var _interopRequireDefault = __webpack_require__("KI45");
 
-_Object$defineProperty(exports, "__esModule", {
+var _defineProperty = _interopRequireDefault(__webpack_require__("hfKm"));
+
+(0, _defineProperty["default"])(exports, "__esModule", {
   value: true
 });
 
@@ -734,36 +674,6 @@ exports.getRouteRegex = getRouteRegex;
 
 /***/ }),
 
-/***/ "8+Nu":
-/***/ (function(module, exports, __webpack_require__) {
-
-var arrayWithHoles = __webpack_require__("8bdy");
-
-var iterableToArrayLimit = __webpack_require__("fprZ");
-
-var nonIterableRest = __webpack_require__("Bh1o");
-
-function _slicedToArray(arr, i) {
-  return arrayWithHoles(arr) || iterableToArrayLimit(arr, i) || nonIterableRest();
-}
-
-module.exports = _slicedToArray;
-
-/***/ }),
-
-/***/ "8bdy":
-/***/ (function(module, exports, __webpack_require__) {
-
-var _Array$isArray = __webpack_require__("p0XB");
-
-function _arrayWithHoles(arr) {
-  if (_Array$isArray(arr)) return arr;
-}
-
-module.exports = _arrayWithHoles;
-
-/***/ }),
-
 /***/ "8gHz":
 /***/ (function(module, exports, __webpack_require__) {
 
@@ -821,9 +731,11 @@ module.exports = __webpack_require__("WEpk").Array.isArray;
 "use strict";
 
 
-var _Object$defineProperty = __webpack_require__("hfKm");
+var _interopRequireDefault = __webpack_require__("KI45");
 
-var __importStar = this && this.__importStar || function (mod) {
+var _defineProperty = _interopRequireDefault(__webpack_require__("hfKm"));
+
+var __importStar = void 0 && (void 0).__importStar || function (mod) {
   if (mod && mod.__esModule) return mod;
   var result = {};
   if (mod != null) for (var k in mod) {
@@ -833,7 +745,7 @@ var __importStar = this && this.__importStar || function (mod) {
   return result;
 };
 
-_Object$defineProperty(exports, "__esModule", {
+(0, _defineProperty["default"])(exports, "__esModule", {
   value: true
 });
 
@@ -869,6 +781,22 @@ module.exports.f = function getOwnPropertyNames(it) {
 
 /***/ }),
 
+/***/ "AT/M":
+/***/ (function(module, __webpack_exports__, __webpack_require__) {
+
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return _assertThisInitialized; });
+function _assertThisInitialized(self) {
+  if (self === void 0) {
+    throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
+  }
+
+  return self;
+}
+
+/***/ }),
+
 /***/ "AUvm":
 /***/ (function(module, exports, __webpack_require__) {
 
@@ -1150,17 +1078,6 @@ module.exports = function (it, key) {
 
 /***/ }),
 
-/***/ "Bh1o":
-/***/ (function(module, exports) {
-
-function _nonIterableRest() {
-  throw new TypeError("Invalid attempt to destructure non-iterable instance");
-}
-
-module.exports = _nonIterableRest;
-
-/***/ }),
-
 /***/ "Bhuq":
 /***/ (function(module, exports, __webpack_require__) {
 
@@ -1174,15 +1091,17 @@ module.exports = __webpack_require__("+plK");
 "use strict";
 
 
-var _regeneratorRuntime = __webpack_require__("ln6h");
+var _interopRequireDefault = __webpack_require__("KI45");
+
+var _regenerator = _interopRequireDefault(__webpack_require__("ln6h"));
 
-var _Object$keys = __webpack_require__("pLtp");
+var _keys = _interopRequireDefault(__webpack_require__("pLtp"));
 
-var _asyncToGenerator = __webpack_require__("+oT+");
+var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__("O40h"));
 
-var _Object$defineProperty = __webpack_require__("hfKm");
+var _defineProperty = _interopRequireDefault(__webpack_require__("hfKm"));
 
-_Object$defineProperty(exports, "__esModule", {
+(0, _defineProperty["default"])(exports, "__esModule", {
   value: true
 });
 
@@ -1246,12 +1165,12 @@ function loadGetInitialProps(_x, _x2) {
 }
 
 function _loadGetInitialProps() {
-  _loadGetInitialProps = _asyncToGenerator(
+  _loadGetInitialProps = (0, _asyncToGenerator2["default"])(
   /*#__PURE__*/
-  _regeneratorRuntime.mark(function _callee(Component, ctx) {
+  _regenerator["default"].mark(function _callee(Component, ctx) {
     var message, res, props, _message;
 
-    return _regeneratorRuntime.wrap(function _callee$(_context) {
+    return _regenerator["default"].wrap(function _callee$(_context) {
       while (1) {
         switch (_context.prev = _context.next) {
           case 0:
@@ -3048,29 +2967,31 @@ $export($export.S + $export.F * !(USE_NATIVE && __webpack_require__("TuGD")(func
 "use strict";
 
 
-var _regeneratorRuntime = __webpack_require__("ln6h");
+var _interopRequireDefault = __webpack_require__("KI45");
+
+var _regenerator = _interopRequireDefault(__webpack_require__("ln6h"));
 
-var _asyncToGenerator = __webpack_require__("+oT+");
+var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__("O40h"));
 
-var _slicedToArray = __webpack_require__("8+Nu");
+var _slicedToArray2 = _interopRequireDefault(__webpack_require__("doui"));
 
-var _Promise = __webpack_require__("eVuF");
+var _promise = _interopRequireDefault(__webpack_require__("eVuF"));
 
-var _Object$assign = __webpack_require__("UXZV");
+var _assign = _interopRequireDefault(__webpack_require__("UXZV"));
 
-var _classCallCheck = __webpack_require__("/HRN");
+var _classCallCheck2 = _interopRequireDefault(__webpack_require__("0iUn"));
 
-var _createClass = __webpack_require__("WaGi");
+var _createClass2 = _interopRequireDefault(__webpack_require__("sLSF"));
 
-var _Object$defineProperty = __webpack_require__("hfKm");
+var _defineProperty = _interopRequireDefault(__webpack_require__("hfKm"));
 
-var __importDefault = this && this.__importDefault || function (mod) {
+var __importDefault = void 0 && (void 0).__importDefault || function (mod) {
   return mod && mod.__esModule ? mod : {
     "default": mod
   };
 };
 
-_Object$defineProperty(exports, "__esModule", {
+(0, _defineProperty["default"])(exports, "__esModule", {
   value: true
 });
 
@@ -3105,8 +3026,7 @@ function () {
         Component = _ref.Component,
         err = _ref.err,
         subscription = _ref.subscription;
-
-    _classCallCheck(this, Router);
+    (0, _classCallCheck2["default"])(this, Router);
 
     this.onPopState = function (e) {
       if (!e.state) {
@@ -3199,7 +3119,7 @@ function () {
               _as2 = _history$state.as,
               options = _history$state.options;
 
-          _this.changeState('replaceState', url, _as2, _Object$assign({}, options, {
+          _this.changeState('replaceState', url, _as2, (0, _assign["default"])({}, options, {
             fromExternal: true
           }));
         }
@@ -3208,7 +3128,7 @@ function () {
   } // @deprecated backwards compatibility even though it's a private method.
 
 
-  _createClass(Router, [{
+  (0, _createClass2["default"])(Router, [{
     key: "update",
     value: function update(route, Component) {
       var data = this.components[route];
@@ -3217,10 +3137,9 @@ function () {
         throw new Error("Cannot update unavailable route: ".concat(route));
       }
 
-      var newData = _Object$assign({}, data, {
+      var newData = (0, _assign["default"])({}, data, {
         Component: Component
       });
-
       this.components[route] = newData; // pages/_app.js updated
 
       if (route === '/_app') {
@@ -3279,7 +3198,7 @@ function () {
     value: function change(method, _url, _as, options) {
       var _this2 = this;
 
-      return new _Promise(function (resolve, reject) {
+      return new _promise["default"](function (resolve, reject) {
         // marking route changes as a navigation start entry
         if (utils_1.SUPPORTS_PERFORMANCE_USER_TIMING) {
           performance.mark('routeChange');
@@ -3350,7 +3269,7 @@ function () {
           } // Merge params into `query`, overwriting any specified in search
 
 
-          _Object$assign(query, routeMatch);
+          (0, _assign["default"])(query, routeMatch);
         }
 
         Router.events.emit('routeChangeStart', as); // If shallow is true and the route exists in the router cache we reuse the previous result
@@ -3372,7 +3291,7 @@ function () {
           if (false) { var appComp; } // @ts-ignore pathname is always defined
 
 
-          _this2.set(route, pathname, query, as, _Object$assign({}, routeInfo, {
+          _this2.set(route, pathname, query, as, (0, _assign["default"])({}, routeInfo, {
             hash: hash
           }));
 
@@ -3412,10 +3331,10 @@ function () {
       // If the route is already rendered on the screen.
 
       if (shallow && cachedRouteInfo && this.route === route) {
-        return _Promise.resolve(cachedRouteInfo);
+        return _promise["default"].resolve(cachedRouteInfo);
       }
 
-      return new _Promise(function (resolve, reject) {
+      return new _promise["default"](function (resolve, reject) {
         if (cachedRouteInfo) {
           return resolve(cachedRouteInfo);
         }
@@ -3430,21 +3349,20 @@ function () {
 
         if (false) { var _require, isValidElementType; }
 
-        return new _Promise(function (resolve, reject) {
-          var ctx = {
+        return new _promise["default"](function (resolve, reject) {
+          // we provide AppTree later so this needs to be `any`
+          _this3.getInitialProps(Component, {
             pathname: pathname,
             query: query,
             asPath: as
-          };
-
-          _this3.getInitialProps(Component, ctx).then(function (props) {
+          }).then(function (props) {
             routeInfo.props = props;
             _this3.components[route] = routeInfo;
             resolve(routeInfo);
           }, reject);
         });
       })["catch"](function (err) {
-        return new _Promise(function (resolve) {
+        return new _promise["default"](function (resolve) {
           if (err.code === 'PAGE_LOAD_ERROR') {
             // If we can't load the page it could be one of following reasons
             //  1. Page doesn't exists
@@ -3473,13 +3391,12 @@ function () {
               Component: Component,
               err: err
             };
-            var ctx = {
-              err: err,
-              pathname: pathname,
-              query: query
-            };
-            return new _Promise(function (resolve) {
-              _this3.getInitialProps(Component, ctx).then(function (props) {
+            return new _promise["default"](function (resolve) {
+              _this3.getInitialProps(Component, {
+                err: err,
+                pathname: pathname,
+                query: query
+              }).then(function (props) {
                 routeInfo.props = props;
                 routeInfo.error = err;
                 resolve(routeInfo);
@@ -3519,12 +3436,12 @@ function () {
       if (!this.asPath) return false;
 
       var _this$asPath$split = this.asPath.split('#'),
-          _this$asPath$split2 = _slicedToArray(_this$asPath$split, 2),
+          _this$asPath$split2 = (0, _slicedToArray2["default"])(_this$asPath$split, 2),
           oldUrlNoHash = _this$asPath$split2[0],
           oldHash = _this$asPath$split2[1];
 
       var _as$split = as.split('#'),
-          _as$split2 = _slicedToArray(_as$split, 2),
+          _as$split2 = (0, _slicedToArray2["default"])(_as$split, 2),
           newUrlNoHash = _as$split2[0],
           newHash = _as$split2[1]; // Makes sure we scroll to the provided hash if the url/hash are the same
 
@@ -3548,7 +3465,7 @@ function () {
     key: "scrollToHash",
     value: function scrollToHash(as) {
       var _as$split3 = as.split('#'),
-          _as$split4 = _slicedToArray(_as$split3, 2),
+          _as$split4 = (0, _slicedToArray2["default"])(_as$split3, 2),
           hash = _as$split4[1]; // Scroll to top if the hash is just `#` with no value
 
 
@@ -3589,7 +3506,7 @@ function () {
     value: function prefetch(url) {
       var _this4 = this;
 
-      return new _Promise(function (resolve, reject) {
+      return new _promise["default"](function (resolve, reject) {
         var _url_1$parse3 = url_1.parse(url),
             pathname = _url_1$parse3.pathname,
             protocol = _url_1$parse3.protocol;
@@ -3611,11 +3528,11 @@ function () {
   }, {
     key: "fetchComponent",
     value: function () {
-      var _fetchComponent = _asyncToGenerator(
+      var _fetchComponent = (0, _asyncToGenerator2["default"])(
       /*#__PURE__*/
-      _regeneratorRuntime.mark(function _callee(route) {
+      _regenerator["default"].mark(function _callee(route) {
         var cancelled, cancel, Component, error;
-        return _regeneratorRuntime.wrap(function _callee$(_context) {
+        return _regenerator["default"].wrap(function _callee$(_context) {
           while (1) {
             switch (_context.prev = _context.next) {
               case 0:
@@ -3664,11 +3581,11 @@ function () {
   }, {
     key: "getInitialProps",
     value: function () {
-      var _getInitialProps = _asyncToGenerator(
+      var _getInitialProps = (0, _asyncToGenerator2["default"])(
       /*#__PURE__*/
-      _regeneratorRuntime.mark(function _callee2(Component, ctx) {
-        var cancelled, cancel, App, props, status, url, err;
-        return _regeneratorRuntime.wrap(function _callee2$(_context2) {
+      _regenerator["default"].mark(function _callee2(Component, ctx) {
+        var cancelled, cancel, App, props, url, res, AppTree, err;
+        return _regenerator["default"].wrap(function _callee2$(_context2) {
           while (1) {
             switch (_context2.prev = _context2.next) {
               case 0:
@@ -3681,14 +3598,13 @@ function () {
                 this.clc = cancel;
                 App = this.components['/_app'].Component;
 
-                if (!( // @ts-ignore workaround for dead-code elimination
-                (self.__HAS_SPR || "production" !== 'production') && Component.__NEXT_SPR)) {
-                  _context2.next = 11;
+                if (!Component.__NEXT_PRERENDER) {
+                  _context2.next = 20;
                   break;
                 }
 
-                url = ctx.asPath ? ctx.asPath : url_1.format({
-                  pathname: ctx.pathname,
+                url = url_1.format({
+                  pathname: ctx.asPath,
                   query: ctx.query
                 });
                 _context2.next = 8;
@@ -3696,48 +3612,63 @@ function () {
                   headers: {
                     'content-type': 'application/json'
                   }
-                }).then(function (res) {
-                  if (!res.ok) {
-                    status = res.status;
-                    throw new Error('failed to load prerender data');
-                  }
+                });
 
-                  return res.json();
-                }).then(function (pageProps) {
-                  return {
-                    pageProps: pageProps
-                  };
-                })["catch"](function (err) {
+              case 8:
+                res = _context2.sent;
+
+                if (!res.ok) {
+                  _context2.next = 15;
+                  break;
+                }
+
+                _context2.next = 12;
+                return res.json()["catch"](function (err) {
                   return {
-                    error: err.message,
-                    status: status
+                    error: err.message
                   };
                 });
 
-              case 8:
-                props = _context2.sent;
-                _context2.next = 14;
+              case 12:
+                _context2.t0 = _context2.sent;
+                _context2.next = 16;
                 break;
 
-              case 11:
-                _context2.next = 13;
+              case 15:
+                _context2.t0 = {
+                  error: 'failed to load prerender',
+                  statusCode: res.status
+                };
+
+              case 16:
+                _context2.t1 = _context2.t0;
+                props = {
+                  pageProps: _context2.t1
+                };
+                _context2.next = 25;
+                break;
+
+              case 20:
+                AppTree = this._wrapApp(App);
+                ctx.AppTree = AppTree;
+                _context2.next = 24;
                 return utils_1.loadGetInitialProps(App, {
-                  AppTree: this._wrapApp(App),
+                  AppTree: AppTree,
                   Component: Component,
                   router: this,
                   ctx: ctx
                 });
 
-              case 13:
+              case 24:
                 props = _context2.sent;
 
-              case 14:
+              case 25:
                 if (cancel === this.clc) {
                   this.clc = null;
                 }
 
                 if (!cancelled) {
-                  _context2.next = 19;
+                  _context2.next = 30;
                   break;
                 }
 
@@ -3745,10 +3676,10 @@ function () {
                 err.cancelled = true;
                 throw err;
 
-              case 19:
+              case 30:
                 return _context2.abrupt("return", props);
 
-              case 20:
+              case 31:
               case "end":
                 return _context2.stop();
             }
@@ -3784,7 +3715,6 @@ function () {
       return rewrite_url_for_export_1.rewriteUrlForNextExport(url);
     }
   }]);
-
   return Router;
 }();
 
@@ -3821,44 +3751,31 @@ module.exports = __webpack_require__("/eQG");
 
 /***/ }),
 
-/***/ "K47E":
-/***/ (function(module, exports) {
-
-function _assertThisInitialized(self) {
-  if (self === void 0) {
-    throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
-  }
-
-  return self;
-}
-
-module.exports = _assertThisInitialized;
-
-/***/ }),
-
 /***/ "KA3u":
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
-var _slicedToArray = __webpack_require__("8+Nu");
+var _interopRequireDefault = __webpack_require__("KI45");
 
-var _Object$defineProperty = __webpack_require__("hfKm");
+var _slicedToArray2 = _interopRequireDefault(__webpack_require__("doui"));
 
-_Object$defineProperty(exports, "__esModule", {
+var _defineProperty = _interopRequireDefault(__webpack_require__("hfKm"));
+
+(0, _defineProperty["default"])(exports, "__esModule", {
   value: true
 });
 
 function rewriteUrlForNextExport(url) {
   var _url$split = url.split('#'),
-      _url$split2 = _slicedToArray(_url$split, 2),
+      _url$split2 = (0, _slicedToArray2["default"])(_url$split, 2),
       pathname = _url$split2[0],
       hash = _url$split2[1]; // tslint:disable-next-line
 
 
   var _pathname$split = pathname.split('?'),
-      _pathname$split2 = _slicedToArray(_pathname$split, 2),
+      _pathname$split2 = (0, _slicedToArray2["default"])(_pathname$split, 2),
       path = _pathname$split2[0],
       qs = _pathname$split2[1];
 
@@ -3937,6 +3854,56 @@ module.exports = function (fn, args, that) {
 
 /***/ }),
 
+/***/ "MI3g":
+/***/ (function(module, __webpack_exports__, __webpack_require__) {
+
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+
+// EXTERNAL MODULE: ./node_modules/@babel/runtime-corejs2/core-js/symbol/iterator.js
+var iterator = __webpack_require__("XVgq");
+var iterator_default = /*#__PURE__*/__webpack_require__.n(iterator);
+
+// EXTERNAL MODULE: ./node_modules/@babel/runtime-corejs2/core-js/symbol.js
+var symbol = __webpack_require__("Z7t5");
+var symbol_default = /*#__PURE__*/__webpack_require__.n(symbol);
+
+// CONCATENATED MODULE: ./node_modules/@babel/runtime-corejs2/helpers/esm/typeof.js
+
+
+
+function typeof_typeof2(obj) { if (typeof symbol_default.a === "function" && typeof iterator_default.a === "symbol") { typeof_typeof2 = function _typeof2(obj) { return typeof obj; }; } else { typeof_typeof2 = function _typeof2(obj) { return obj && typeof symbol_default.a === "function" && obj.constructor === symbol_default.a && obj !== symbol_default.a.prototype ? "symbol" : typeof obj; }; } return typeof_typeof2(obj); }
+
+function typeof_typeof(obj) {
+  if (typeof symbol_default.a === "function" && typeof_typeof2(iterator_default.a) === "symbol") {
+    typeof_typeof = function _typeof(obj) {
+      return typeof_typeof2(obj);
+    };
+  } else {
+    typeof_typeof = function _typeof(obj) {
+      return obj && typeof symbol_default.a === "function" && obj.constructor === symbol_default.a && obj !== symbol_default.a.prototype ? "symbol" : typeof_typeof2(obj);
+    };
+  }
+
+  return typeof_typeof(obj);
+}
+// EXTERNAL MODULE: ./node_modules/@babel/runtime-corejs2/helpers/esm/assertThisInitialized.js
+var assertThisInitialized = __webpack_require__("AT/M");
+
+// CONCATENATED MODULE: ./node_modules/@babel/runtime-corejs2/helpers/esm/possibleConstructorReturn.js
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return _possibleConstructorReturn; });
+
+
+function _possibleConstructorReturn(self, call) {
+  if (call && (typeof_typeof(call) === "object" || typeof call === "function")) {
+    return call;
+  }
+
+  return Object(assertThisInitialized["default"])(self);
+}
+
+/***/ }),
+
 /***/ "MPFp":
 /***/ (function(module, exports, __webpack_require__) {
 
@@ -4137,32 +4104,6 @@ module.exports = document && document.documentElement;
 
 /***/ }),
 
-/***/ "N9n2":
-/***/ (function(module, exports, __webpack_require__) {
-
-var _Object$create = __webpack_require__("SqZg");
-
-var setPrototypeOf = __webpack_require__("vjea");
-
-function _inherits(subClass, superClass) {
-  if (typeof superClass !== "function" && superClass !== null) {
-    throw new TypeError("Super expression must either be null or a function");
-  }
-
-  subClass.prototype = _Object$create(superClass && superClass.prototype, {
-    constructor: {
-      value: subClass,
-      writable: true,
-      configurable: true
-    }
-  });
-  if (superClass) setPrototypeOf(subClass, superClass);
-}
-
-module.exports = _inherits;
-
-/***/ }),
-
 /***/ "NV0k":
 /***/ (function(module, exports) {
 
@@ -4238,24 +4179,72 @@ module.exports = function (it) {
 
 /***/ }),
 
-/***/ "Ojgd":
-/***/ (function(module, exports) {
-
-// 7.1.4 ToInteger
-var ceil = Math.ceil;
-var floor = Math.floor;
-module.exports = function (it) {
-  return isNaN(it = +it) ? 0 : (it > 0 ? floor : ceil)(it);
-};
+/***/ "O40h":
+/***/ (function(module, __webpack_exports__, __webpack_require__) {
 
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return _asyncToGenerator; });
+/* harmony import */ var _core_js_promise__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("eVuF");
+/* harmony import */ var _core_js_promise__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_core_js_promise__WEBPACK_IMPORTED_MODULE_0__);
 
-/***/ }),
 
-/***/ "PBE1":
-/***/ (function(module, exports, __webpack_require__) {
+function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
+  try {
+    var info = gen[key](arg);
+    var value = info.value;
+  } catch (error) {
+    reject(error);
+    return;
+  }
 
-"use strict";
-// https://github.com/tc39/proposal-promise-finally
+  if (info.done) {
+    resolve(value);
+  } else {
+    _core_js_promise__WEBPACK_IMPORTED_MODULE_0___default.a.resolve(value).then(_next, _throw);
+  }
+}
+
+function _asyncToGenerator(fn) {
+  return function () {
+    var self = this,
+        args = arguments;
+    return new _core_js_promise__WEBPACK_IMPORTED_MODULE_0___default.a(function (resolve, reject) {
+      var gen = fn.apply(self, args);
+
+      function _next(value) {
+        asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
+      }
+
+      function _throw(err) {
+        asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
+      }
+
+      _next(undefined);
+    });
+  };
+}
+
+/***/ }),
+
+/***/ "Ojgd":
+/***/ (function(module, exports) {
+
+// 7.1.4 ToInteger
+var ceil = Math.ceil;
+var floor = Math.floor;
+module.exports = function (it) {
+  return isNaN(it = +it) ? 0 : (it > 0 ? floor : ceil)(it);
+};
+
+
+/***/ }),
+
+/***/ "PBE1":
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+// https://github.com/tc39/proposal-promise-finally
 
 var $export = __webpack_require__("Y7ZC");
 var core = __webpack_require__("WEpk");
@@ -4573,6 +4562,34 @@ module.exports = __webpack_require__("JbBM");
 
 /***/ }),
 
+/***/ "Tit0":
+/***/ (function(module, __webpack_exports__, __webpack_require__) {
+
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return _inherits; });
+/* harmony import */ var _core_js_object_create__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("SqZg");
+/* harmony import */ var _core_js_object_create__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_core_js_object_create__WEBPACK_IMPORTED_MODULE_0__);
+/* harmony import */ var _setPrototypeOf__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("VLay");
+
+
+function _inherits(subClass, superClass) {
+  if (typeof superClass !== "function" && superClass !== null) {
+    throw new TypeError("Super expression must either be null or a function");
+  }
+
+  subClass.prototype = _core_js_object_create__WEBPACK_IMPORTED_MODULE_0___default()(superClass && superClass.prototype, {
+    constructor: {
+      value: subClass,
+      writable: true,
+      configurable: true
+    }
+  });
+  if (superClass) Object(_setPrototypeOf__WEBPACK_IMPORTED_MODULE_1__[/* default */ "a"])(subClass, superClass);
+}
+
+/***/ }),
+
 /***/ "TuGD":
 /***/ (function(module, exports, __webpack_require__) {
 
@@ -4717,6 +4734,25 @@ module.exports = function (TYPE, $create) {
 
 /***/ }),
 
+/***/ "VLay":
+/***/ (function(module, __webpack_exports__, __webpack_require__) {
+
+"use strict";
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return _setPrototypeOf; });
+/* harmony import */ var _core_js_object_set_prototype_of__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("TRZx");
+/* harmony import */ var _core_js_object_set_prototype_of__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_core_js_object_set_prototype_of__WEBPACK_IMPORTED_MODULE_0__);
+
+function _setPrototypeOf(o, p) {
+  _setPrototypeOf = _core_js_object_set_prototype_of__WEBPACK_IMPORTED_MODULE_0___default.a || function _setPrototypeOf(o, p) {
+    o.__proto__ = p;
+    return o;
+  };
+
+  return _setPrototypeOf(o, p);
+}
+
+/***/ }),
+
 /***/ "VVlx":
 /***/ (function(module, exports, __webpack_require__) {
 
@@ -4768,32 +4804,6 @@ if (typeof __e == 'number') __e = core; // eslint-disable-line no-undef
 
 /***/ }),
 
-/***/ "WaGi":
-/***/ (function(module, exports, __webpack_require__) {
-
-var _Object$defineProperty = __webpack_require__("hfKm");
-
-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;
-}
-
-module.exports = _createClass;
-
-/***/ }),
-
 /***/ "WbBG":
 /***/ (function(module, exports, __webpack_require__) {
 
@@ -5111,25 +5121,6 @@ module.exports = __webpack_require__("+SFK");
 
 /***/ }),
 
-/***/ "ZDA2":
-/***/ (function(module, exports, __webpack_require__) {
-
-var _typeof = __webpack_require__("iZP3");
-
-var assertThisInitialized = __webpack_require__("K47E");
-
-function _possibleConstructorReturn(self, call) {
-  if (call && (_typeof(call) === "object" || typeof call === "function")) {
-    return call;
-  }
-
-  return assertThisInitialized(self);
-}
-
-module.exports = _possibleConstructorReturn;
-
-/***/ }),
-
 /***/ "ZW5q":
 /***/ (function(module, exports, __webpack_require__) {
 
@@ -5184,6 +5175,27 @@ module.exports = function (it) {
 
 /***/ }),
 
+/***/ "a7VT":
+/***/ (function(module, __webpack_exports__, __webpack_require__) {
+
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return _getPrototypeOf; });
+/* harmony import */ var _core_js_object_get_prototype_of__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("Bhuq");
+/* harmony import */ var _core_js_object_get_prototype_of__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_core_js_object_get_prototype_of__WEBPACK_IMPORTED_MODULE_0__);
+/* harmony import */ var _core_js_object_set_prototype_of__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("TRZx");
+/* harmony import */ var _core_js_object_set_prototype_of__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_core_js_object_set_prototype_of__WEBPACK_IMPORTED_MODULE_1__);
+
+
+function _getPrototypeOf(o) {
+  _getPrototypeOf = _core_js_object_set_prototype_of__WEBPACK_IMPORTED_MODULE_1___default.a ? _core_js_object_get_prototype_of__WEBPACK_IMPORTED_MODULE_0___default.a : function _getPrototypeOf(o) {
+    return o.__proto__ || _core_js_object_get_prototype_of__WEBPACK_IMPORTED_MODULE_0___default()(o);
+  };
+  return _getPrototypeOf(o);
+}
+
+/***/ }),
+
 /***/ "aPfg":
 /***/ (function(module, exports, __webpack_require__) {
 
@@ -5256,47 +5268,6 @@ exports.f = Object.getOwnPropertyNames || function getOwnPropertyNames(O) {
 
 /***/ }),
 
-/***/ "b3CU":
-/***/ (function(module, exports, __webpack_require__) {
-
-var _Reflect$construct = __webpack_require__("pbKT");
-
-var setPrototypeOf = __webpack_require__("vjea");
-
-function isNativeReflectConstruct() {
-  if (typeof Reflect === "undefined" || !_Reflect$construct) return false;
-  if (_Reflect$construct.sham) return false;
-  if (typeof Proxy === "function") return true;
-
-  try {
-    Date.prototype.toString.call(_Reflect$construct(Date, [], function () {}));
-    return true;
-  } catch (e) {
-    return false;
-  }
-}
-
-function _construct(Parent, args, Class) {
-  if (isNativeReflectConstruct()) {
-    module.exports = _construct = _Reflect$construct;
-  } else {
-    module.exports = _construct = function _construct(Parent, args, Class) {
-      var a = [null];
-      a.push.apply(a, args);
-      var Constructor = Function.bind.apply(Parent, a);
-      var instance = new Constructor();
-      if (Class) setPrototypeOf(instance, Class.prototype);
-      return instance;
-    };
-  }
-
-  return _construct.apply(null, arguments);
-}
-
-module.exports = _construct;
-
-/***/ }),
-
 /***/ "bBy9":
 /***/ (function(module, exports, __webpack_require__) {
 
@@ -5429,6 +5400,67 @@ __webpack_require__("Zxgi")('observable');
 
 /***/ }),
 
+/***/ "doui":
+/***/ (function(module, __webpack_exports__, __webpack_require__) {
+
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+
+// EXTERNAL MODULE: ./node_modules/@babel/runtime-corejs2/core-js/array/is-array.js
+var is_array = __webpack_require__("p0XB");
+var is_array_default = /*#__PURE__*/__webpack_require__.n(is_array);
+
+// CONCATENATED MODULE: ./node_modules/@babel/runtime-corejs2/helpers/esm/arrayWithHoles.js
+
+function _arrayWithHoles(arr) {
+  if (is_array_default()(arr)) return arr;
+}
+// EXTERNAL MODULE: ./node_modules/@babel/runtime-corejs2/core-js/get-iterator.js
+var get_iterator = __webpack_require__("XXOK");
+var get_iterator_default = /*#__PURE__*/__webpack_require__.n(get_iterator);
+
+// CONCATENATED MODULE: ./node_modules/@babel/runtime-corejs2/helpers/esm/iterableToArrayLimit.js
+
+function _iterableToArrayLimit(arr, i) {
+  var _arr = [];
+  var _n = true;
+  var _d = false;
+  var _e = undefined;
+
+  try {
+    for (var _i = get_iterator_default()(arr), _s; !(_n = (_s = _i.next()).done); _n = true) {
+      _arr.push(_s.value);
+
+      if (i && _arr.length === i) break;
+    }
+  } catch (err) {
+    _d = true;
+    _e = err;
+  } finally {
+    try {
+      if (!_n && _i["return"] != null) _i["return"]();
+    } finally {
+      if (_d) throw _e;
+    }
+  }
+
+  return _arr;
+}
+// CONCATENATED MODULE: ./node_modules/@babel/runtime-corejs2/helpers/esm/nonIterableRest.js
+function _nonIterableRest() {
+  throw new TypeError("Invalid attempt to destructure non-iterable instance");
+}
+// CONCATENATED MODULE: ./node_modules/@babel/runtime-corejs2/helpers/esm/slicedToArray.js
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return _slicedToArray; });
+
+
+
+function _slicedToArray(arr, i) {
+  return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest();
+}
+
+/***/ }),
+
 /***/ "eUtF":
 /***/ (function(module, exports, __webpack_require__) {
 
@@ -5506,41 +5538,6 @@ module.exports = __webpack_require__("jmDH") ? Object.defineProperties : functio
 
 /***/ }),
 
-/***/ "fprZ":
-/***/ (function(module, exports, __webpack_require__) {
-
-var _getIterator = __webpack_require__("XXOK");
-
-function _iterableToArrayLimit(arr, i) {
-  var _arr = [];
-  var _n = true;
-  var _d = false;
-  var _e = undefined;
-
-  try {
-    for (var _i = _getIterator(arr), _s; !(_n = (_s = _i.next()).done); _n = true) {
-      _arr.push(_s.value);
-
-      if (i && _arr.length === i) break;
-    }
-  } catch (err) {
-    _d = true;
-    _e = err;
-  } finally {
-    try {
-      if (!_n && _i["return"] != null) _i["return"]();
-    } finally {
-      if (_d) throw _e;
-    }
-  }
-
-  return _arr;
-}
-
-module.exports = _iterableToArrayLimit;
-
-/***/ }),
-
 /***/ "hDam":
 /***/ (function(module, exports) {
 
@@ -5618,33 +5615,6 @@ if (true) {
 
 /***/ }),
 
-/***/ "iZP3":
-/***/ (function(module, exports, __webpack_require__) {
-
-var _Symbol$iterator = __webpack_require__("XVgq");
-
-var _Symbol = __webpack_require__("Z7t5");
-
-function _typeof2(obj) { if (typeof _Symbol === "function" && typeof _Symbol$iterator === "symbol") { _typeof2 = function _typeof2(obj) { return typeof obj; }; } else { _typeof2 = function _typeof2(obj) { return obj && typeof _Symbol === "function" && obj.constructor === _Symbol && obj !== _Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof2(obj); }
-
-function _typeof(obj) {
-  if (typeof _Symbol === "function" && _typeof2(_Symbol$iterator) === "symbol") {
-    module.exports = _typeof = function _typeof(obj) {
-      return _typeof2(obj);
-    };
-  } else {
-    module.exports = _typeof = function _typeof(obj) {
-      return obj && typeof _Symbol === "function" && obj.constructor === _Symbol && obj !== _Symbol.prototype ? "symbol" : _typeof2(obj);
-    };
-  }
-
-  return _typeof(obj);
-}
-
-module.exports = _typeof;
-
-/***/ }),
-
 /***/ "iq4v":
 /***/ (function(module, exports, __webpack_require__) {
 
@@ -5712,13 +5682,14 @@ module.exports = __webpack_require__("NegM");
 "use strict";
 
 
-var _Object$defineProperty = __webpack_require__("hfKm");
+var _interopRequireDefault = __webpack_require__("KI45");
+
+var _defineProperty = _interopRequireDefault(__webpack_require__("hfKm"));
 
-_Object$defineProperty(exports, "__esModule", {
+(0, _defineProperty["default"])(exports, "__esModule", {
   value: true
 }); // Identify /[param]/ in route string
 
-
 var TEST_ROUTE = /\/\[[^\/]+?\](?=\/|$)/;
 
 function isDynamicRoute(route) {
@@ -5838,17 +5809,18 @@ The above copyright notice and this permission notice shall be included in all c
 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
 
-var _Object$create = __webpack_require__("SqZg");
+var _interopRequireDefault = __webpack_require__("KI45");
 
-var _Object$defineProperty = __webpack_require__("hfKm");
+var _create = _interopRequireDefault(__webpack_require__("SqZg"));
+
+var _defineProperty = _interopRequireDefault(__webpack_require__("hfKm"));
 
-_Object$defineProperty(exports, "__esModule", {
+(0, _defineProperty["default"])(exports, "__esModule", {
   value: true
 });
 
 function mitt() {
-  var all = _Object$create(null);
-
+  var all = (0, _create["default"])(null);
   return {
     on: function on(type, handler) {
       ;
@@ -6674,6 +6646,50 @@ try {
 
 /***/ }),
 
+/***/ "mgRA":
+/***/ (function(module, __webpack_exports__, __webpack_require__) {
+
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return _construct; });
+/* harmony import */ var _core_js_reflect_construct__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("pbKT");
+/* harmony import */ var _core_js_reflect_construct__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_core_js_reflect_construct__WEBPACK_IMPORTED_MODULE_0__);
+/* harmony import */ var _setPrototypeOf__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("VLay");
+
+
+
+function isNativeReflectConstruct() {
+  if (typeof Reflect === "undefined" || !_core_js_reflect_construct__WEBPACK_IMPORTED_MODULE_0___default.a) return false;
+  if (_core_js_reflect_construct__WEBPACK_IMPORTED_MODULE_0___default.a.sham) return false;
+  if (typeof Proxy === "function") return true;
+
+  try {
+    Date.prototype.toString.call(_core_js_reflect_construct__WEBPACK_IMPORTED_MODULE_0___default()(Date, [], function () {}));
+    return true;
+  } catch (e) {
+    return false;
+  }
+}
+
+function _construct(Parent, args, Class) {
+  if (isNativeReflectConstruct()) {
+    _construct = _core_js_reflect_construct__WEBPACK_IMPORTED_MODULE_0___default.a;
+  } else {
+    _construct = function _construct(Parent, args, Class) {
+      var a = [null];
+      a.push.apply(a, args);
+      var Constructor = Function.bind.apply(Parent, a);
+      var instance = new Constructor();
+      if (Class) Object(_setPrototypeOf__WEBPACK_IMPORTED_MODULE_1__[/* default */ "a"])(instance, Class.prototype);
+      return instance;
+    };
+  }
+
+  return _construct.apply(null, arguments);
+}
+
+/***/ }),
+
 /***/ "mqlF":
 /***/ (function(module, exports) {
 
@@ -6700,7 +6716,9 @@ module.exports = function (it, TYPE) {
 "use strict";
 
 
-var _construct = __webpack_require__("b3CU");
+var _interopRequireDefault2 = __webpack_require__("KI45");
+
+var _construct2 = _interopRequireDefault2(__webpack_require__("mgRA"));
 
 var _interopRequireWildcard = __webpack_require__("5Uuq");
 
@@ -6821,7 +6839,7 @@ var createRouter = function createRouter() {
     args[_key] = arguments[_key];
   }
 
-  singletonRouter.router = _construct(_router2["default"], args);
+  singletonRouter.router = (0, _construct2["default"])(_router2["default"], args);
   singletonRouter.readyCallbacks.forEach(function (cb) {
     return cb();
   });
@@ -7164,6 +7182,35 @@ exports.encode = exports.stringify = __webpack_require__("4JlD");
 
 /***/ }),
 
+/***/ "sLSF":
+/***/ (function(module, __webpack_exports__, __webpack_require__) {
+
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return _createClass; });
+/* harmony import */ var _core_js_object_define_property__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("hfKm");
+/* harmony import */ var _core_js_object_define_property__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_core_js_object_define_property__WEBPACK_IMPORTED_MODULE_0__);
+
+
+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;
+
+    _core_js_object_define_property__WEBPACK_IMPORTED_MODULE_0___default()(target, descriptor.key, descriptor);
+  }
+}
+
+function _createClass(Constructor, protoProps, staticProps) {
+  if (protoProps) _defineProperties(Constructor.prototype, protoProps);
+  if (staticProps) _defineProperties(Constructor, staticProps);
+  return Constructor;
+}
+
+/***/ }),
+
 /***/ "sNwI":
 /***/ (function(module, exports, __webpack_require__) {
 
@@ -7277,24 +7324,6 @@ b.type=a;return b},isValidElement:N,version:"16.9.0",unstable_withSuspenseConfig
 
 /***/ }),
 
-/***/ "vjea":
-/***/ (function(module, exports, __webpack_require__) {
-
-var _Object$setPrototypeOf = __webpack_require__("TRZx");
-
-function _setPrototypeOf(o, p) {
-  module.exports = _setPrototypeOf = _Object$setPrototypeOf || function _setPrototypeOf(o, p) {
-    o.__proto__ = p;
-    return o;
-  };
-
-  return _setPrototypeOf(o, p);
-}
-
-module.exports = _setPrototypeOf;
-
-/***/ }),
-
 /***/ "vwuL":
 /***/ (function(module, exports, __webpack_require__) {
 
Diff for mainModern.js
@@ -134,9 +134,6 @@ class HeadManager {
   updateElements(type, components) {
     const headEl = document.getElementsByTagName('head')[0];
     const headCountEl = headEl.querySelector('meta[name=next-head-count]');
-
-    if (false) {}
-
     const headCount = Number(headCountEl.content);
     const oldTags = [];
 
@@ -203,12 +200,13 @@ function reactElementToDOM(_ref) {
 "use strict";
 
 
-var _Object$defineProperty = __webpack_require__("hfKm");
+var _interopRequireDefault = __webpack_require__("KI45");
+
+var _defineProperty = _interopRequireDefault(__webpack_require__("hfKm"));
 
-_Object$defineProperty(exports, "__esModule", {
+(0, _defineProperty.default)(exports, "__esModule", {
   value: true
 });
-
 let runtimeConfig;
 
 exports.default = () => {
@@ -229,9 +227,11 @@ exports.setConfig = setConfig;
 "use strict";
 
 
-var _Object$defineProperty = __webpack_require__("hfKm");
+var _interopRequireDefault = __webpack_require__("KI45");
+
+var _defineProperty = _interopRequireDefault(__webpack_require__("hfKm"));
 
-var __importStar = this && this.__importStar || function (mod) {
+var __importStar = void 0 && (void 0).__importStar || function (mod) {
   if (mod && mod.__esModule) return mod;
   var result = {};
   if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
@@ -239,7 +239,7 @@ var __importStar = this && this.__importStar || function (mod) {
   return result;
 };
 
-_Object$defineProperty(exports, "__esModule", {
+(0, _defineProperty.default)(exports, "__esModule", {
   value: true
 });
 
@@ -369,7 +369,7 @@ class Container extends _react.default.Component {
     this.scrollToHash(); // If page was exported and has a querystring
     // If it's a dynamic route or has a querystring
 
-    if (data.nextExport && ((0, _isDynamic.isDynamicRoute)(router.pathname) || location.search || data.skeleton)) {
+    if (data.nextExport && ((0, _isDynamic.isDynamicRoute)(router.pathname) || location.search)) {
       // update query on mount for exported pages
       router.replace(router.pathname + '?' + (0, _querystring.stringify)((0, _extends2.default)({}, router.query, (0, _querystring.parse)(location.search.substr(1)))), asPath, {
         // WARNING: `_h` is an internal option for handing Next.js
@@ -464,6 +464,22 @@ function () {
       emitter
     };
     render(renderCtx);
+
+    if (window.__NEXT_DATA__.skeleton && Component.getInitialProps) {
+      const appCtx = {
+        router,
+        AppTree: wrapApp(App),
+        Component: Component,
+        ctx: {
+          pathname: page,
+          asPath,
+          query
+        }
+      };
+      props.pageProps = (yield App.getInitialProps(appCtx)).pageProps;
+      render(renderCtx);
+    }
+
     return emitter;
   });
 
@@ -520,15 +536,17 @@ function _renderError() {
     // If we've gotten here upon initial render, we can use the props from the server.
     // Otherwise, we need to call `getInitialProps` on `App` before mounting.
 
+    const AppTree = wrapApp(App);
     const appCtx = {
-      AppTree: wrapApp(App),
       Component: ErrorComponent,
+      AppTree,
       router,
       ctx: {
         err,
         pathname: page,
         query,
-        asPath
+        asPath,
+        AppTree
       }
     };
     const initProps = props.props ? props.props : yield (0, _utils.loadGetInitialProps)(App, appCtx);
@@ -637,15 +655,17 @@ function _doRender() {
         query,
         asPath
       } = router;
+      const AppTree = wrapApp(App);
       const appCtx = {
         router,
-        AppTree: wrapApp(App),
+        AppTree,
         Component: ErrorComponent,
         ctx: {
           err,
           pathname,
           query,
-          asPath
+          asPath,
+          AppTree
         }
       };
       props = yield (0, _utils.loadGetInitialProps)(App, appCtx);
@@ -725,17 +745,19 @@ $export($export.P + $export.R, 'Map', { toJSON: __webpack_require__("8iia")('Map
 "use strict";
 
 
-var _Map = __webpack_require__("LX0d");
+var _interopRequireDefault = __webpack_require__("KI45");
+
+var _map = _interopRequireDefault(__webpack_require__("LX0d"));
 
-var _Object$defineProperty = __webpack_require__("hfKm");
+var _defineProperty = _interopRequireDefault(__webpack_require__("hfKm"));
 
-_Object$defineProperty(exports, "__esModule", {
+(0, _defineProperty.default)(exports, "__esModule", {
   value: true
 });
 
 class DataManager {
   constructor(data) {
-    this.data = new _Map(data);
+    this.data = new _map.default(data);
   }
 
   getData() {
@@ -751,7 +773,7 @@ class DataManager {
   }
 
   overwrite(data) {
-    this.data = new _Map(data);
+    this.data = new _map.default(data);
   }
 
 }
@@ -802,9 +824,11 @@ module.exports = __webpack_require__("raTm")(MAP, function (get) {
 "use strict";
 
 
-var _Object$defineProperty = __webpack_require__("hfKm");
+var _interopRequireDefault = __webpack_require__("KI45");
+
+var _defineProperty = _interopRequireDefault(__webpack_require__("hfKm"));
 
-var __importStar = this && this.__importStar || function (mod) {
+var __importStar = void 0 && (void 0).__importStar || function (mod) {
   if (mod && mod.__esModule) return mod;
   var result = {};
   if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
@@ -812,7 +836,7 @@ var __importStar = this && this.__importStar || function (mod) {
   return result;
 };
 
-_Object$defineProperty(exports, "__esModule", {
+(0, _defineProperty.default)(exports, "__esModule", {
   value: true
 });
 
Diff for commonsModern.js
@@ -360,11 +360,13 @@ var objectKeys = Object.keys || function (obj) {
 "use strict";
 
 
-var _Object$keys = __webpack_require__("pLtp");
+var _interopRequireDefault = __webpack_require__("KI45");
 
-var _Object$defineProperty = __webpack_require__("hfKm");
+var _keys = _interopRequireDefault(__webpack_require__("pLtp"));
+
+var _defineProperty = _interopRequireDefault(__webpack_require__("hfKm"));
 
-_Object$defineProperty(exports, "__esModule", {
+(0, _defineProperty.default)(exports, "__esModule", {
   value: true
 });
 
@@ -381,15 +383,13 @@ function getRouteMatcher(routeRegex) {
     }
 
     const params = {};
-
-    _Object$keys(groups).forEach(slugName => {
+    (0, _keys.default)(groups).forEach(slugName => {
       const m = routeMatch[groups[slugName]];
 
       if (m !== undefined) {
         params[slugName] = decodeURIComponent(m);
       }
     });
-
     return params;
   };
 }
@@ -549,9 +549,11 @@ var meta = module.exports = {
 "use strict";
 
 
-var _Object$defineProperty = __webpack_require__("hfKm");
+var _interopRequireDefault = __webpack_require__("KI45");
 
-_Object$defineProperty(exports, "__esModule", {
+var _defineProperty = _interopRequireDefault(__webpack_require__("hfKm"));
+
+(0, _defineProperty.default)(exports, "__esModule", {
   value: true
 });
 
@@ -620,9 +622,11 @@ module.exports = function (it) {
 "use strict";
 
 
-var _Object$defineProperty = __webpack_require__("hfKm");
+var _interopRequireDefault = __webpack_require__("KI45");
+
+var _defineProperty = _interopRequireDefault(__webpack_require__("hfKm"));
 
-var __importStar = this && this.__importStar || function (mod) {
+var __importStar = void 0 && (void 0).__importStar || function (mod) {
   if (mod && mod.__esModule) return mod;
   var result = {};
   if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
@@ -630,7 +634,7 @@ var __importStar = this && this.__importStar || function (mod) {
   return result;
 };
 
-_Object$defineProperty(exports, "__esModule", {
+(0, _defineProperty.default)(exports, "__esModule", {
   value: true
 });
 
@@ -657,11 +661,13 @@ module.exports = function (it, key) {
 "use strict";
 
 
-var _Object$keys = __webpack_require__("pLtp");
+var _interopRequireDefault = __webpack_require__("KI45");
 
-var _Object$defineProperty = __webpack_require__("hfKm");
+var _keys = _interopRequireDefault(__webpack_require__("pLtp"));
 
-_Object$defineProperty(exports, "__esModule", {
+var _defineProperty = _interopRequireDefault(__webpack_require__("hfKm"));
+
+(0, _defineProperty.default)(exports, "__esModule", {
   value: true
 });
 
@@ -2459,19 +2465,21 @@ $export($export.S + $export.F * !(USE_NATIVE && __webpack_require__("TuGD")(func
 "use strict";
 
 
-var _Promise = __webpack_require__("eVuF");
+var _interopRequireDefault = __webpack_require__("KI45");
 
-var _Object$assign = __webpack_require__("UXZV");
+var _promise = _interopRequireDefault(__webpack_require__("eVuF"));
 
-var _Object$defineProperty = __webpack_require__("hfKm");
+var _assign = _interopRequireDefault(__webpack_require__("UXZV"));
+
+var _defineProperty = _interopRequireDefault(__webpack_require__("hfKm"));
 
-var __importDefault = this && this.__importDefault || function (mod) {
+var __importDefault = void 0 && (void 0).__importDefault || function (mod) {
   return mod && mod.__esModule ? mod : {
     "default": mod
   };
 };
 
-_Object$defineProperty(exports, "__esModule", {
+(0, _defineProperty.default)(exports, "__esModule", {
   value: true
 });
 
@@ -2597,7 +2605,7 @@ class Router {
             as,
             options
           } = history.state;
-          this.changeState('replaceState', url, as, _Object$assign({}, options, {
+          this.changeState('replaceState', url, as, (0, _assign.default)({}, options, {
             fromExternal: true
           }));
         }
@@ -2617,10 +2625,9 @@ class Router {
       throw new Error("Cannot update unavailable route: ".concat(route));
     }
 
-    const newData = _Object$assign({}, data, {
+    const newData = (0, _assign.default)({}, data, {
       Component
     });
-
     this.components[route] = newData; // pages/_app.js updated
 
     if (route === '/_app') {
@@ -2672,7 +2679,7 @@ class Router {
   }
 
   change(method, _url, _as, options) {
-    return new _Promise((resolve, reject) => {
+    return new _promise.default((resolve, reject) => {
       // marking route changes as a navigation start entry
       if (utils_1.SUPPORTS_PERFORMANCE_USER_TIMING) {
         performance.mark('routeChange');
@@ -2741,7 +2748,7 @@ class Router {
         } // Merge params into `query`, overwriting any specified in search
 
 
-        _Object$assign(query, routeMatch);
+        (0, _assign.default)(query, routeMatch);
       }
 
       Router.events.emit('routeChangeStart', as); // If shallow is true and the route exists in the router cache we reuse the previous result
@@ -2763,7 +2770,7 @@ class Router {
         if (false) {} // @ts-ignore pathname is always defined
 
 
-        this.set(route, pathname, query, as, _Object$assign({}, routeInfo, {
+        this.set(route, pathname, query, as, (0, _assign.default)({}, routeInfo, {
           hash
         }));
 
@@ -2799,10 +2806,10 @@ class Router {
     // If the route is already rendered on the screen.
 
     if (shallow && cachedRouteInfo && this.route === route) {
-      return _Promise.resolve(cachedRouteInfo);
+      return _promise.default.resolve(cachedRouteInfo);
     }
 
-    return new _Promise((resolve, reject) => {
+    return new _promise.default((resolve, reject) => {
       if (cachedRouteInfo) {
         return resolve(cachedRouteInfo);
       }
@@ -2817,20 +2824,20 @@ class Router {
 
       if (false) {}
 
-      return new _Promise((resolve, reject) => {
-        const ctx = {
+      return new _promise.default((resolve, reject) => {
+        // we provide AppTree later so this needs to be `any`
+        this.getInitialProps(Component, {
           pathname,
           query,
           asPath: as
-        };
-        this.getInitialProps(Component, ctx).then(props => {
+        }).then(props => {
           routeInfo.props = props;
           this.components[route] = routeInfo;
           resolve(routeInfo);
         }, reject);
       });
     }).catch(err => {
-      return new _Promise(resolve => {
+      return new _promise.default(resolve => {
         if (err.code === 'PAGE_LOAD_ERROR') {
           // If we can't load the page it could be one of following reasons
           //  1. Page doesn't exists
@@ -2859,13 +2866,12 @@ class Router {
             Component,
             err
           };
-          const ctx = {
-            err,
-            pathname,
-            query
-          };
-          return new _Promise(resolve => {
-            this.getInitialProps(Component, ctx).then(props => {
+          return new _promise.default(resolve => {
+            this.getInitialProps(Component, {
+              err,
+              pathname,
+              query
+            }).then(props => {
               routeInfo.props = props;
               routeInfo.error = err;
               resolve(routeInfo);
@@ -2955,7 +2961,7 @@ class Router {
 
 
   prefetch(url) {
-    return new _Promise((resolve, reject) => {
+    return new _promise.default((resolve, reject) => {
       const {
         pathname,
         protocol
@@ -3010,37 +3016,30 @@ class Router {
     } = this.components['/_app'];
     let props;
 
-    if ( // @ts-ignore workaround for dead-code elimination
-    (self.__HAS_SPR || "production" !== 'production') && Component.__NEXT_SPR) {
-      let status;
-      const url = ctx.asPath ? ctx.asPath : url_1.format({
-        pathname: ctx.pathname,
+    if (Component.__NEXT_PRERENDER) {
+      const url = url_1.format({
+        pathname: ctx.asPath,
         query: ctx.query
       });
-      props = await fetch(url, {
+      const res = await fetch(url, {
         headers: {
           'content-type': 'application/json'
         }
-      }).then(res => {
-        if (!res.ok) {
-          status = res.status;
-          throw new Error('failed to load prerender data');
-        }
-
-        return res.json();
-      }).then(pageProps => {
-        return {
-          pageProps
-        };
-      }).catch(err => {
-        return {
-          error: err.message,
-          status
-        };
       });
+      props = {
+        pageProps: res.ok ? await res.json().catch(err => ({
+          error: err.message
+        })) : {
+          error: 'failed to load prerender',
+          statusCode: res.status
+        }
+      };
     } else {
+      const AppTree = this._wrapApp(App);
+
+      ctx.AppTree = AppTree;
       props = await utils_1.loadGetInitialProps(App, {
-        AppTree: this._wrapApp(App),
+        AppTree,
         Component,
         router: this,
         ctx
@@ -3106,9 +3105,11 @@ module.exports = __webpack_require__("/eQG");
 "use strict";
 
 
-var _Object$defineProperty = __webpack_require__("hfKm");
+var _interopRequireDefault = __webpack_require__("KI45");
+
+var _defineProperty = _interopRequireDefault(__webpack_require__("hfKm"));
 
-_Object$defineProperty(exports, "__esModule", {
+(0, _defineProperty.default)(exports, "__esModule", {
   value: true
 });
 
@@ -4618,13 +4619,14 @@ module.exports = __webpack_require__("NegM");
 "use strict";
 
 
-var _Object$defineProperty = __webpack_require__("hfKm");
+var _interopRequireDefault = __webpack_require__("KI45");
 
-_Object$defineProperty(exports, "__esModule", {
+var _defineProperty = _interopRequireDefault(__webpack_require__("hfKm"));
+
+(0, _defineProperty.default)(exports, "__esModule", {
   value: true
 }); // Identify /[param]/ in route string
 
-
 const TEST_ROUTE = /\/\[[^\/]+?\](?=\/|$)/;
 
 function isDynamicRoute(route) {
@@ -4744,17 +4746,18 @@ The above copyright notice and this permission notice shall be included in all c
 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
 
-var _Object$create = __webpack_require__("SqZg");
+var _interopRequireDefault = __webpack_require__("KI45");
 
-var _Object$defineProperty = __webpack_require__("hfKm");
+var _create = _interopRequireDefault(__webpack_require__("SqZg"));
 
-_Object$defineProperty(exports, "__esModule", {
+var _defineProperty = _interopRequireDefault(__webpack_require__("hfKm"));
+
+(0, _defineProperty.default)(exports, "__esModule", {
   value: true
 });
 
 function mitt() {
-  const all = _Object$create(null);
-
+  const all = (0, _create.default)(null);
   return {
     on(type, handler) {
       ;

@ijjk
Copy link
Member Author

ijjk commented Aug 12, 2019

Stats from current PR

Click to expand stats ⚠️ Total Bundle Size Increase ⚠️
zeit/next.js canary ijjk/next.js add-apptree-ctx Change
Build Duration 24.4s 23.1s -1.3s
node_modules Size 41.6 MB 41.6 MB ⚠️ +1.19 kB
Total Bundle (main, webpack, commons) Size 210 kB 210 kB ⚠️ +38 B
Total Bundle (main, webpack, commons) gzip Size 69.3 kB 69.3 kB ⚠️ +14 B
Total Bundle (main, webpack, commons) Modern Size 187 kB 187 kB ⚠️ +37 B
Total Bundle (main, webpack, commons) Modern gzip Size 61.6 kB 61.6 kB ⚠️ +7 B
Client _app Size 1.9 kB 1.9 kB
Client _app gzip Size 913 B 913 B
Client _app Modern Size 1.79 kB 1.79 kB
Client _app gzip Modern Size 880 B 880 B
Client _error Size 8.02 kB 8.02 kB
Client _error gzip Size 3.13 kB 3.13 kB
Client _error Modern Size 5.82 kB 5.82 kB
Client _error gzip Modern Size 2.35 kB 2.35 kB
Client pages/index Size 343 B 343 B
Client pages/index gzip Size 246 B 246 B
Client pages/index Modern Size 319 B 319 B
Client pages/index gzip Modern Size 254 B 254 B
Client pages/link Size 4.07 kB 4.07 kB
Client pages/link gzip Size 1.8 kB 1.8 kB
Client pages/link Modern Size 3.78 kB 3.78 kB
Client pages/link gzip Modern Size 1.72 kB 1.72 kB
Client pages/routerDirect Size 423 B 423 B
Client pages/routerDirect gzip Size 306 B 306 B
Client pages/routerDirect Modern Size 411 B 411 B
Client pages/routerDirect gzip Modern Size 314 B 314 B
Client pages/withRouter Size 435 B 435 B
Client pages/withRouter gzip Size 301 B 301 B
Client pages/withRouter Modern Size 423 B 423 B
Client pages/withRouter gzip Modern Size 309 B 309 B
Client main Size 13.8 kB 13.8 kB ⚠️ +32 B
Client main gzip Size 4.88 kB 4.89 kB ⚠️ +18 B
Client main Modern Size 11.4 kB 11.4 kB ⚠️ +28 B
Client main Modern gzip Size 4.32 kB 4.34 kB ⚠️ +12 B
Client commons Size 194 kB 194 kB ⚠️ +6 B
Client commons gzip Size 63.3 kB 63.3 kB -4 B
Client commons Modern Size 175 kB 175 kB ⚠️ +9 B
Client commons Modern gzip Size 57.3 kB 57.3 kB -5 B
Client webpack Size 1.53 kB 1.53 kB
Client webpack gzip Size 778 B 778 B
Client webpack Modern Size 1.53 kB 1.53 kB
Client webpack Modern gzip Size 785 B 785 B
Base Rendered Size 2.76 kB 2.76 kB
Build Dir Size 1.41 MB 1.41 MB ⚠️ +595 B
Click to expand serverless stats ⚠️ Total Bundle Size Increase ⚠️
zeit/next.js canary ijjk/next.js add-apptree-ctx Change
Build Duration 25s 25.2s ⚠️ +239ms
node_modules Size 41.6 MB 41.6 MB ⚠️ +1.19 kB
Total Bundle (main, webpack, commons) Size 210 kB 210 kB ⚠️ +38 B
Total Bundle (main, webpack, commons) gzip Size 69.3 kB 69.3 kB ⚠️ +14 B
Total Bundle (main, webpack, commons) Modern Size 187 kB 187 kB ⚠️ +37 B
Total Bundle (main, webpack, commons) Modern gzip Size 61.6 kB 61.6 kB ⚠️ +7 B
Client _app Size 1.9 kB 1.9 kB
Client _app gzip Size 913 B 913 B
Client _app Modern Size 1.79 kB 1.79 kB
Client _app gzip Modern Size 880 B 880 B
Client _error Size 8.02 kB 8.02 kB
Client _error gzip Size 3.13 kB 3.13 kB
Client _error Modern Size 5.82 kB 5.82 kB
Client _error gzip Modern Size 2.35 kB 2.35 kB
Client pages/index Size 343 B 343 B
Client pages/index gzip Size 246 B 246 B
Client pages/index Modern Size 319 B 319 B
Client pages/index gzip Modern Size 254 B 254 B
Client pages/link Size 4.07 kB 4.07 kB
Client pages/link gzip Size 1.8 kB 1.8 kB
Client pages/link Modern Size 3.78 kB 3.78 kB
Client pages/link gzip Modern Size 1.72 kB 1.72 kB
Client pages/routerDirect Size 423 B 423 B
Client pages/routerDirect gzip Size 306 B 306 B
Client pages/routerDirect Modern Size 411 B 411 B
Client pages/routerDirect gzip Modern Size 314 B 314 B
Client pages/withRouter Size 435 B 435 B
Client pages/withRouter gzip Size 301 B 301 B
Client pages/withRouter Modern Size 423 B 423 B
Client pages/withRouter gzip Modern Size 309 B 309 B
Client main Size 13.8 kB 13.8 kB ⚠️ +32 B
Client main gzip Size 4.88 kB 4.89 kB ⚠️ +18 B
Client main Modern Size 11.4 kB 11.4 kB ⚠️ +28 B
Client main Modern gzip Size 4.32 kB 4.34 kB ⚠️ +12 B
Client commons Size 194 kB 194 kB ⚠️ +6 B
Client commons gzip Size 63.3 kB 63.3 kB -4 B
Client commons Modern Size 175 kB 175 kB ⚠️ +9 B
Client commons Modern gzip Size 57.3 kB 57.3 kB -5 B
Client webpack Size 1.53 kB 1.53 kB
Client webpack gzip Size 778 B 778 B
Client webpack Modern Size 1.53 kB 1.53 kB
Client webpack Modern gzip Size 785 B 785 B
Serverless pages/link Size 255 kB 255 kB ⚠️ +303 B
Serverless pages/link gzip Size 68.9 kB 68.9 kB ⚠️ +69 B
Serverless pages/index Size 247 kB 247 kB ⚠️ +303 B
Serverless pages/index gzip Size 66.6 kB 66.7 kB ⚠️ +70 B
Serverless pages/_error Size 247 kB 247 kB ⚠️ +303 B
Serverless pages/_error gzip Size 66.3 kB 66.4 kB ⚠️ +70 B
Serverless pages/routerDirect Size 248 kB 248 kB ⚠️ +303 B
Serverless pages/routerDirect gzip Size 66.6 kB 66.6 kB ⚠️ +70 B
Serverless pages/withRouter Size 248 kB 248 kB ⚠️ +303 B
Serverless pages/withRouter gzip Size 66.6 kB 66.7 kB ⚠️ +75 B
Build Dir Size 2.61 MB 2.61 MB ⚠️ +2.18 kB
Diff for main.js
@@ -586,7 +586,7 @@ function _renderError() {
   _renderError = (0, _asyncToGenerator2["default"])(
   /*#__PURE__*/
   _regeneratorRuntime.mark(function _callee3(props) {
-    var App, err, appCtx, initProps;
+    var App, err, AppTree, appCtx, initProps;
     return _regeneratorRuntime.wrap(function _callee3$(_context3) {
       while (1) {
         switch (_context3.prev = _context3.next) {
@@ -612,44 +612,46 @@ function _renderError() {
             // In production we do a normal render with the `ErrorComponent` as component.
             // If we've gotten here upon initial render, we can use the props from the server.
             // Otherwise, we need to call `getInitialProps` on `App` before mounting.
+            AppTree = wrapApp(App);
             appCtx = {
-              AppTree: wrapApp(App),
               Component: ErrorComponent,
+              AppTree: AppTree,
               router: router,
               ctx: {
                 err: err,
                 pathname: page,
                 query: query,
-                asPath: asPath
+                asPath: asPath,
+                AppTree: AppTree
               }
             };
 
             if (!props.props) {
-              _context3.next = 12;
+              _context3.next = 13;
               break;
             }
 
             _context3.t0 = props.props;
-            _context3.next = 15;
+            _context3.next = 16;
             break;
 
-          case 12:
-            _context3.next = 14;
+          case 13:
+            _context3.next = 15;
             return (0, _utils.loadGetInitialProps)(App, appCtx);
 
-          case 14:
+          case 15:
             _context3.t0 = _context3.sent;
 
-          case 15:
+          case 16:
             initProps = _context3.t0;
-            _context3.next = 18;
+            _context3.next = 19;
             return doRender((0, _extends2["default"])({}, props, {
               err: err,
               Component: ErrorComponent,
               props: initProps
             }));
 
-          case 18:
+          case 19:
           case "end":
             return _context3.stop();
         }
@@ -747,7 +749,7 @@ function _doRender() {
   _doRender = (0, _asyncToGenerator2["default"])(
   /*#__PURE__*/
   _regeneratorRuntime.mark(function _callee4(_ref5) {
-    var App, Component, props, err, _router2, pathname, _query, _asPath, appCtx, appProps;
+    var App, Component, props, err, _router2, pathname, _query, _asPath, AppTree, appCtx, appProps;
 
     return _regeneratorRuntime.wrap(function _callee4$(_context4) {
       while (1) {
@@ -757,29 +759,31 @@ function _doRender() {
             // this is for when ErrorComponent gets replaced by Component by HMR
 
             if (!(!props && Component && Component !== ErrorComponent && lastAppProps.Component === ErrorComponent)) {
-              _context4.next = 7;
+              _context4.next = 8;
               break;
             }
 
             _router2 = router, pathname = _router2.pathname, _query = _router2.query, _asPath = _router2.asPath;
+            AppTree = wrapApp(App);
             appCtx = {
               router: router,
-              AppTree: wrapApp(App),
+              AppTree: AppTree,
               Component: ErrorComponent,
               ctx: {
                 err: err,
                 pathname: pathname,
                 query: _query,
-                asPath: _asPath
+                asPath: _asPath,
+                AppTree: AppTree
               }
             };
-            _context4.next = 6;
+            _context4.next = 7;
             return (0, _utils.loadGetInitialProps)(App, appCtx);
 
-          case 6:
+          case 7:
             props = _context4.sent;
 
-          case 7:
+          case 8:
             Component = Component || lastAppProps.Component;
             props = props || lastAppProps.props;
             appProps = (0, _extends2["default"])({}, props, {
@@ -802,7 +806,7 @@ function _doRender() {
               appProps: appProps
             });
 
-          case 14:
+          case 15:
           case "end":
             return _context4.stop();
         }
Diff for commons.js
@@ -3431,13 +3431,12 @@ function () {
         if (false) { var _require, isValidElementType; }
 
         return new _Promise(function (resolve, reject) {
-          var ctx = {
+          // we provide AppTree later so this needs to be `any`
+          _this3.getInitialProps(Component, {
             pathname: pathname,
             query: query,
             asPath: as
-          };
-
-          _this3.getInitialProps(Component, ctx).then(function (props) {
+          }).then(function (props) {
             routeInfo.props = props;
             _this3.components[route] = routeInfo;
             resolve(routeInfo);
@@ -3473,13 +3472,12 @@ function () {
               Component: Component,
               err: err
             };
-            var ctx = {
-              err: err,
-              pathname: pathname,
-              query: query
-            };
             return new _Promise(function (resolve) {
-              _this3.getInitialProps(Component, ctx).then(function (props) {
+              _this3.getInitialProps(Component, {
+                err: err,
+                pathname: pathname,
+                query: query
+              }).then(function (props) {
                 routeInfo.props = props;
                 routeInfo.error = err;
                 resolve(routeInfo);
@@ -3667,7 +3665,7 @@ function () {
       var _getInitialProps = _asyncToGenerator(
       /*#__PURE__*/
       _regeneratorRuntime.mark(function _callee2(Component, ctx) {
-        var cancelled, cancel, App, props, status, url, err;
+        var cancelled, cancel, App, props, status, url, AppTree, err;
         return _regeneratorRuntime.wrap(function _callee2$(_context2) {
           while (1) {
             switch (_context2.prev = _context2.next) {
@@ -3716,28 +3714,30 @@ function () {
 
               case 8:
                 props = _context2.sent;
-                _context2.next = 14;
+                _context2.next = 16;
                 break;
 
               case 11:
-                _context2.next = 13;
+                AppTree = this._wrapApp(App);
+                ctx.AppTree = AppTree;
+                _context2.next = 15;
                 return utils_1.loadGetInitialProps(App, {
-                  AppTree: this._wrapApp(App),
+                  AppTree: AppTree,
                   Component: Component,
                   router: this,
                   ctx: ctx
                 });
 
-              case 13:
+              case 15:
                 props = _context2.sent;
 
-              case 14:
+              case 16:
                 if (cancel === this.clc) {
                   this.clc = null;
                 }
 
                 if (!cancelled) {
-                  _context2.next = 19;
+                  _context2.next = 21;
                   break;
                 }
 
@@ -3745,10 +3745,10 @@ function () {
                 err.cancelled = true;
                 throw err;
 
-              case 19:
+              case 21:
                 return _context2.abrupt("return", props);
 
-              case 20:
+              case 22:
               case "end":
                 return _context2.stop();
             }
Diff for mainModern.js
@@ -520,15 +520,17 @@ function _renderError() {
     // If we've gotten here upon initial render, we can use the props from the server.
     // Otherwise, we need to call `getInitialProps` on `App` before mounting.
 
+    const AppTree = wrapApp(App);
     const appCtx = {
-      AppTree: wrapApp(App),
       Component: ErrorComponent,
+      AppTree,
       router,
       ctx: {
         err,
         pathname: page,
         query,
-        asPath
+        asPath,
+        AppTree
       }
     };
     const initProps = props.props ? props.props : yield (0, _utils.loadGetInitialProps)(App, appCtx);
@@ -637,15 +639,17 @@ function _doRender() {
         query,
         asPath
       } = router;
+      const AppTree = wrapApp(App);
       const appCtx = {
         router,
-        AppTree: wrapApp(App),
+        AppTree,
         Component: ErrorComponent,
         ctx: {
           err,
           pathname,
           query,
-          asPath
+          asPath,
+          AppTree
         }
       };
       props = yield (0, _utils.loadGetInitialProps)(App, appCtx);
Diff for commonsModern.js
@@ -2818,12 +2818,12 @@ class Router {
       if (false) {}
 
       return new _Promise((resolve, reject) => {
-        const ctx = {
+        // we provide AppTree later so this needs to be `any`
+        this.getInitialProps(Component, {
           pathname,
           query,
           asPath: as
-        };
-        this.getInitialProps(Component, ctx).then(props => {
+        }).then(props => {
           routeInfo.props = props;
           this.components[route] = routeInfo;
           resolve(routeInfo);
@@ -2859,13 +2859,12 @@ class Router {
             Component,
             err
           };
-          const ctx = {
-            err,
-            pathname,
-            query
-          };
           return new _Promise(resolve => {
-            this.getInitialProps(Component, ctx).then(props => {
+            this.getInitialProps(Component, {
+              err,
+              pathname,
+              query
+            }).then(props => {
               routeInfo.props = props;
               routeInfo.error = err;
               resolve(routeInfo);
@@ -3039,8 +3038,11 @@ class Router {
         };
       });
     } else {
+      const AppTree = this._wrapApp(App);
+
+      ctx.AppTree = AppTree;
       props = await utils_1.loadGetInitialProps(App, {
-        AppTree: this._wrapApp(App),
+        AppTree,
         Component,
         router: this,
         ctx

@ijjk
Copy link
Member Author

ijjk commented Aug 12, 2019

Stats from current PR

Default Server Mode

General
zeit/next.js canary ijjk/next.js add-apptree-ctx Change
buildDuration 23.1s 22.6s -540ms
nodeModulesSize 41.6 MB 41.6 MB ⚠️ +1.19 kB
Client Bundles (main, webpack, commons) ⚠️ Overall increase ⚠️
zeit/next.js canary ijjk/next.js add-apptree-ctx Change
main-HASH.js 13.8 kB 13.8 kB ⚠️ +32 B
main-HASH.js gzip 4.84 kB 4.86 kB ⚠️ +18 B
webpack-HASH.js 1.53 kB 1.53 kB
webpack-HASH.js gzip 746 B 746 B
commons.HASH.js 194 kB 194 kB ⚠️ +6 B
commons.HASH.js gzip 63.1 kB 63.1 kB -5 B
Overall change ⚠️ +38 B
Client Bundles (main, webpack, commons) Modern ⚠️ Overall increase ⚠️
zeit/next.js canary ijjk/next.js add-apptree-ctx Change
main-HASH.module.js 11.4 kB 11.4 kB ⚠️ +28 B
main-HASH.module.js gzip 4.29 kB 4.3 kB ⚠️ +13 B
webpack-HASH.module.js 1.53 kB 1.53 kB
webpack-HASH.module.js gzip 746 B 746 B
commons.HASH.module.js 175 kB 175 kB ⚠️ +9 B
commons.HASH.module.js gzip 57.1 kB 57.1 kB -5 B
Overall change ⚠️ +37 B
Client Pages
zeit/next.js canary ijjk/next.js add-apptree-ctx Change
_app.js 1.9 kB 1.9 kB
_app.js gzip 905 B 905 B
_error.js 8.02 kB 8.02 kB
_error.js gzip 3.12 kB 3.12 kB
index.js 343 B 343 B
index.js gzip 237 B 237 B
link.js 4.07 kB 4.07 kB
link.js gzip 1.79 kB 1.79 kB
routerDirect.js 423 B 423 B
routerDirect.js gzip 290 B 290 B
withRouter.js 435 B 435 B
withRouter.js gzip 287 B 286 B -1 B
Overall change
Client Pages Modern
zeit/next.js canary ijjk/next.js add-apptree-ctx Change
_app.module.js 1.79 kB 1.79 kB
_app.module.js gzip 865 B 865 B
_error.module.js 5.82 kB 5.82 kB
_error.module.js gzip 2.33 kB 2.33 kB
index.module.js 319 B 319 B
index.module.js gzip 238 B 238 B
link.module.js 3.78 kB 3.78 kB
link.module.js gzip 1.7 kB 1.7 kB -1 B
routerDirect.module.js 411 B 411 B
routerDirect.module.js gzip 291 B 291 B
withRouter.module.js 423 B 423 B
withRouter.module.js gzip 288 B 288 B
Overall change
Fetched pages
zeit/next.js canary ijjk/next.js add-apptree-ctx Change
link 2.81 kB 2.81 kB
link gzip 846 B 847 B ⚠️ +1 B
index 2.76 kB 2.76 kB
index gzip 837 B 840 B ⚠️ +3 B
withRouter 2.82 kB 2.82 kB
withRouter gzip 833 B 836 B ⚠️ +3 B
Overall change

Diffs

Diff for main-HASH.js
@@ -586,7 +586,7 @@ function _renderError() {
   _renderError = (0, _asyncToGenerator2["default"])(
   /*#__PURE__*/
   _regeneratorRuntime.mark(function _callee3(props) {
-    var App, err, appCtx, initProps;
+    var App, err, AppTree, appCtx, initProps;
     return _regeneratorRuntime.wrap(function _callee3$(_context3) {
       while (1) {
         switch (_context3.prev = _context3.next) {
@@ -612,44 +612,46 @@ function _renderError() {
             // In production we do a normal render with the `ErrorComponent` as component.
             // If we've gotten here upon initial render, we can use the props from the server.
             // Otherwise, we need to call `getInitialProps` on `App` before mounting.
+            AppTree = wrapApp(App);
             appCtx = {
-              AppTree: wrapApp(App),
               Component: ErrorComponent,
+              AppTree: AppTree,
               router: router,
               ctx: {
                 err: err,
                 pathname: page,
                 query: query,
-                asPath: asPath
+                asPath: asPath,
+                AppTree: AppTree
               }
             };
 
             if (!props.props) {
-              _context3.next = 12;
+              _context3.next = 13;
               break;
             }
 
             _context3.t0 = props.props;
-            _context3.next = 15;
+            _context3.next = 16;
             break;
 
-          case 12:
-            _context3.next = 14;
+          case 13:
+            _context3.next = 15;
             return (0, _utils.loadGetInitialProps)(App, appCtx);
 
-          case 14:
+          case 15:
             _context3.t0 = _context3.sent;
 
-          case 15:
+          case 16:
             initProps = _context3.t0;
-            _context3.next = 18;
+            _context3.next = 19;
             return doRender((0, _extends2["default"])({}, props, {
               err: err,
               Component: ErrorComponent,
               props: initProps
             }));
 
-          case 18:
+          case 19:
           case "end":
             return _context3.stop();
         }
@@ -747,7 +749,7 @@ function _doRender() {
   _doRender = (0, _asyncToGenerator2["default"])(
   /*#__PURE__*/
   _regeneratorRuntime.mark(function _callee4(_ref5) {
-    var App, Component, props, err, _router2, pathname, _query, _asPath, appCtx, appProps;
+    var App, Component, props, err, _router2, pathname, _query, _asPath, AppTree, appCtx, appProps;
 
     return _regeneratorRuntime.wrap(function _callee4$(_context4) {
       while (1) {
@@ -757,29 +759,31 @@ function _doRender() {
             // this is for when ErrorComponent gets replaced by Component by HMR
 
             if (!(!props && Component && Component !== ErrorComponent && lastAppProps.Component === ErrorComponent)) {
-              _context4.next = 7;
+              _context4.next = 8;
               break;
             }
 
             _router2 = router, pathname = _router2.pathname, _query = _router2.query, _asPath = _router2.asPath;
+            AppTree = wrapApp(App);
             appCtx = {
               router: router,
-              AppTree: wrapApp(App),
+              AppTree: AppTree,
               Component: ErrorComponent,
               ctx: {
                 err: err,
                 pathname: pathname,
                 query: _query,
-                asPath: _asPath
+                asPath: _asPath,
+                AppTree: AppTree
               }
             };
-            _context4.next = 6;
+            _context4.next = 7;
             return (0, _utils.loadGetInitialProps)(App, appCtx);
 
-          case 6:
+          case 7:
             props = _context4.sent;
 
-          case 7:
+          case 8:
             Component = Component || lastAppProps.Component;
             props = props || lastAppProps.props;
             appProps = (0, _extends2["default"])({}, props, {
@@ -802,7 +806,7 @@ function _doRender() {
               appProps: appProps
             });
 
-          case 14:
+          case 15:
           case "end":
             return _context4.stop();
         }
Diff for commons.HASH.js
@@ -3431,13 +3431,12 @@ function () {
         if (false) { var _require, isValidElementType; }
 
         return new _Promise(function (resolve, reject) {
-          var ctx = {
+          // we provide AppTree later so this needs to be `any`
+          _this3.getInitialProps(Component, {
             pathname: pathname,
             query: query,
             asPath: as
-          };
-
-          _this3.getInitialProps(Component, ctx).then(function (props) {
+          }).then(function (props) {
             routeInfo.props = props;
             _this3.components[route] = routeInfo;
             resolve(routeInfo);
@@ -3473,13 +3472,12 @@ function () {
               Component: Component,
               err: err
             };
-            var ctx = {
-              err: err,
-              pathname: pathname,
-              query: query
-            };
             return new _Promise(function (resolve) {
-              _this3.getInitialProps(Component, ctx).then(function (props) {
+              _this3.getInitialProps(Component, {
+                err: err,
+                pathname: pathname,
+                query: query
+              }).then(function (props) {
                 routeInfo.props = props;
                 routeInfo.error = err;
                 resolve(routeInfo);
@@ -3667,7 +3665,7 @@ function () {
       var _getInitialProps = _asyncToGenerator(
       /*#__PURE__*/
       _regeneratorRuntime.mark(function _callee2(Component, ctx) {
-        var cancelled, cancel, App, props, status, url, err;
+        var cancelled, cancel, App, props, status, url, AppTree, err;
         return _regeneratorRuntime.wrap(function _callee2$(_context2) {
           while (1) {
             switch (_context2.prev = _context2.next) {
@@ -3716,28 +3714,30 @@ function () {
 
               case 8:
                 props = _context2.sent;
-                _context2.next = 14;
+                _context2.next = 16;
                 break;
 
               case 11:
-                _context2.next = 13;
+                AppTree = this._wrapApp(App);
+                ctx.AppTree = AppTree;
+                _context2.next = 15;
                 return utils_1.loadGetInitialProps(App, {
-                  AppTree: this._wrapApp(App),
+                  AppTree: AppTree,
                   Component: Component,
                   router: this,
                   ctx: ctx
                 });
 
-              case 13:
+              case 15:
                 props = _context2.sent;
 
-              case 14:
+              case 16:
                 if (cancel === this.clc) {
                   this.clc = null;
                 }
 
                 if (!cancelled) {
-                  _context2.next = 19;
+                  _context2.next = 21;
                   break;
                 }
 
@@ -3745,10 +3745,10 @@ function () {
                 err.cancelled = true;
                 throw err;
 
-              case 19:
+              case 21:
                 return _context2.abrupt("return", props);
 
-              case 20:
+              case 22:
               case "end":
                 return _context2.stop();
             }
Diff for commons.HASH.module.js
@@ -2818,12 +2818,12 @@ class Router {
       if (false) {}
 
       return new _Promise((resolve, reject) => {
-        const ctx = {
+        // we provide AppTree later so this needs to be `any`
+        this.getInitialProps(Component, {
           pathname,
           query,
           asPath: as
-        };
-        this.getInitialProps(Component, ctx).then(props => {
+        }).then(props => {
           routeInfo.props = props;
           this.components[route] = routeInfo;
           resolve(routeInfo);
@@ -2859,13 +2859,12 @@ class Router {
             Component,
             err
           };
-          const ctx = {
-            err,
-            pathname,
-            query
-          };
           return new _Promise(resolve => {
-            this.getInitialProps(Component, ctx).then(props => {
+            this.getInitialProps(Component, {
+              err,
+              pathname,
+              query
+            }).then(props => {
               routeInfo.props = props;
               routeInfo.error = err;
               resolve(routeInfo);
@@ -3039,8 +3038,11 @@ class Router {
         };
       });
     } else {
+      const AppTree = this._wrapApp(App);
+
+      ctx.AppTree = AppTree;
       props = await utils_1.loadGetInitialProps(App, {
-        AppTree: this._wrapApp(App),
+        AppTree,
         Component,
         router: this,
         ctx
Diff for main-HASH.module.js
@@ -520,15 +520,17 @@ function _renderError() {
     // If we've gotten here upon initial render, we can use the props from the server.
     // Otherwise, we need to call `getInitialProps` on `App` before mounting.
 
+    const AppTree = wrapApp(App);
     const appCtx = {
-      AppTree: wrapApp(App),
       Component: ErrorComponent,
+      AppTree,
       router,
       ctx: {
         err,
         pathname: page,
         query,
-        asPath
+        asPath,
+        AppTree
       }
     };
     const initProps = props.props ? props.props : yield (0, _utils.loadGetInitialProps)(App, appCtx);
@@ -637,15 +639,17 @@ function _doRender() {
         query,
         asPath
       } = router;
+      const AppTree = wrapApp(App);
       const appCtx = {
         router,
-        AppTree: wrapApp(App),
+        AppTree,
         Component: ErrorComponent,
         ctx: {
           err,
           pathname,
           query,
-          asPath
+          asPath,
+          AppTree
         }
       };
       props = yield (0, _utils.loadGetInitialProps)(App, appCtx);

Serverless Mode

General
zeit/next.js canary ijjk/next.js add-apptree-ctx Change
buildDuration 24.5s 24.4s -87ms
nodeModulesSize 41.6 MB 41.6 MB ⚠️ +1.19 kB
Client Bundles (main, webpack, commons) ⚠️ Overall increase ⚠️
zeit/next.js canary ijjk/next.js add-apptree-ctx Change
main-HASH.js 13.8 kB 13.8 kB ⚠️ +32 B
main-HASH.js gzip 4.84 kB 4.86 kB ⚠️ +18 B
webpack-HASH.js 1.53 kB 1.53 kB
webpack-HASH.js gzip 746 B 746 B
commons.HASH.js 194 kB 194 kB ⚠️ +6 B
commons.HASH.js gzip 63.1 kB 63.1 kB -5 B
Overall change ⚠️ +38 B
Client Bundles (main, webpack, commons) Modern ⚠️ Overall increase ⚠️
zeit/next.js canary ijjk/next.js add-apptree-ctx Change
main-HASH.module.js 11.4 kB 11.4 kB ⚠️ +28 B
main-HASH.module.js gzip 4.29 kB 4.3 kB ⚠️ +13 B
webpack-HASH.module.js 1.53 kB 1.53 kB
webpack-HASH.module.js gzip 746 B 746 B
commons.HASH.module.js 175 kB 175 kB ⚠️ +9 B
commons.HASH.module.js gzip 57.1 kB 57.1 kB -5 B
Overall change ⚠️ +37 B
Client Pages
zeit/next.js canary ijjk/next.js add-apptree-ctx Change
_app.js 1.9 kB 1.9 kB
_app.js gzip 905 B 905 B
_error.js 8.02 kB 8.02 kB
_error.js gzip 3.12 kB 3.12 kB
index.js 343 B 343 B
index.js gzip 237 B 237 B
link.js 4.07 kB 4.07 kB
link.js gzip 1.79 kB 1.79 kB
routerDirect.js 423 B 423 B
routerDirect.js gzip 290 B 290 B
withRouter.js 435 B 435 B
withRouter.js gzip 287 B 287 B
Overall change
Client Pages Modern
zeit/next.js canary ijjk/next.js add-apptree-ctx Change
_app.module.js 1.79 kB 1.79 kB
_app.module.js gzip 865 B 865 B
_error.module.js 5.82 kB 5.82 kB
_error.module.js gzip 2.33 kB 2.33 kB
index.module.js 319 B 319 B
index.module.js gzip 238 B 238 B
link.module.js 3.78 kB 3.78 kB
link.module.js gzip 1.7 kB 1.7 kB
routerDirect.module.js 411 B 411 B
routerDirect.module.js gzip 291 B 291 B
withRouter.module.js 423 B 423 B
withRouter.module.js gzip 288 B 288 B
Overall change
Serverless bundles ⚠️ Overall increase ⚠️
zeit/next.js canary ijjk/next.js add-apptree-ctx Change
_error.js 247 kB 247 kB ⚠️ +303 B
_error.js gzip 66.1 kB 66.2 kB ⚠️ +71 B
index.js 247 kB 247 kB ⚠️ +303 B
index.js gzip 66.5 kB 66.5 kB ⚠️ +69 B
link.js 255 kB 255 kB ⚠️ +303 B
link.js gzip 68.6 kB 68.7 kB ⚠️ +72 B
routerDirect.js 248 kB 248 kB ⚠️ +303 B
routerDirect.js gzip 66.4 kB 66.4 kB ⚠️ +72 B
withRouter.js 248 kB 248 kB ⚠️ +303 B
withRouter.js gzip 66.5 kB 66.5 kB ⚠️ +67 B
Overall change ⚠️ +1.51 kB

@timneutkens timneutkens merged commit 8c19d78 into vercel:canary Aug 13, 2019
@ijjk ijjk deleted the add-apptree-ctx branch August 13, 2019 16:44
@vercel vercel locked as resolved and limited conversation to collaborators Feb 1, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants