diff --git a/.changeset/remote-exports-prebundle.md b/.changeset/remote-exports-prebundle.md new file mode 100644 index 000000000000..8feaf30b0ec8 --- /dev/null +++ b/.changeset/remote-exports-prebundle.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/kit': patch +--- + +fix: resolve remote modules as external during dev prebundling so packages can re-export remote functions diff --git a/packages/kit/src/exports/vite/index.js b/packages/kit/src/exports/vite/index.js index c71334b40084..4a6d3d3ccc35 100644 --- a/packages/kit/src/exports/vite/index.js +++ b/packages/kit/src/exports/vite/index.js @@ -12,6 +12,7 @@ import { exactRegex, prefixRegex } from 'rolldown/filter'; import { copy, mkdirp, read, resolve_entry, rimraf } from '../../utils/filesystem.js'; import { posixify } from '../../utils/os.js'; +import { to_fs } from '../../utils/vite.js'; import { create_sveltekit_env, create_sveltekit_env_public, @@ -472,22 +473,27 @@ function kit({ svelte_config }) { } }; - // treat .remote.js files as empty for the purposes of prebundling + // externalize .remote.js files to stop dependency tracing during prebundling if (kit.experimental.remoteFunctions) { // @ts-expect-error optimizeDeps is already set above new_config.optimizeDeps.rolldownOptions ??= {}; // @ts-expect-error new_config.optimizeDeps.rolldownOptions.plugins ??= []; // @ts-expect-error - new_config.optimizeDeps.rolldownOptions.plugins.push({ - name: 'vite-plugin-sveltekit-setup:optimize-remote-functions', - load: { - filter: { id: remote_module_pattern }, - handler() { - return ''; + new_config.optimizeDeps.rolldownOptions.plugins.push( + /** @type {Rolldown.Plugin} */ ({ + name: 'vite-plugin-sveltekit-setup:optimize-remote-functions', + resolveId: { + filter: { id: remote_module_pattern }, + async handler(id, importer) { + const resolved = await this.resolve(id, importer, { skipSelf: true }); + if (!resolved) return { id, external: true }; + // a servable /@fs url; 'absolute' stops rolldown relativizing it in the deps bundle + return { id: to_fs(resolved.id), external: 'absolute' }; + } } - } - }); + }) + ); } const define = { diff --git a/packages/kit/test/apps/async/_test_dependencies/remote-lib/data.remote.js b/packages/kit/test/apps/async/_test_dependencies/remote-lib/data.remote.js new file mode 100644 index 000000000000..80f2cf9816bf --- /dev/null +++ b/packages/kit/test/apps/async/_test_dependencies/remote-lib/data.remote.js @@ -0,0 +1,3 @@ +import { query } from '$app/server'; + +export const lib_echo = query('unchecked', (value) => `lib says ${value}`); diff --git a/packages/kit/test/apps/async/_test_dependencies/remote-lib/index.js b/packages/kit/test/apps/async/_test_dependencies/remote-lib/index.js new file mode 100644 index 000000000000..f4bb682cc0e8 --- /dev/null +++ b/packages/kit/test/apps/async/_test_dependencies/remote-lib/index.js @@ -0,0 +1 @@ +export { lib_echo } from './data.remote.js'; diff --git a/packages/kit/test/apps/async/_test_dependencies/remote-lib/package.json b/packages/kit/test/apps/async/_test_dependencies/remote-lib/package.json new file mode 100644 index 000000000000..5cdb3672b492 --- /dev/null +++ b/packages/kit/test/apps/async/_test_dependencies/remote-lib/package.json @@ -0,0 +1,8 @@ +{ + "name": "e2e-test-dep-remote", + "version": "1.0.0", + "private": true, + "type": "module", + "main": "index.js", + "svelte": "./index.js" +} diff --git a/packages/kit/test/apps/async/package.json b/packages/kit/test/apps/async/package.json index 265697958d8a..d022b7a658a0 100644 --- a/packages/kit/test/apps/async/package.json +++ b/packages/kit/test/apps/async/package.json @@ -21,7 +21,8 @@ "svelte-check": "catalog:", "typescript": "catalog:", "valibot": "catalog:", - "vite": "catalog:" + "vite": "catalog:", + "e2e-test-dep-remote": "file:./_test_dependencies/remote-lib" }, "imports": { "#lib": "./src/lib/index.js", diff --git a/packages/kit/test/apps/async/src/routes/remote-lib/+page.svelte b/packages/kit/test/apps/async/src/routes/remote-lib/+page.svelte new file mode 100644 index 000000000000..90cac358b310 --- /dev/null +++ b/packages/kit/test/apps/async/src/routes/remote-lib/+page.svelte @@ -0,0 +1,10 @@ + + +
{result}
diff --git a/packages/kit/test/apps/async/test/client.test.js b/packages/kit/test/apps/async/test/client.test.js index 8f8e7b1eee0b..e9aa7f118bbe 100644 --- a/packages/kit/test/apps/async/test/client.test.js +++ b/packages/kit/test/apps/async/test/client.test.js @@ -30,6 +30,13 @@ test.describe('remote functions', () => { const response = await response_promise; expect(response.headers()['cache-control']).toBe('private, no-store'); }); + + test('packages can re-export remote functions', async ({ page }) => { + await page.goto('/remote-lib'); + await expect(page.locator('h1')).toHaveText('lib says hello'); + await page.getByRole('button', { name: 'call remote function' }).click(); + await expect(page.locator('p')).toHaveText('lib says client'); + }); }); // have to run in serial because commands mutate in-memory data on the server (should fix this at some point) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ad7b2cfa89ea..f7c1e211b07e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -692,6 +692,9 @@ importers: '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' version: 7.0.0(svelte@5.56.3(@typescript-eslint/types@8.61.1))(vite@8.1.5(@types/node@22.19.19)(esbuild@0.28.1)(jiti@2.4.2)(yaml@2.9.0)) + e2e-test-dep-remote: + specifier: file:./_test_dependencies/remote-lib + version: file:packages/kit/test/apps/async/_test_dependencies/remote-lib svelte: specifier: 'catalog:' version: 5.56.3(@typescript-eslint/types@8.61.1) @@ -3162,6 +3165,9 @@ packages: e2e-test-dep-cjs-only@file:packages/kit/test/apps/dev-only/_test_dependencies/cjs-only: resolution: {directory: packages/kit/test/apps/dev-only/_test_dependencies/cjs-only, type: directory} + e2e-test-dep-remote@file:packages/kit/test/apps/async/_test_dependencies/remote-lib: + resolution: {directory: packages/kit/test/apps/async/_test_dependencies/remote-lib, type: directory} + emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} @@ -5799,6 +5805,8 @@ snapshots: e2e-test-dep-cjs-only@file:packages/kit/test/apps/dev-only/_test_dependencies/cjs-only: {} + e2e-test-dep-remote@file:packages/kit/test/apps/async/_test_dependencies/remote-lib: {} + emoji-regex@8.0.0: {} enhanced-resolve@5.24.0: