Skip to content

Commit 82ae30f

Browse files
authored
fix: prevent code execution order issues around SvelteKit's env modules (#14632)
With #14571 we hoped to have solved the chunk/code execution order issues, but they snuck back in. The problem, it turns out (read https://rollupjs.org/configuration-options/#output-manualchunks very carefully), is that dependencies of a manual chunk might get pulled into that manual chunk, too. If the dependency happens to be our env module, this can cause issues since the module might eagerly access the env. Luckily Rollup has recently solved this via a dedicated option (that will be the default in version 5 and is hence deprecated right away) named `onlyExplicitManualChunks` (rollup/rollup#6087). This solves our problems around chunk ordering. For users not on the latest version yet we do a best-effort fallback by extracting env into its own chunk. This should solve most issues people encounter but the general problem can still occur, which is only fixed with the new option (hence we warn if the rollup version is not up to date). Fixes #14590
1 parent 90eaf07 commit 82ae30f

File tree

2 files changed

+33
-2
lines changed

2 files changed

+33
-2
lines changed

.changeset/light-poets-retire.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@sveltejs/kit': patch
3+
---
4+
5+
fix: prevent code execution order issues around SvelteKit's `env` modules

packages/kit/src/exports/vite/index.js

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ import {
4141
import { import_peer } from '../../utils/import.js';
4242
import { compact } from '../../utils/array.js';
4343
import { should_ignore } from './static_analysis/utils.js';
44+
import { rollupVersion } from 'vite';
4445

4546
const cwd = process.cwd();
4647

@@ -675,6 +676,15 @@ async function kit({ svelte_config }) {
675676
// Set up manualChunks to isolate *.remote.ts files
676677
const { manualChunks } = config.build.rollupOptions.output;
677678

679+
const [major, minor] = rollupVersion.split('.').map(Number);
680+
const is_outdated_rollup = major === 4 && minor < 52;
681+
if (is_outdated_rollup) {
682+
console.warn(
683+
'Rollup >=4.52.0 is recommended when using SvelteKit remote functions as it fixes some bugs related to code-splitting. Current version: ' +
684+
rollupVersion
685+
);
686+
}
687+
678688
config.build.rollupOptions.output = {
679689
...config.build.rollupOptions.output,
680690
manualChunks(id, meta) {
@@ -685,8 +695,19 @@ async function kit({ svelte_config }) {
685695
return `remote-${hash(relative)}`;
686696
}
687697

688-
if (imported_by_remotes.has(id)) {
689-
return `chunk-${uid++}`;
698+
// With onlyExplicitManualChunks Rollup will keep any manual chunk's dependencies out of that chunk.
699+
// This option only exists on more recent Rollup versions; use this as a fallback for older versions.
700+
if (is_outdated_rollup) {
701+
// Prevent core runtime and env from ending up in a remote chunk, which could break because of initialization order
702+
if (id === `${runtime_directory}/app/server/index.js`) {
703+
return 'app-server';
704+
}
705+
if (id === `${runtime_directory}/shared-server.js`) {
706+
return 'app-shared-server';
707+
}
708+
if (imported_by_remotes.has(id)) {
709+
return `chunk-${uid++}`;
710+
}
690711
}
691712

692713
// If there was an existing manualChunks function, call it
@@ -707,6 +728,11 @@ async function kit({ svelte_config }) {
707728
}
708729
}
709730
};
731+
732+
if (!is_outdated_rollup) {
733+
// @ts-expect-error only exists in more recent Rollup versions https://rollupjs.org/configuration-options/#output-onlyexplicitmanualchunks
734+
config.build.rollupOptions.onlyExplicitManualChunks = true;
735+
}
710736
},
711737

712738
configureServer(_dev_server) {

0 commit comments

Comments
 (0)