|
| 1 | +# Runtime development sheet |
| 2 | + |
| 3 | +From: 20. November 2021 |
| 4 | + |
| 5 | +This is a description how the runtime internally works. |
| 6 | + |
| 7 | +## Next.js milestones |
| 8 | + |
| 9 | +### [10.0.9-canary.4](https://github.com/vercel/next.js/releases/tag/v10.0.9-canary.4) - 09 Mar 2021 |
| 10 | + |
| 11 | +Beginning with this version the builder no longer sets the environment variable `NEXT_PRIVATE_TARGET=experimental-serverless-trace` and uses the default `target: server`. |
| 12 | + |
| 13 | +### [10.0.8-canary.15](https://github.com/vercel/next.js/releases/tag/v10.0.8-canary.15) - 03 Mar 2021 |
| 14 | + |
| 15 | +Beginning with this version Next.js uses the `target: server` by default instead of `target: experimental-serverless-trace`. |
| 16 | +This can be overridden by setting the environment variable `NEXT_PRIVATE_TARGET=experimental-serverless-trace` in newer versions of Next.js. |
| 17 | +The path of the server output folder also changed from `.serverless` to `.server` in the build output. |
| 18 | + |
| 19 | +### [9.0.4-canary.1](https://github.com/vercel/next.js/releases/tag/v9.0.4-canary.1) - 06 Aug 2019 |
| 20 | + |
| 21 | +Beginning with with this version, the builder uses `target: experimental-serverless-trace` instead of `target: serverless` when building Next.js. |
| 22 | + |
| 23 | +## Procedure |
| 24 | + |
| 25 | +### 1. Download of files |
| 26 | + |
| 27 | +All source files that are required for the build, are downloaded to a temporary folder before the actual build happens. |
| 28 | +Some third-party packages try to detect a Vercel-like build environment like this, so we need to make sure that the following environment variables are set before staring the build: |
| 29 | + |
| 30 | +``` |
| 31 | +NOW_BUILDER=1 |
| 32 | +VERCEL=1 |
| 33 | +``` |
| 34 | + |
| 35 | +Since the build script is commonly started from outside of the temporary download folder, we have to manually set the `INIT_CWD` environment variable to the temporary download folder. |
| 36 | + |
| 37 | +### 2. Pre-Build |
| 38 | + |
| 39 | +Before running the build, the `package.json` gets customized to ensure that the `next build` command is executed by the builder. |
| 40 | +If the `build` script is not set, it gets overridden with `next build`. |
| 41 | +When the `build` script is already set, then the `build` script is renamed and runs before the actual Next.js build. |
| 42 | + |
| 43 | +It is then detecting if npm or yarn is used and runs the install command of the package manager that is used. |
| 44 | + |
| 45 | +#### Create serverless `next.config.js` |
| 46 | + |
| 47 | +> This step is only executed on Next.js versions `< 10.0.9-canary.4`. |
| 48 | +
|
| 49 | +To set the target option in the `next.config.js`, the original file (if exists) is renamed to `next.config.__vercel_builder_backup__.js`. |
| 50 | +Then a new `next.config.js` is created with the following content: |
| 51 | + |
| 52 | +```js |
| 53 | +module.exports = function (...args) { |
| 54 | + let original = require('./next.config.__vercel_builder_backup__'); |
| 55 | + |
| 56 | + const finalConfig = {}; |
| 57 | + const target = { target: 'experimental-serverless-trace' }; |
| 58 | + |
| 59 | + if ( |
| 60 | + typeof original === 'function' && |
| 61 | + original.constructor.name === 'AsyncFunction' |
| 62 | + ) { |
| 63 | + // AsyncFunctions will become promises |
| 64 | + original = original(...args); |
| 65 | + } |
| 66 | + |
| 67 | + if (original instanceof Promise) { |
| 68 | + // Special case for promises, as it's currently not supported |
| 69 | + // and will just error later on |
| 70 | + return original |
| 71 | + .then((orignalConfig) => Object.assign(finalConfig, orignalConfig)) |
| 72 | + .then((config) => Object.assign(config, target)); |
| 73 | + } else if (typeof original === 'function') { |
| 74 | + Object.assign(finalConfig, original(...args)); |
| 75 | + } else if (typeof original === 'object') { |
| 76 | + Object.assign(finalConfig, original); |
| 77 | + } |
| 78 | + |
| 79 | + Object.assign(finalConfig, target); |
| 80 | + |
| 81 | + return finalConfig; |
| 82 | +}; |
| 83 | +``` |
0 commit comments