**This does not change existing behavior.**
building to serverless is completely opt-in.
- Implements `target: 'serverless'` in `next.config.js`
- Removes `next build --lambdas` (was only available on next@canary so far)
This implements the concept of build targets. Currently there will be 2 build targets:
- server (This is the target that already existed / the default, no changes here)
- serverless (New target aimed at compiling pages to serverless handlers)
The serverless target will output a single file per `page` in the `pages` directory:
- `pages/index.js` => `.next/serverless/index.js`
- `pages/about.js` => `.next/serverless/about.js`
So what is inside `.next/serverless/about.js`? All the code needed to render that specific page. It has the Node.js `http.Server` request handler function signature:
```ts
(req: http.IncomingMessage, res: http.ServerResponse) => void
```
So how do you use it? Generally you **don't** want to use the below example, but for illustration purposes it's shown how the handler is called using a plain `http.Server`:
```js
const http = require('http')
// Note that `.default` is needed because the exported module is an esmodule
const handler = require('./.next/serverless/about.js').default
const server = new http.Server((req, res) => handler(req, res))
server.listen(3000, () => console.log('Listening on http://localhost:3000'))
```
Generally you'll upload this handler function to an external service like [Now v2](https://zeit.co/now-2), the `@now/next` builder will be updated to reflect these changes. This means that it'll be no longer neccesary for `@now/next` to do some of the guesswork in creating smaller handler functions. As Next.js will output the smallest possible serverless handler function automatically.
The function has 0 dependencies so no node_modules are required to run it, and is generally very small. 45Kb zipped is the baseline, but I'm sure we can make it even smaller in the future.
One important thing to note is that the function won't try to load `next.config.js`, so `publicRuntimeConfig` / `serverRuntimeConfig` are not supported. Reasons are outlined here: #5846
So to summarize:
- every page becomes a serverless function
- the serverless function has 0 dependencies (they're all inlined)
- "just" 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
TODO:
- [x] Compile next/dynamic / `import()` into the function file, so that no extra files have to be uploaded.
- [x] Setting `assetPrefix` at build time for serverless target
- [x] Support custom /_app
- [x] Support custom /_document
- [x] Support custom /_error
- [x] Add `next.config.js` property for `target`
Need discussion:
- [ ] Since the serverless target won't support `publicRuntimeConfig` / `serverRuntimeConfig` as they're runtime values. I think we should support build-time env var replacement with webpack.DefinePlugin or similar.
- [ ] Serving static files with the correct cache-control, as there is no static file serving in the serverless target
Resolves#4055
Credit: https://github.com/zeit/next.js/pull/5095
I didn't use the ignore webpack plugin from the original PR and tested bundle size with https://github.com/zeit/next.js/pull/5339 - seems to be safe on that front.
Was able to get tests to pass locally, unsure of what goes wrong in CI 🤷♂️
**Questions**
1) The initial PR didn't include changes to `next-server/lib/router` in `getRouteInfo()`. Should the same changes be made within?
2) Should we add a test for rendering a component created via `forwardRef()`?
`component-with-forwardedRef`:
```javascript
export default React.forwardRef((props, ref) => <span {...props} forwardedRef={ref}>This is a component with a forwarded ref</span>);
```
some test:
```javascript
test('renders from forwardRef', async () => {
const $ = await get$('/component-with-forwardedRef')
const span = $('span')
expect(span.text()).toMatch(/This is a component with a forwarded ref/)
})
```
This message is from @timneutkens after making changes:
- Convert executables to Typescript
- Remove `minimist` in favor of `arg`
- Implement `--node-args` usage: `--node-args="--throw-deprecation"`
- Adds tests for usage of the `next` cli
This PR will
- allow nextjs export to use all available CPU cores for rendering & writing pages by using child_process
- make use of async-sema to allow each thread to concurrently write multiple paths
- show a fancy progress bar while processing pages (with non-TTY fallback for CI web consoles)
The performance gain for my MacBook with 4 CPU cores went from ~25 pages per second to ~75 pages per second. Beefy CI machines with lots of cores should profit even more.
* Move send-html function and rewrite in typescript
* Move getPageFiles and convert to ts
* Move getPageFiles and convert to ts (#5841)
* Move getPageFiles and convert to ts
# Conflicts:
# packages/next-server/server/render.js
* Fix unit tests
- Replaces taskr-babel with taskr-typescript for the `next` package
- Makes sure Node 8+ is used, no unneeded transpilation
- Compile Next.js client side files through babel the same way pages are
- Compile Next.js client side files to esmodules, not commonjs, so that tree shaking works.
- Move error-debug.js out of next-server as it's only used/require in development
- Drop ansi-html as dependency from next-server
- Make next/link esmodule (for tree-shaking)
- Make next/router esmodule (for tree-shaking)
- add typescript compilation to next-server
- Remove last remains of Flow
- Move hoist-non-react-statics to next, out of next-server
- Move htmlescape to next, out of next-server
- Remove runtime-corejs2 from next-server
* Remove flow-typed
* Remove flow types
* Remove the last types
* Bring back taskr dependency
* Revert "Bring back taskr dependency"
This reverts commit 38cb95d7274d63fe63c6ac3c95ca358a28c17895.
* Bring back preset-flow as it’s used for tests
* Revert "Revert "Bring back taskr dependency""
This reverts commit b4c933ef133f4039f544fb10bf31d5c95d3b27a2.
* Update jest
* Let jest start chromedriver
This makes sure chromedriver always ends even if the test was canceled by the user.
* Properly close browser in production-config test
* Properly close browser in production/security test
* Properly close browser in export test
* Properly close browser in app-aspath test
* Remove taskr from project root
This isn’t needed anymore
* Readd taskr to project root (temporary)
* Improve global setup/teardown
* Properly close browser in basic/client-navigation test
Clicking an target=_blank link will open a second browser window. We can only close this by using broser.quit()