Repository: sveltejs/kit
Pull request #4922 (2022-05-14 04:43:32)

[breaking] drop Node 14 support
closes https://github.com/sveltejs/kit/issues/4916

changeset-bot[bot]: ###  🦋  Changeset detected

Latest commit: b994439a8d58dcad2044de6afdd7ca43d1db3353

**The changes in this PR will be included in the next version bump.**

<details><summary>This PR includes changesets to release 2 packages</summary>

  | Name                     | Type  |
| ------------------------ | ----- |
| @sveltejs/adapter-vercel | Patch |
| @sveltejs/kit            | Patch |

</details>

Not sure what this means? [Click here  to learn what changesets are](https://github.com/changesets/changesets/blob/master/docs/adding-a-changeset.md).

[Click here if you're a maintainer who wants to add another changeset to this PR](https://github.com/sveltejs/kit/new/rm-node-14?filename=.changeset/kind-adults-remember.md&value=---%0A%22%40sveltejs%2Fadapter-vercel%22%3A%20patch%0A%22%40sveltejs%2Fkit%22%3A%20patch%0A---%0A%0A%5Bbreaking%5D%20drop%20Node%2014%20support%0A)



Patch:
diff --git a/.changeset/honest-rats-double.md b/.changeset/honest-rats-double.md
new file mode 100644
index 000000000..db9ce8583
--- /dev/null
+++ b/.changeset/honest-rats-double.md
@@ -0,0 +1,5 @@
+---
+"@sveltejs/adapter-netlify": patch
+---
+
+[docs] explain how to change node version
diff --git a/.changeset/lemon-oranges-pump.md b/.changeset/lemon-oranges-pump.md
new file mode 100644
index 000000000..aca141158
--- /dev/null
+++ b/.changeset/lemon-oranges-pump.md
@@ -0,0 +1,6 @@
+---
+'@sveltejs/adapter-vercel': patch
+'@sveltejs/kit': patch
+---
+
+[breaking] drop Node 14 support
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 369498501..bf14f8024 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -18,7 +18,7 @@ jobs:
       - uses: pnpm/action-setup@v2.2.1
       - uses: actions/setup-node@v3
         with:
-          node-version: '14.x'
+          node-version: '16.x'
           cache: pnpm
       - run: pnpm install --frozen-lockfile
       - run: pnpm turbo run lint check
@@ -28,11 +28,9 @@ jobs:
     strategy:
       fail-fast: false
       matrix:
-        node-version: [14]
+        node-version: [16]
         os: [ubuntu-latest, macOS-latest, windows-2019]
         include:
-          - node-version: 16
-            os: ubuntu-latest
           - node-version: 18
             os: ubuntu-latest
     env:
diff --git a/documentation/docs/02-routing.md b/documentation/docs/02-routing.md
index 039bc5ac4..f7051a78a 100644
--- a/documentation/docs/02-routing.md
+++ b/documentation/docs/02-routing.md
@@ -25,6 +25,8 @@ The filename determines the route. For example, `src/routes/index.svelte` is the
 </svelte:head>
 
 <h1>Hello and welcome to my site!</h1>
+
+<a href="/about">About my site</a>
 ```
 
 A file called either `src/routes/about.svelte` or `src/routes/about/index.svelte` would correspond to the `/about` route:
@@ -37,8 +39,12 @@ A file called either `src/routes/about.svelte` or `src/routes/about/index.svelte
 
 <h1>About this site</h1>
 <p>TODO...</p>
+
+<a href="/">Home</a>
 ```
 
+> Note that SvelteKit uses `<a>` elements to navigate between routes, rather than a framework-specific `<Link>` component.
+
 Dynamic parameters are encoded using `[brackets]`. For example, a blog post might be defined by `src/routes/blog/[slug].svelte`. These parameters can be accessed in a [`load`](/docs/loading#input-params) function or via the [`page`](/docs/modules#$app-stores) store.
 
 A file or directory can have multiple dynamic parts, like `[id]-[category].svelte`. (Parameters are 'non-greedy'; in an ambiguous case like `x-y-z`, `id` would be `x` and `category` would be `y-z`.)
diff --git a/packages/adapter-netlify/README.md b/packages/adapter-netlify/README.md
index 75897126f..681a0ba65 100644
--- a/packages/adapter-netlify/README.md
+++ b/packages/adapter-netlify/README.md
@@ -42,6 +42,10 @@ Then, make sure you have a [netlify.toml](https://docs.netlify.com/configure-bui
 
 If the `netlify.toml` file or the `build.publish` value is missing, a default value of `"build"` will be used. Note that if you have set the publish directory in the Netlify UI to something else then you will need to set it in `netlify.toml` too, or use the default value of `"build"`.
 
+### Node version
+
+New projects will use Node 16 by default. However, if you're upgrading a project you created a while ago it may be stuck on an older version. See [the Netlify docs](https://docs.netlify.com/configure-builds/manage-dependencies/#node-js-and-javascript) for details on manually specifying Node 16 or newer.
+
 ## Netlify Edge Functions (beta)
 
 SvelteKit supports the beta release of Netlify Edge Functions. If you pass the option `edge: true` to the `adapter` function, server-side rendering will happen in a Deno-based edge function that's deployed close to the site visitor. If set to `false` (the default), the site will deploy to standard Node-based Netlify Functions.
diff --git a/packages/adapter-vercel/README.md b/packages/adapter-vercel/README.md
index 34a0999fb..7095c12b7 100644
--- a/packages/adapter-vercel/README.md
+++ b/packages/adapter-vercel/README.md
@@ -6,7 +6,7 @@ If you're using [adapter-auto](../adapter-auto), you don't need to install this
 
 ## Usage
 
-> The `edge` and `split` options depend on the Vercel Build Output API which is currently in beta. For now, you must opt in by visiting `https://vercel.com/svelte/[YOUR_PROJECT]/settings/environment-variables` and adding `ENABLE_VC_BUILD` with the value `1`.
+> The `edge` and `split` options depend on the Vercel Build Output API which is currently in beta. For now, you must opt in by visiting `https://vercel.com/[YOUR_USERNAME]/[YOUR_PROJECT]/settings/environment-variables` and adding `ENABLE_VC_BUILD` with the value `1`.
 
 Add `"@sveltejs/adapter-vercel": "next"` to the `devDependencies` in your `package.json` and run `npm install`.
 
diff --git a/packages/adapter-vercel/index.js b/packages/adapter-vercel/index.js
index e246c8891..0cd43b209 100644
--- a/packages/adapter-vercel/index.js
+++ b/packages/adapter-vercel/index.js
@@ -395,8 +395,8 @@ function get_node_version() {
 	const full = process.version.slice(1); // 'v16.5.0' --> '16.5.0'
 	const major = parseInt(full.split('.')[0]); // '16.5.0' --> 16
 
-	if (major < 14) {
-		throw new Error(`SvelteKit only support Node.js version 14 or greater (currently using v${full}). Consult the documentation: https://vercel.com/docs/runtimes#official-runtimes/node-js/node-js-version`)
+	if (major < 16) {
+		throw new Error(`SvelteKit only supports Node.js version 16 or greater (currently using v${full}). Consult the documentation: https://vercel.com/docs/runtimes#official-runtimes/node-js/node-js-version`)
 	}
 
 	return { major, full };
diff --git a/packages/kit/package.json b/packages/kit/package.json
index 153171b93..592358745 100644
--- a/packages/kit/package.json
+++ b/packages/kit/package.json
@@ -93,6 +93,6 @@
 	},
 	"types": "types/index.d.ts",
 	"engines": {
-		"node": ">=14.13"
+		"node": ">=16"
 	}
 }
diff --git a/packages/kit/src/packaging/index.js b/packages/kit/src/packaging/index.js
index c525ca135..010774db9 100644
--- a/packages/kit/src/packaging/index.js
+++ b/packages/kit/src/packaging/index.js
@@ -109,6 +109,7 @@ export async function watch(config, cwd = process.cwd()) {
 	let timeout;
 
 	const watcher = chokidar.watch(lib, { ignoreInitial: true });
+	const ready = new Promise((resolve) => watcher.on('ready', resolve));
 
 	watcher.on('all', async (type, path) => {
 		const file = analyze(config, relative(lib, path));
@@ -176,6 +177,7 @@ export async function watch(config, cwd = process.cwd()) {
 
 	return {
 		watcher,
+		ready,
 		settled: () =>
 			new Promise((fulfil, reject) => {
 				fulfillers.push(fulfil);


Test patch:
diff --git a/packages/kit/src/packaging/test/index.js b/packages/kit/src/packaging/test/index.js
index ebefaef98..3c818f22b 100644
--- a/packages/kit/src/packaging/test/index.js
+++ b/packages/kit/src/packaging/test/index.js
@@ -154,7 +154,7 @@ if (!process.env.CI) {
 		const config = await load_config({ cwd });
 		config.kit.package.dir = resolve(cwd, config.kit.package.dir);
 
-		const { watcher, settled } = await watch(config, cwd);
+		const { watcher, ready, settled } = await watch(config, cwd);
 
 		/** @param {string} file */
 		function compare(file) {
@@ -181,6 +181,8 @@ if (!process.env.CI) {
 		}
 
 		try {
+			await ready;
+
 			// completes initial build
 			compare('index.js');
 
diff --git a/packages/kit/src/packaging/test/watch/tsconfig.json b/packages/kit/src/packaging/test/watch/tsconfig.json
index bcc299cd9..44dca20d0 100644
--- a/packages/kit/src/packaging/test/watch/tsconfig.json
+++ b/packages/kit/src/packaging/test/watch/tsconfig.json
@@ -1,6 +1,7 @@
 {
 	"compilerOptions": {
 		"allowJs": true,
-		"checkJs": true
+		"checkJs": true,
+		"newLine": "lf"
 	}
 }