Skip to content

feat: remote files can now be in your kit.alias locations #14096

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/deep-tools-stand.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@sveltejs/kit': patch
---

feat: remote files can now be in your kit.alias locations
2 changes: 1 addition & 1 deletion documentation/docs/20-core-concepts/60-remote-functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export default {

## Overview

Remote functions are exported from a `.remote.js` or `.remote.ts` file, and come in four flavours: `query`, `form`, `command` and `prerender`. On the client, the exported functions are transformed to `fetch` wrappers that invoke their counterparts on the server via a generated HTTP endpoint.
Remote functions are exported from a `.remote.js` or `.remote.ts` file, and come in four flavours: `query`, `form`, `command` and `prerender`. On the client, the exported functions are transformed to `fetch` wrappers that invoke their counterparts on the server via a generated HTTP endpoint. You can put these remote files in `lib` or `routes` directory, or any directory that is aliased with the `kit.alias` option.

## query

Expand Down
12 changes: 11 additions & 1 deletion packages/kit/src/core/sync/create_manifest_data/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -481,7 +481,17 @@ function create_remotes(config, cwd) {
const remotes = [];

// TODO could files live in other directories, including node_modules?
for (const dir of [config.kit.files.lib, config.kit.files.routes]) {
const directories = [config.kit.files.lib, config.kit.files.routes];

// Add alias directories
for (const [, alias_path] of Object.entries(config.kit.alias)) {
const resolved_path = path.resolve(cwd, alias_path);
if (fs.existsSync(resolved_path)) {
directories.push(resolved_path);
}
}

for (const dir of directories) {
if (!fs.existsSync(dir)) continue;

for (const file of walk(dir)) {
Expand Down
16 changes: 16 additions & 0 deletions packages/kit/src/core/sync/create_manifest_data/index.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -820,3 +820,19 @@ test('errors with both ts and js handlers for the same route', () => {
/^Multiple endpoint files found in samples\/conflicting-ts-js-handlers-server\/ : \+server\.js and \+server\.ts/
);
});

test('finds remote functions in alias directories', () => {
const { remotes } = create('samples/remotes-with-alias', {
kit: {
experimental: {
remoteFunctions: true
},
alias: {
$modules: './src/modules'
}
}
});

expect(remotes).toHaveLength(1);
expect(remotes[0].file).toBe('samples/remotes-with-alias/src/modules/remotes/hello.remote.js');
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { query } from '$app/server';

export const get_hello = query(() => 'hello world');
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/** @type {import('@sveltejs/kit').Config} */
const config = {
kit: {
experimental: {
remoteFunctions: true
},
alias: {
$modules: './src/modules'
}
}
};

export default config;
5 changes: 5 additions & 0 deletions packages/kit/src/exports/vite/graph_analysis/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { app_server, env_dynamic_private, env_static_private } from '../module_i

const ILLEGAL_IMPORTS = new Set([env_dynamic_private, env_static_private, app_server]);
const ILLEGAL_MODULE_NAME_PATTERN = /.*\.server\..+/;
const REMOTE_FILE_PATTERN = /.*\.remote\..+/;

/**
* Checks if given id imports a module that is not allowed to be imported into client-side code.
Expand All @@ -18,6 +19,10 @@ const ILLEGAL_MODULE_NAME_PATTERN = /.*\.server\..+/;
export function is_illegal(id, dirs) {
if (ILLEGAL_IMPORTS.has(id)) return true;
if (!id.startsWith(dirs.cwd) || id.startsWith(dirs.node_modules)) return false;

// Allow remote functions to be imported on the client side (they get transformed)
if (REMOTE_FILE_PATTERN.test(path.basename(id))) return false;

return ILLEGAL_MODULE_NAME_PATTERN.test(path.basename(id)) || id.startsWith(dirs.server);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { query } from '$app/server';

export const get_hello_from_modules = query(() => 'hello from $modules');
4 changes: 4 additions & 0 deletions packages/kit/test/apps/basics/src/routes/remote/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import { browser } from '$app/environment';
import { refreshAll } from '$app/navigation';
import { add, get_count, set_count, set_count_server } from './query-command.remote.js';
import { get_hello_from_modules } from '$modules/remotes/hello.remote.js';

let { data } = $props();

Expand All @@ -11,6 +12,9 @@
const count = browser ? get_count() : null; // so that we get a remote request in the browser
</script>

{#if browser}
<p id="hello-from-modules">{#await get_hello_from_modules() then result}{result}{/await}</p>
{/if}
<p id="echo-result">{data.echo_result}</p>
<!-- TODO use await here once async lands -->
{#if browser}
Expand Down
4 changes: 4 additions & 0 deletions packages/kit/test/apps/basics/svelte.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ const config = {
remoteFunctions: true
},

alias: {
$modules: './src/modules'
},

prerender: {
entries: [
'*',
Expand Down
5 changes: 5 additions & 0 deletions packages/kit/test/apps/basics/test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1622,6 +1622,11 @@ test.describe('remote functions', () => {
await clicknav('[href="/remote/prerender/functions-only"]');
await expect(page.locator('#prerendered-data')).toHaveText('a c 中文 yes');
});

test('query returns correct data from modules', async ({ page }) => {
await page.goto('/remote');
await expect(page.locator('#hello-from-modules')).toHaveText('hello from $modules');
});
});

test.describe('params prop', () => {
Expand Down
Loading