Repository: sveltejs/kit
Pull request #8818 (2023-01-31 19:12:08)

chore: split dev and build cross-browser tests
Firefox takes twice as long to run as Chrome. By splitting dev and build into two jobs we can run them in parallel and finish twice as fast soling our timeout issues

I also moved the Firefox tests to Ubuntu. Eventhough this means we test an additional variant it reduces our billing because Windows is billed at a higher rate

changeset-bot[bot]: ###  ⚠️  No Changeset found

Latest commit: ee79aa297260dcb24d5469c3cb11cdbced49502c

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. **If these changes should result in a version bump, you need to add a changeset.**

<details><summary>This PR includes no changesets</summary>

  When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

</details>

[Click here to learn what changesets are, and how to add one](https://github.com/changesets/changesets/blob/master/docs/adding-a-changeset.md).

[Click here if you're a maintainer who wants to add a changeset to this PR](https://github.com/sveltejs/kit/new/windows-timeout?filename=.changeset/rare-snails-tie.md&value=---%0A%0A---%0A%0Achore%3A%20bump%20windows%20timeout%20limit%0A)


Rich-Harris: I think we're only crossing the 30 minute threshold when individual tests fail, because we're over-relying on `page.locator` and there's an absurdly large 45 second timeout for individual tests. I'd prefer that we bring that way down (like, 3 seconds should honestly be more than enough) and reduce our usage of `page.locator` to the bare minimum. Otherwise we're just going to go from 'tests cancelled after 30 minutes' to 'tests failed after 35 minutes' (best case) or 'tests cancelled after 45 minutes' (worst case), neither of which is an improvement
Rich-Harris: ok so i stand corrected

<img width="624" alt="image" src="https://user-images.githubusercontent.com/1162160/215869827-1a73a30d-409c-43c8-87bd-48232de59fbf.png">

but still, if we're reaching 40m because flaky tests are only re-running after sitting around uselessly for 45 seconds, then we should stop them from sitting around uselessly for 45 seconds

Patch:
diff --git a/.changeset/bright-moles-worry.md b/.changeset/bright-moles-worry.md
deleted file mode 100644
index 702cd71ab..000000000
--- a/.changeset/bright-moles-worry.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@sveltejs/kit': patch
----
-
-fix: only show prerendering message when actually prerendering
diff --git a/.changeset/hip-eggs-raise.md b/.changeset/hip-eggs-raise.md
deleted file mode 100644
index 3220a0bef..000000000
--- a/.changeset/hip-eggs-raise.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@sveltejs/kit': patch
----
-
-fix: handle anchors with special chars when navigating
diff --git a/.changeset/hot-adults-peel.md b/.changeset/hot-adults-peel.md
new file mode 100644
index 000000000..c763e9a2f
--- /dev/null
+++ b/.changeset/hot-adults-peel.md
@@ -0,0 +1,5 @@
+---
+'@sveltejs/kit': patch
+---
+
+fix: remove Vite manifest before running adapter
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index ce20c4a0e..242087c1b 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -77,10 +77,28 @@ jobs:
         include:
           - node-version: 16
             os: windows-2019 # slowness reported on newer versions https://github.com/actions/runner-images/issues/5166
+            e2e-browser: 'chromium'
+            mode: 'dev'
+          - node-version: 16
+            os: ubuntu-latest
+            e2e-browser: 'firefox'
+            mode: 'dev'
+          - node-version: 16
+            os: macOS-latest
+            e2e-browser: 'webkit'
+            mode: 'dev'
+          - node-version: 16
+            os: windows-2019 # slowness reported on newer versions https://github.com/actions/runner-images/issues/5166
+            e2e-browser: 'chromium'
+            mode: 'build'
+          - node-version: 16
+            os: ubuntu-latest
             e2e-browser: 'firefox'
+            mode: 'build'
           - node-version: 16
             os: macOS-latest
             e2e-browser: 'webkit'
+            mode: 'build'
     env:
       KIT_E2E_BROWSER: ${{matrix.e2e-browser}}
     steps:
@@ -93,15 +111,15 @@ jobs:
           cache: pnpm
       - run: pnpm install --frozen-lockfile
       - run: pnpm playwright install ${{ matrix.e2e-browser }}
-      - run: pnpm test:cross-platform
+      - run: pnpm test:cross-platform:${{ matrix.mode }}
       - name: Archive test results
         if: failure()
         shell: bash
-        run: find packages -type d -name test-results -not -empty | tar -czf test-results-cross-platform.tar.gz --files-from=-
+        run: find packages -type d -name test-results -not -empty | tar -czf test-results-cross-platform-${{ matrix.mode }}.tar.gz --files-from=-
       - name: Upload test results
         if: failure()
         uses: actions/upload-artifact@v3
         with:
           retention-days: 3
-          name: test-failure-cross-platform-${{ github.run_id }}-${{ matrix.os }}-${{ matrix.node-version }}-${{ matrix.e2e-browser }}
-          path: test-results-cross-platform.tar.gz
+          name: test-failure-cross-platform-${{ matrix.mode }}-${{ github.run_id }}-${{ matrix.os }}-${{ matrix.node-version }}-${{ matrix.e2e-browser }}
+          path: test-results-cross-platform-${{ matrix.mode }}.tar.gz
diff --git a/documentation/docs/25-build-and-deploy/90-adapter-vercel.md b/documentation/docs/25-build-and-deploy/90-adapter-vercel.md
index 549740268..bcf38cac2 100644
--- a/documentation/docs/25-build-and-deploy/90-adapter-vercel.md
+++ b/documentation/docs/25-build-and-deploy/90-adapter-vercel.md
@@ -25,7 +25,9 @@ export default {
 			edge: false,
 
 			// an array of dependencies that esbuild should treat
-			// as external when bundling functions
+			// as external when bundling functions. this only applies
+			// to edge functions, and should only be used to exclude
+			// optional dependencies that will not run outside Node
 			external: [],
 
 			// if true, will split your app into multiple functions
diff --git a/package.json b/package.json
index c9236e32f..c965b657b 100644
--- a/package.json
+++ b/package.json
@@ -5,7 +5,8 @@
 	"private": true,
 	"scripts": {
 		"test": "pnpm test -r --filter=./packages/*",
-		"test:cross-platform": "pnpm -r test:cross-platform --filter=./packages/*",
+		"test:cross-platform:dev": "pnpm run --dir packages/kit test:cross-platform:dev",
+		"test:cross-platform:build": "pnpm run --dir packages/kit test:cross-platform:build",
 		"test:vite-ecosystem-ci": "pnpm test --dir packages/kit",
 		"check": "pnpm -r check",
 		"lint": "pnpm -r lint",
@@ -36,7 +37,7 @@
 		"tiny-glob": "^0.2.9",
 		"typescript": "^4.9.4"
 	},
-	"packageManager": "pnpm@7.26.2",
+	"packageManager": "pnpm@7.26.3",
 	"engines": {
 		"pnpm": "^7.0.0"
 	},
diff --git a/packages/kit/CHANGELOG.md b/packages/kit/CHANGELOG.md
index 3031863b2..4a9aa2cf9 100644
--- a/packages/kit/CHANGELOG.md
+++ b/packages/kit/CHANGELOG.md
@@ -1,5 +1,15 @@
 # @sveltejs/kit
 
+## 1.3.7
+
+### Patch Changes
+
+- fix: only show prerendering message when actually prerendering ([#8809](https://github.com/sveltejs/kit/pull/8809))
+
+- fix: handle anchors with special chars when navigating ([#8806](https://github.com/sveltejs/kit/pull/8806))
+
+- fix: await finalise hook and run it only once ([#8817](https://github.com/sveltejs/kit/pull/8817))
+
 ## 1.3.6
 
 ### Patch Changes
diff --git a/packages/kit/package.json b/packages/kit/package.json
index d29bd42cf..c6aeabcb7 100644
--- a/packages/kit/package.json
+++ b/packages/kit/package.json
@@ -1,6 +1,6 @@
 {
 	"name": "@sveltejs/kit",
-	"version": "1.3.6",
+	"version": "1.3.7",
 	"repository": {
 		"type": "git",
 		"url": "https://github.com/sveltejs/kit",
@@ -65,7 +65,8 @@
 		"format": "pnpm lint --write",
 		"test": "pnpm test:unit && pnpm test:integration",
 		"test:integration": "pnpm -r --workspace-concurrency 1 --filter=\"./test/**\" test",
-		"test:cross-platform": "pnpm test:unit && pnpm -r --workspace-concurrency 1 --filter=\"./test/**\" test:cross-platform",
+		"test:cross-platform:dev": "pnpm -r --workspace-concurrency 1 --filter=\"./test/**\" test:cross-platform:dev",
+		"test:cross-platform:build": "pnpm test:unit && pnpm -r --workspace-concurrency 1 --filter=\"./test/**\" test:cross-platform:build",
 		"test:unit": "uvu src \"(spec\\.js|test[\\\\/]index\\.js)\"",
 		"postinstall": "node postinstall.js"
 	},
diff --git a/packages/kit/src/exports/vite/index.js b/packages/kit/src/exports/vite/index.js
index 07a1b9a06..e313cf812 100644
--- a/packages/kit/src/exports/vite/index.js
+++ b/packages/kit/src/exports/vite/index.js
@@ -139,10 +139,7 @@ export async function sveltekit() {
 	return [...svelte(vite_plugin_svelte_options), ...kit({ svelte_config })];
 }
 
-/**
- * If `true`, the server build has been completed and we're creating the client build
- */
-let secondary_build = false;
+let secondary_build_started = false;
 
 /**
  * Returns the SvelteKit Vite plugin. Vite executes Rollup hooks as well as some of its own.
@@ -176,8 +173,8 @@ function kit({ svelte_config }) {
 	/** @type {{ public: Record<string, string>; private: Record<string, string> }} */
 	let env;
 
-	/** @type {(() => Promise<void>) | null} */
-	let finalise = null;
+	/** @type {() => Promise<void>} */
+	let finalise;
 
 	const service_worker_entry_file = resolve_entry(kit.files.serviceWorker);
 
@@ -251,7 +248,7 @@ function kit({ svelte_config }) {
 
 			if (is_build) {
 				if (!new_config.build) new_config.build = {};
-				new_config.build.ssr = !secondary_build;
+				new_config.build.ssr = !secondary_build_started;
 
 				new_config.define = {
 					__SVELTEKIT_ADAPTER_NAME__: JSON.stringify(kit.adapter?.name),
@@ -363,7 +360,7 @@ function kit({ svelte_config }) {
 		writeBundle: {
 			sequential: true,
 			async handler(_options) {
-				if (!secondary_build) return;
+				if (vite_config.build.ssr) return;
 
 				const guard = module_guard(this, {
 					cwd: vite.normalizePath(process.cwd()),
@@ -535,10 +532,7 @@ function kit({ svelte_config }) {
 		 * Clears the output directories.
 		 */
 		buildStart() {
-			if (secondary_build) return;
-
-			// reset (here, not in `config`, because `build --watch` skips `config`)
-			finalise = null;
+			if (secondary_build_started) return;
 
 			if (is_build) {
 				if (!vite_config.build.watch) {
@@ -549,7 +543,7 @@ function kit({ svelte_config }) {
 		},
 
 		generateBundle() {
-			if (!secondary_build) return;
+			if (vite_config.build.ssr) return;
 
 			this.emitFile({
 				type: 'asset',
@@ -566,8 +560,7 @@ function kit({ svelte_config }) {
 		writeBundle: {
 			sequential: true,
 			async handler(_options) {
-				if (secondary_build) return; // only run this once
-				secondary_build = true;
+				if (secondary_build_started) return; // only run this once
 
 				const verbose = vite_config.logLevel === 'info';
 				const log = logger({ verbose });
@@ -615,6 +608,8 @@ function kit({ svelte_config }) {
 					metadata.nodes
 				);
 
+				secondary_build_started = true;
+
 				const { output } = /** @type {import('rollup').RollupOutput} */ (
 					await vite.build({
 						configFile: vite_config.configFile,
@@ -698,6 +693,10 @@ function kit({ svelte_config }) {
 							.cyan('npm run preview')} to preview your production build locally.`
 					);
 
+					// avoid making the manifest available to users
+					fs.unlinkSync(`${out}/client/${vite_config.build.manifest}`);
+					fs.unlinkSync(`${out}/server/${vite_config.build.manifest}`);
+
 					if (kit.adapter) {
 						const { adapt } = await import('../../core/adapt/index.js');
 						await adapt(svelte_config, build_data, metadata, prerendered, prerender_map, log);
@@ -709,10 +708,6 @@ function kit({ svelte_config }) {
 							`See ${link} to learn how to configure your app to run on the platform of your choosing`
 						);
 					}
-
-					// avoid making the manifest available to users
-					fs.unlinkSync(`${out}/client/${vite_config.build.manifest}`);
-					fs.unlinkSync(`${out}/server/${vite_config.build.manifest}`);
 				};
 			}
 		},
@@ -723,7 +718,8 @@ function kit({ svelte_config }) {
 		closeBundle: {
 			sequential: true,
 			async handler() {
-				finalise?.();
+				if (!vite_config.build.ssr) return;
+				await finalise();
 			}
 		}
 	};
diff --git a/packages/kit/src/runtime/client/client.js b/packages/kit/src/runtime/client/client.js
index 0369e2710..4db7fce48 100644
--- a/packages/kit/src/runtime/client/client.js
+++ b/packages/kit/src/runtime/client/client.js
@@ -723,23 +723,22 @@ export function create_client({ target, base }) {
 		const url_changed = current.url ? id !== current.url.pathname + current.url.search : false;
 		const route_changed = current.route ? route.id !== current.route.id : false;
 
-		const invalid_server_nodes = loaders.reduce((acc, loader, i) => {
+		let parent_invalid = false;
+		const invalid_server_nodes = loaders.map((loader, i) => {
 			const previous = current.branch[i];
 
 			const invalid =
 				!!loader?.[0] &&
 				(previous?.loader !== loader[1] ||
-					has_changed(
-						acc.some(Boolean),
-						route_changed,
-						url_changed,
-						previous.server?.uses,
-						params
-					));
-
-			acc.push(invalid);
-			return acc;
-		}, /** @type {boolean[]} */ ([]));
+					has_changed(parent_invalid, route_changed, url_changed, previous.server?.uses, params));
+
+			if (invalid) {
+				// For the next one
+				parent_invalid = true;
+			}
+
+			return invalid;
+		});
 
 		if (invalid_server_nodes.some(Boolean)) {
 			try {
diff --git a/packages/kit/types/internal.d.ts b/packages/kit/types/internal.d.ts
index 32f384b42..17d03141f 100644
--- a/packages/kit/types/internal.d.ts
+++ b/packages/kit/types/internal.d.ts
@@ -75,8 +75,8 @@ export type CSRRoute = {
 	id: string;
 	exec(path: string): undefined | Record<string, string>;
 	errors: Array<CSRPageNodeLoader | undefined>;
-	layouts: Array<[boolean, CSRPageNodeLoader] | undefined>;
-	leaf: [boolean, CSRPageNodeLoader];
+	layouts: Array<[has_server_load: boolean, node_loader: CSRPageNodeLoader] | undefined>;
+	leaf: [has_server_load: boolean, node_loader: CSRPageNodeLoader];
 };
 
 export type GetParams = (match: RegExpExecArray) => Record<string, string>;


Test patch:
diff --git a/packages/kit/test/apps/basics/package.json b/packages/kit/test/apps/basics/package.json
index 2b602cbf6..5941e968a 100644
--- a/packages/kit/test/apps/basics/package.json
+++ b/packages/kit/test/apps/basics/package.json
@@ -10,7 +10,6 @@
 		"test": "node test/setup.js && pnpm test:dev && pnpm test:build",
 		"test:dev": "rimraf test/errors.json && cross-env DEV=true playwright test",
 		"test:build": "rimraf test/errors.json && playwright test",
-		"test:cross-platform": "npm run test:cross-platform:dev && npm run test:cross-platform:build",
 		"test:cross-platform:dev": "node test/setup.js && rimraf test/errors.json && cross-env DEV=true playwright test test/cross-platform/",
 		"test:cross-platform:build": "node test/setup.js && rimraf test/errors.json && playwright test test/cross-platform/"
 	},
diff --git a/packages/kit/test/build-errors/package.json b/packages/kit/test/build-errors/package.json
index e294d46ed..849aa371b 100644
--- a/packages/kit/test/build-errors/package.json
+++ b/packages/kit/test/build-errors/package.json
@@ -4,7 +4,7 @@
 	"version": "0.0.0-next.0",
 	"scripts": {
 		"test": "uvu . \"(spec\\.js|test[\\\\/]index\\.js)\"",
-		"test:cross-platform": "uvu . \"(spec\\.js|test[\\\\/]index\\.js)\""
+		"test:cross-platform:build": "uvu . \"(spec\\.js|test[\\\\/]index\\.js)\""
 	},
 	"type": "module",
 	"devDependencies": {