From 794da0b63217be48e76644bb729a01dec70412e4 Mon Sep 17 00:00:00 2001 From: Tim Neutkens Date: Wed, 16 Jan 2019 15:33:22 +0100 Subject: [PATCH 01/12] Add docs for Serverless target --- packages/next/README.md | 51 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/packages/next/README.md b/packages/next/README.md index 45dad86bb9c0a..8f838bee0d569 100644 --- a/packages/next/README.md +++ b/packages/next/README.md @@ -1585,6 +1585,57 @@ Note: `NODE_ENV` is properly configured by the `next` subcommands, if absent, to Note: we recommend putting `.next`, or your [custom dist folder](https://github.com/zeit/next.js#custom-configuration), in `.gitignore` or `.npmignore`. Otherwise, use `files` or `now.files` to opt-into a whitelist of files you want to deploy, excluding `.next` or your custom dist folder. +### Serverless deployment + +
+ Examples + +
+ +Serverless deployment dramatically improves reliability and scalability by splitting your application into many entrypoints. In case of Next.js an entrypoint is a page in the `pages` directory. + +To enable building serverless functions you have to enable the `serverless` build `target` in `next.config.js`: + +```js +module.exports = { + target: 'serverless' +} +``` + +The serverless target will output a single file per page, this file is completely standalone and doesn't require any dependencies to run: + +- `pages/index.js` => `.next/serverless/pages/index.js` +- `pages/about.js` => `.next/serverless/pages/about.js` + +The signature of the Next.js Serverless function is similar to the Node.js HTTP server callback: + +```ts +export function render(req: http.IncomingMessage, res: http.ServerResponse) => void +``` + +- [http.IncomingMessage](https://nodejs.org/api/http.html#http_class_http_incomingmessage) +- [http.ServerResponse](https://nodejs.org/api/http.html#http_class_http_serverresponse) +- void refers to the function not having a return value. Calling the function will finish the request. + +Example usage with [`http.Server`](https://nodejs.org/api/http.html#http_class_http_server): + +```js +const http = require('http') +const page = require('./.next/serverless/about.js') +const server = new http.Server((req, res) => page.render(req, res)) +server.listen(3000, () => console.log('Listening on http://localhost:3000')) +``` + +Next.js provides low level APIs for serverless as platforms have different function signatures. The low level APIs allow the user to implement Next.js on any serverless platform. + +Generally you will want to wrap the Next.js serverless build output to interoperate between your deployment platform and the Next.js serverless function. + +Examples of automatically created Serverless deployments: + +- [Now v2 with `@now/next` builder](https://github.com/zeit/now-examples/tree/master/nextjs) + ## Browser support Next.js supports IE11 and all modern browsers out of the box using [`@babel/preset-env`](https://new.babeljs.io/docs/en/next/babel-preset-env.html). In order to support IE11 Next.js adds a global `Promise` polyfill. In cases where your own code or any external NPM dependencies you are using requires features not supported by your target browsers you will need to implement polyfills. From 5ce84843c71cc12538282902db71e453d6eb9074 Mon Sep 17 00:00:00 2001 From: Tim Neutkens Date: Wed, 16 Jan 2019 15:57:40 +0100 Subject: [PATCH 02/12] Add summary --- packages/next/README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/packages/next/README.md b/packages/next/README.md index 8f838bee0d569..221e87a1afd53 100644 --- a/packages/next/README.md +++ b/packages/next/README.md @@ -1636,6 +1636,14 @@ Examples of automatically created Serverless deployments: - [Now v2 with `@now/next` builder](https://github.com/zeit/now-examples/tree/master/nextjs) +To summarize: + +- Every page becomes a serverless function +- The serverless function has 0 dependencies (they're all inlined) +- Uses the req and res coming from Node.js +- opt-in using target: 'serverless' in next.config.js +- Does not load next.config.js when executing the function, note that this means `publicRuntimeConfig` / `serverRuntimeConfig` are not supported. + ## Browser support Next.js supports IE11 and all modern browsers out of the box using [`@babel/preset-env`](https://new.babeljs.io/docs/en/next/babel-preset-env.html). In order to support IE11 Next.js adds a global `Promise` polyfill. In cases where your own code or any external NPM dependencies you are using requires features not supported by your target browsers you will need to implement polyfills. From f55fdb0f846b8940db691eb012aa28551b290955 Mon Sep 17 00:00:00 2001 From: Timothy <1695613+timothyis@users.noreply.github.com> Date: Wed, 16 Jan 2019 16:50:11 +0100 Subject: [PATCH 03/12] Update packages/next/README.md Co-Authored-By: timneutkens --- packages/next/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/next/README.md b/packages/next/README.md index 221e87a1afd53..8a62821aba5bf 100644 --- a/packages/next/README.md +++ b/packages/next/README.md @@ -1628,7 +1628,7 @@ const server = new http.Server((req, res) => page.render(req, res)) server.listen(3000, () => console.log('Listening on http://localhost:3000')) ``` -Next.js provides low level APIs for serverless as platforms have different function signatures. The low level APIs allow the user to implement Next.js on any serverless platform. +Next.js provides low-level APIs for serverless as platforms have different function signatures. These APIs allow the user to implement Next.js on any serverless platform. Generally you will want to wrap the Next.js serverless build output to interoperate between your deployment platform and the Next.js serverless function. From c9467c2019a2264b5e2451371733efeee796b6c2 Mon Sep 17 00:00:00 2001 From: Timothy <1695613+timothyis@users.noreply.github.com> Date: Wed, 16 Jan 2019 16:50:31 +0100 Subject: [PATCH 04/12] Apply suggestions from code review Co-Authored-By: timneutkens --- packages/next/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/next/README.md b/packages/next/README.md index 8a62821aba5bf..33ec683e97dd2 100644 --- a/packages/next/README.md +++ b/packages/next/README.md @@ -1630,7 +1630,7 @@ server.listen(3000, () => console.log('Listening on http://localhost:3000')) Next.js provides low-level APIs for serverless as platforms have different function signatures. These APIs allow the user to implement Next.js on any serverless platform. -Generally you will want to wrap the Next.js serverless build output to interoperate between your deployment platform and the Next.js serverless function. +Generally, you will want to wrap the Next.js serverless build output to interoperate between your deployment platform and the Next.js serverless function. Examples of automatically created Serverless deployments: From 31af9c8923a9f4c3b83e781ce5b549ea599e2aea Mon Sep 17 00:00:00 2001 From: Tim Neutkens Date: Wed, 16 Jan 2019 17:06:39 +0100 Subject: [PATCH 05/12] Update packages/next/README.md --- packages/next/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/next/README.md b/packages/next/README.md index 33ec683e97dd2..33cadc8605abb 100644 --- a/packages/next/README.md +++ b/packages/next/README.md @@ -1617,7 +1617,7 @@ export function render(req: http.IncomingMessage, res: http.ServerResponse) => v - [http.IncomingMessage](https://nodejs.org/api/http.html#http_class_http_incomingmessage) - [http.ServerResponse](https://nodejs.org/api/http.html#http_class_http_serverresponse) -- void refers to the function not having a return value. Calling the function will finish the request. +- `void` refers to the function not having a return value. Calling the function will finish the request. Example usage with [`http.Server`](https://nodejs.org/api/http.html#http_class_http_server): From 8736d47fc5f668ffc4343fa4a61f3a5c738e4252 Mon Sep 17 00:00:00 2001 From: Tim Neutkens Date: Tue, 15 Jan 2019 02:20:20 +0100 Subject: [PATCH 06/12] Use Object.assign instead of object spread for serverless loader (#6056) Fixes https://github.com/zeit/now-builders/issues/168 For some reason with a certain mix of deps `...` is not supported in webpack's parsing. By default it is supported as all our tests passed before and we have deployed Next.js apps on v2 already. --- .../webpack/loaders/next-serverless-loader.ts | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/packages/next/build/webpack/loaders/next-serverless-loader.ts b/packages/next/build/webpack/loaders/next-serverless-loader.ts index 258ce395925af..5553196fb68c1 100644 --- a/packages/next/build/webpack/loaders/next-serverless-loader.ts +++ b/packages/next/build/webpack/loaders/next-serverless-loader.ts @@ -51,27 +51,24 @@ const nextServerlessLoader: loader.Loader = function () { const parsedUrl = parse(req.url, true) try { ${page === '/_error' ? `res.statusCode = 404` : ''} - const result = await renderToHTML(req, res, "${page}", parsedUrl.query, { - ...options, + const result = await renderToHTML(req, res, "${page}", parsedUrl.query, Object.assign({}, options, { Component - }) + })) return result } catch (err) { if (err.code === 'ENOENT') { res.statusCode = 404 - const result = await renderToHTML(req, res, "/_error", parsedUrl.query, { - ...options, + const result = await renderToHTML(req, res, "/_error", parsedUrl.query, Object.assign({}, options, { Component: Error - }) + })) return result } else { console.error(err) res.statusCode = 500 - const result = await renderToHTML(req, res, "/_error", parsedUrl.query, { - ...options, + const result = await renderToHTML(req, res, "/_error", parsedUrl.query, Object.assign({}, options, { Component: Error, err - }) + })) return result } } From b9fa1f4ca3e22ff4df3a96546e5bf540c9a3efa1 Mon Sep 17 00:00:00 2001 From: Telegin Evgeniy Date: Wed, 16 Jan 2019 15:32:47 +0600 Subject: [PATCH 07/12] Add iOS 10 support for TerserPlugin (#6067) Resolves #5630 --- packages/next/build/webpack-config.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/next/build/webpack-config.js b/packages/next/build/webpack-config.js index 0ef6388afd5ff..68021644e3b50 100644 --- a/packages/next/build/webpack-config.js +++ b/packages/next/build/webpack-config.js @@ -124,7 +124,11 @@ function optimizationConfig ({ dev, isServer, totalPages, target }) { // Terser is a better uglifier config.minimizer = [ - new TerserPlugin(terserPluginConfig) + new TerserPlugin({...terserPluginConfig, + terserOptions: { + safari10: true + } + }) ] // Only enabled in production From 7b3e0bd8d614c006c420430976c301c9d529a676 Mon Sep 17 00:00:00 2001 From: fabb <153960+fabb@users.noreply.github.com> Date: Wed, 16 Jan 2019 10:57:37 +0100 Subject: [PATCH 08/12] added warning to readme about nesting of meta tags inside of (#6068) --- packages/next/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/next/README.md b/packages/next/README.md index 33cadc8605abb..03f94df7c2006 100644 --- a/packages/next/README.md +++ b/packages/next/README.md @@ -277,6 +277,8 @@ In this case only the second `` is rendered. _Note: The contents of `` get cleared upon unmounting the component, so make sure each page completely defines what it needs in ``, without making assumptions about what other pages added_ +_Note: `` and `<meta>` elements need to be contained as **direct** children of the `<Head>` element, or wrapped into maximum one level of `<React.Fragment>`, otherwise the metatags won't be correctly picked up on clientside navigation._ + ### Fetching data and component lifecycle <details> From 7274ec46a628bf162c570667a00a1d86a5d6f3fa Mon Sep 17 00:00:00 2001 From: Giuseppe <giuseppeg@users.noreply.github.com> Date: Wed, 16 Jan 2019 11:37:01 +0100 Subject: [PATCH 09/12] Upgrade styled-jsx (#6069) Introduces full support for Babel 7 including JSX Fragments shorthand. Switched to visiting the `Program` path and then start a traversal manually to solve conflicts with other Babel plugins. --- packages/next/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/next/package.json b/packages/next/package.json index f4943623d63e8..a410dc6308f3d 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -78,7 +78,7 @@ "recursive-copy": "2.0.6", "resolve": "1.5.0", "strip-ansi": "3.0.1", - "styled-jsx": "3.1.3", + "styled-jsx": "3.2.0", "terser-webpack-plugin": "1.1.0", "tty-aware-progress": "1.0.3", "unfetch": "3.0.0", From 4e5b4ab898c75bb418a09b4e3a84f9b268a5830a Mon Sep 17 00:00:00 2001 From: Tim Neutkens <timneutkens@me.com> Date: Thu, 17 Jan 2019 15:57:56 +0100 Subject: [PATCH 10/12] Add note about contributing examples --- packages/next/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/next/README.md b/packages/next/README.md index 03f94df7c2006..92be75b36060d 100644 --- a/packages/next/README.md +++ b/packages/next/README.md @@ -1593,6 +1593,7 @@ Note: we recommend putting `.next`, or your [custom dist folder](https://github. <summary><b>Examples</b></summary> <ul> <li><a href="https://github.com/zeit/now-examples/tree/master/nextjs">Now.sh</a></li> + <li>We encourage contributing more examples to this section</li> </ul> </details> From d4bfb5f03551c1df0aad13d0b59e91374f69b42a Mon Sep 17 00:00:00 2001 From: Tim Neutkens <timneutkens@me.com> Date: Thu, 17 Jan 2019 16:02:03 +0100 Subject: [PATCH 11/12] Bring back my changes --- packages/next/README.md | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/packages/next/README.md b/packages/next/README.md index 92be75b36060d..a7bbd8fc5f05f 100644 --- a/packages/next/README.md +++ b/packages/next/README.md @@ -1602,6 +1602,7 @@ Serverless deployment dramatically improves reliability and scalability by split To enable building serverless functions you have to enable the `serverless` build `target` in `next.config.js`: ```js +// next.config.js module.exports = { target: 'serverless' } @@ -1620,9 +1621,11 @@ export function render(req: http.IncomingMessage, res: http.ServerResponse) => v - [http.IncomingMessage](https://nodejs.org/api/http.html#http_class_http_incomingmessage) - [http.ServerResponse](https://nodejs.org/api/http.html#http_class_http_serverresponse) -- `void` refers to the function not having a return value. Calling the function will finish the request. +- void refers to the function not having a return value. Calling the function will finish the request. + +Next.js provides low-level APIs for Serverless as hosting platforms have different function signatures. In general you will want to wrap the output of a Next.js Serverless build with a compatability layer. -Example usage with [`http.Server`](https://nodejs.org/api/http.html#http_class_http_server): +For example if the platform supports the Node.js [`http.Server`](https://nodejs.org/api/http.html#http_class_http_server) class: ```js const http = require('http') @@ -1631,21 +1634,18 @@ const server = new http.Server((req, res) => page.render(req, res)) server.listen(3000, () => console.log('Listening on http://localhost:3000')) ``` -Next.js provides low-level APIs for serverless as platforms have different function signatures. These APIs allow the user to implement Next.js on any serverless platform. - -Generally, you will want to wrap the Next.js serverless build output to interoperate between your deployment platform and the Next.js serverless function. - -Examples of automatically created Serverless deployments: - -- [Now v2 with `@now/next` builder](https://github.com/zeit/now-examples/tree/master/nextjs) +For specific platform examples see [the examples section above](#serverless-deployment). To summarize: -- Every page becomes a serverless function -- The serverless function has 0 dependencies (they're all inlined) -- Uses the req and res coming from Node.js -- opt-in using target: 'serverless' in next.config.js -- Does not load next.config.js when executing the function, note that this means `publicRuntimeConfig` / `serverRuntimeConfig` are not supported. +- Low-level API for implementing Serverless deployment +- Every page in the `pages` directory becomes a serverless function +- Creates the smallest possible Serverless function (50Kb base zip size) +- Optimized for fast cold start of the function +- The serverless function has 0 dependencies (they are included in the function bundle) +- Uses the [http.IncomingMessage](https://nodejs.org/api/http.html#http_class_http_incomingmessage) and [http.ServerResponse](https://nodejs.org/api/http.html#http_class_http_serverresponse) from Node.js +- opt-in using `target: 'serverless'` in `next.config.js` +- Does not load `next.config.js` when executing the function, note that this means `publicRuntimeConfig` / `serverRuntimeConfig` are not supported ## Browser support From 0b92f5d1874f0c2caa9ca14ff3c369b11bd75387 Mon Sep 17 00:00:00 2001 From: Tim Neutkens <timneutkens@me.com> Date: Thu, 17 Jan 2019 16:02:54 +0100 Subject: [PATCH 12/12] Add quotes --- packages/next/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/next/README.md b/packages/next/README.md index a7bbd8fc5f05f..5f769a871fa41 100644 --- a/packages/next/README.md +++ b/packages/next/README.md @@ -1621,7 +1621,7 @@ export function render(req: http.IncomingMessage, res: http.ServerResponse) => v - [http.IncomingMessage](https://nodejs.org/api/http.html#http_class_http_incomingmessage) - [http.ServerResponse](https://nodejs.org/api/http.html#http_class_http_serverresponse) -- void refers to the function not having a return value. Calling the function will finish the request. +- `void` refers to the function not having a return value. Calling the function will finish the request. Next.js provides low-level APIs for Serverless as hosting platforms have different function signatures. In general you will want to wrap the output of a Next.js Serverless build with a compatability layer.