From e201fa9380a00e072a80a2dcab56de3d77e5b67c Mon Sep 17 00:00:00 2001 From: Mustafa Taleb Date: Mon, 13 Jan 2025 12:26:22 -0700 Subject: [PATCH] fix: remove ":$" from virtual module ids to allow dev server to work with proxies (#12157) Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com> Co-authored-by: Ben McCann <322311+benmccann@users.noreply.github.com> --- .changeset/eleven-colts-relax.md | 5 ++ .../vite/build/build_service_worker.js | 10 ++-- .../src/exports/vite/graph_analysis/index.js | 24 +-------- .../exports/vite/graph_analysis/index.spec.js | 14 ++++-- packages/kit/src/exports/vite/index.js | 18 +++++-- packages/kit/src/exports/vite/module_ids.js | 10 ++-- packages/kit/src/exports/vite/utils.js | 50 +++++++++++++++++++ 7 files changed, 92 insertions(+), 39 deletions(-) create mode 100644 .changeset/eleven-colts-relax.md diff --git a/.changeset/eleven-colts-relax.md b/.changeset/eleven-colts-relax.md new file mode 100644 index 000000000000..8a73924d8651 --- /dev/null +++ b/.changeset/eleven-colts-relax.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/kit': patch +--- + +fix: remove ":$" from virtual module ids to allow dev server to work with proxies diff --git a/packages/kit/src/exports/vite/build/build_service_worker.js b/packages/kit/src/exports/vite/build/build_service_worker.js index 3b7c1cfe38f9..17eff31066dc 100644 --- a/packages/kit/src/exports/vite/build/build_service_worker.js +++ b/packages/kit/src/exports/vite/build/build_service_worker.js @@ -2,7 +2,7 @@ import fs from 'node:fs'; import * as vite from 'vite'; import { dedent } from '../../../core/sync/utils.js'; import { s } from '../../../utils/misc.js'; -import { get_config_aliases, strip_virtual_prefix, get_env } from '../utils.js'; +import { get_config_aliases, strip_virtual_prefix, get_env, normalize_id } from '../utils.js'; import { create_static_module } from '../../../core/env.js'; import { env_static_public, service_worker } from '../module_ids.js'; @@ -68,7 +68,8 @@ export async function build_service_worker( name: 'service-worker-build-virtual-modules', resolveId(id) { if (id.startsWith('$env/') || id.startsWith('$app/') || id === '$service-worker') { - return `\0virtual:${id}`; + // ids with :$ don't work with reverse proxies like nginx + return `\0virtual:${id.substring(1)}`; } }, @@ -83,7 +84,10 @@ export async function build_service_worker( return create_static_module('$env/static/public', env.public); } - const stripped = strip_virtual_prefix(id); + const normalized_cwd = vite.normalizePath(process.cwd()); + const normalized_lib = vite.normalizePath(kit.files.lib); + const relative = normalize_id(id, normalized_lib, normalized_cwd); + const stripped = strip_virtual_prefix(relative); throw new Error( `Cannot import ${stripped} into service-worker code. Only the modules $service-worker and $env/static/public are available in service workers.` ); diff --git a/packages/kit/src/exports/vite/graph_analysis/index.js b/packages/kit/src/exports/vite/graph_analysis/index.js index a58cc7a72a2a..ecf7ee146769 100644 --- a/packages/kit/src/exports/vite/graph_analysis/index.js +++ b/packages/kit/src/exports/vite/graph_analysis/index.js @@ -1,6 +1,6 @@ import path from 'node:path'; import { posixify } from '../../../utils/filesystem.js'; -import { strip_virtual_prefix } from '../utils.js'; +import { normalize_id, strip_virtual_prefix } from '../utils.js'; import { app_server, env_dynamic_private, env_static_private } from '../module_ids.js'; const ILLEGAL_IMPORTS = new Set([env_dynamic_private, env_static_private, app_server]); @@ -85,25 +85,3 @@ export function module_guard(context, { cwd, lib }) { } }; } - -/** - * Removes cwd/lib path from the start of the id - * @param {string} id - * @param {string} lib - * @param {string} cwd - */ -export function normalize_id(id, lib, cwd) { - if (id.startsWith(lib)) { - id = id.replace(lib, '$lib'); - } - - if (id.startsWith(cwd)) { - id = path.relative(cwd, id); - } - - if (id === app_server) { - return '$app/server'; - } - - return posixify(id); -} diff --git a/packages/kit/src/exports/vite/graph_analysis/index.spec.js b/packages/kit/src/exports/vite/graph_analysis/index.spec.js index d149111f36af..35ecd31feb7b 100644 --- a/packages/kit/src/exports/vite/graph_analysis/index.spec.js +++ b/packages/kit/src/exports/vite/graph_analysis/index.spec.js @@ -1,5 +1,6 @@ import { assert, test } from 'vitest'; import { module_guard } from './index.js'; +import * as module_ids from '../module_ids.js'; /** * @@ -44,7 +45,7 @@ test('throws an error when importing $env/static/private', () => { importedIds: ['~/src/routes/+page.svelte'] }, '~/src/routes/+page.svelte': { - importedIds: ['\0virtual:$env/static/private'] + importedIds: ['\0virtual:env/static/private'] } }, `Cannot import $env/static/private into client-side code: @@ -60,7 +61,7 @@ test('throws an error when dynamically importing $env/static/private', () => { importedIds: ['~/src/routes/+page.svelte'] }, '~/src/routes/+page.svelte': { - dynamicallyImportedIds: ['\0virtual:$env/static/private'] + dynamicallyImportedIds: ['\0virtual:env/static/private'] } }, `Cannot import $env/static/private into client-side code: @@ -76,7 +77,7 @@ test('throws an error when importing $env/dynamic/private', () => { importedIds: ['~/src/routes/+page.svelte'] }, '~/src/routes/+page.svelte': { - importedIds: ['\0virtual:$env/dynamic/private'] + importedIds: ['\0virtual:env/dynamic/private'] } }, `Cannot import $env/dynamic/private into client-side code: @@ -92,7 +93,7 @@ test('throws an error when dynamically importing $env/dynamic/private', () => { importedIds: ['~/src/routes/+page.svelte'] }, '~/src/routes/+page.svelte': { - dynamicallyImportedIds: ['\0virtual:$env/dynamic/private'] + dynamicallyImportedIds: ['\0virtual:env/dynamic/private'] } }, `Cannot import $env/dynamic/private into client-side code: @@ -101,6 +102,11 @@ test('throws an error when dynamically importing $env/dynamic/private', () => { ); }); +// nginx does not process URLs containing the sequence `:$` +test('":$" is not in virtual module ids', () => { + assert.notInclude(Object.values(module_ids).join(''), ':$'); +}); + test('throws an error when importing a .server.js module', () => { check( { diff --git a/packages/kit/src/exports/vite/index.js b/packages/kit/src/exports/vite/index.js index 21bc3d49575f..093a851fb1df 100644 --- a/packages/kit/src/exports/vite/index.js +++ b/packages/kit/src/exports/vite/index.js @@ -15,9 +15,9 @@ import { build_server_nodes } from './build/build_server.js'; import { build_service_worker } from './build/build_service_worker.js'; import { assets_base, find_deps } from './build/utils.js'; import { dev } from './dev/index.js'; -import { is_illegal, module_guard, normalize_id } from './graph_analysis/index.js'; +import { is_illegal, module_guard } from './graph_analysis/index.js'; import { preview } from './preview/index.js'; -import { get_config_aliases, get_env, strip_virtual_prefix } from './utils.js'; +import { get_config_aliases, get_env, normalize_id, strip_virtual_prefix } from './utils.js'; import { write_client_manifest } from '../../core/sync/write_client_manifest.js'; import prerender from '../../core/postbuild/prerender.js'; import analyse from '../../core/postbuild/analyse.js'; @@ -376,8 +376,14 @@ async function kit({ svelte_config }) { parsed_importer.name === parsed_service_worker.name; if (importer_is_service_worker && id !== '$service-worker' && id !== '$env/static/public') { + const normalized_cwd = vite.normalizePath(cwd); + const normalized_lib = vite.normalizePath(kit.files.lib); throw new Error( - `Cannot import ${id} into service-worker code. Only the modules $service-worker and $env/static/public are available in service workers.` + `Cannot import ${normalize_id( + id, + normalized_lib, + normalized_cwd + )} into service-worker code. Only the modules $service-worker and $env/static/public are available in service workers.` ); } @@ -385,7 +391,11 @@ async function kit({ svelte_config }) { } // treat $env/static/[public|private] as virtual - if (id.startsWith('$env/') || id.startsWith('__sveltekit/') || id === '$service-worker') { + if (id.startsWith('$env/') || id === '$service-worker') { + // ids with :$ don't work with reverse proxies like nginx + return `\0virtual:${id.substring(1)}`; + } + if (id.startsWith('__sveltekit/')) { return `\0virtual:${id}`; } }, diff --git a/packages/kit/src/exports/vite/module_ids.js b/packages/kit/src/exports/vite/module_ids.js index 3be16f68a71f..91b5caeddb4f 100644 --- a/packages/kit/src/exports/vite/module_ids.js +++ b/packages/kit/src/exports/vite/module_ids.js @@ -1,11 +1,11 @@ import { fileURLToPath } from 'node:url'; -export const env_static_private = '\0virtual:$env/static/private'; -export const env_static_public = '\0virtual:$env/static/public'; -export const env_dynamic_private = '\0virtual:$env/dynamic/private'; -export const env_dynamic_public = '\0virtual:$env/dynamic/public'; +export const env_static_private = '\0virtual:env/static/private'; +export const env_static_public = '\0virtual:env/static/public'; +export const env_dynamic_private = '\0virtual:env/dynamic/private'; +export const env_dynamic_public = '\0virtual:env/dynamic/public'; -export const service_worker = '\0virtual:$service-worker'; +export const service_worker = '\0virtual:service-worker'; export const sveltekit_environment = '\0virtual:__sveltekit/environment'; export const sveltekit_paths = '\0virtual:__sveltekit/paths'; diff --git a/packages/kit/src/exports/vite/utils.js b/packages/kit/src/exports/vite/utils.js index a4ff95178803..02916e4d85c5 100644 --- a/packages/kit/src/exports/vite/utils.js +++ b/packages/kit/src/exports/vite/utils.js @@ -4,6 +4,14 @@ import { posixify } from '../../utils/filesystem.js'; import { negotiate } from '../../utils/http.js'; import { filter_private_env, filter_public_env } from '../../utils/env.js'; import { escape_html } from '../../utils/escape.js'; +import { + app_server, + env_dynamic_private, + env_dynamic_public, + env_static_private, + env_static_public, + service_worker +} from './module_ids.js'; /** * Transforms kit.alias to a valid vite.resolve.alias array. @@ -105,4 +113,46 @@ export function not_found(req, res, base) { } } +/** + * Removes cwd/lib path from the start of the id + * @param {string} id + * @param {string} lib + * @param {string} cwd + */ +export function normalize_id(id, lib, cwd) { + if (id.startsWith(lib)) { + id = id.replace(lib, '$lib'); + } + + if (id.startsWith(cwd)) { + id = path.relative(cwd, id); + } + + if (id === app_server) { + return '$app/server'; + } + + if (id === env_static_private) { + return '$env/static/private'; + } + + if (id === env_static_public) { + return '$env/static/public'; + } + + if (id === env_dynamic_private) { + return '$env/dynamic/private'; + } + + if (id === env_dynamic_public) { + return '$env/dynamic/public'; + } + + if (id === service_worker) { + return '$service-worker'; + } + + return posixify(id); +} + export const strip_virtual_prefix = /** @param {string} id */ (id) => id.replace('\0virtual:', '');