diff --git a/.changeset/slow-files-stare.md b/.changeset/slow-files-stare.md new file mode 100644 index 000000000000..e68f7eaee10f --- /dev/null +++ b/.changeset/slow-files-stare.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/kit': patch +--- + +[fix] allow SvelteKit to be used without bundling diff --git a/packages/kit/package.json b/packages/kit/package.json index 12e0eb45144f..f1cf41c77678 100644 --- a/packages/kit/package.json +++ b/packages/kit/package.json @@ -14,6 +14,7 @@ "@types/cookie": "^0.5.1", "cookie": "^0.5.0", "devalue": "^4.2.0", + "esm-env": "^1.0.0", "kleur": "^4.1.5", "magic-string": "^0.27.0", "mime": "^3.0.0", diff --git a/packages/kit/src/exports/index.js b/packages/kit/src/exports/index.js index 9efee4666bfa..63326a7fbcbf 100644 --- a/packages/kit/src/exports/index.js +++ b/packages/kit/src/exports/index.js @@ -1,4 +1,5 @@ import { HttpError, Redirect, ActionFailure } from '../runtime/control.js'; +import { BROWSER, DEV } from 'esm-env'; // For some reason we need to type the params as well here, // JSdoc doesn't seem to like @type with function overloads @@ -8,10 +9,7 @@ import { HttpError, Redirect, ActionFailure } from '../runtime/control.js'; * @param {any} message */ export function error(status, message) { - if ( - (!__SVELTEKIT_BROWSER__ || __SVELTEKIT_DEV__) && - (isNaN(status) || status < 400 || status > 599) - ) { + if ((!BROWSER || DEV) && (isNaN(status) || status < 400 || status > 599)) { throw new Error(`HTTP error status codes must be between 400 and 599 — ${status} is invalid`); } @@ -20,10 +18,7 @@ export function error(status, message) { /** @type {import('@sveltejs/kit').redirect} */ export function redirect(status, location) { - if ( - (!__SVELTEKIT_BROWSER__ || __SVELTEKIT_DEV__) && - (isNaN(status) || status < 300 || status > 308) - ) { + if ((!BROWSER || DEV) && (isNaN(status) || status < 300 || status > 308)) { throw new Error('Invalid status code'); } diff --git a/packages/kit/src/exports/vite/build/utils.js b/packages/kit/src/exports/vite/build/utils.js index 00877dc383d3..1d2a49743cd1 100644 --- a/packages/kit/src/exports/vite/build/utils.js +++ b/packages/kit/src/exports/vite/build/utils.js @@ -146,8 +146,6 @@ export function get_default_build_config({ config, input, ssr, outDir }) { __SVELTEKIT_ADAPTER_NAME__: JSON.stringify(config.kit.adapter?.name), __SVELTEKIT_APP_VERSION_FILE__: JSON.stringify(`${config.kit.appDir}/version.json`), __SVELTEKIT_APP_VERSION_POLL_INTERVAL__: JSON.stringify(config.kit.version.pollInterval), - __SVELTEKIT_BROWSER__: ssr ? 'false' : 'true', - __SVELTEKIT_DEV__: 'false', __SVELTEKIT_EMBEDDED__: config.kit.embedded ? 'true' : 'false' }, publicDir: ssr ? false : config.kit.files.assets, diff --git a/packages/kit/src/exports/vite/dev/index.js b/packages/kit/src/exports/vite/dev/index.js index aba100ef3fa6..56e148509134 100644 --- a/packages/kit/src/exports/vite/dev/index.js +++ b/packages/kit/src/exports/vite/dev/index.js @@ -26,12 +26,6 @@ const cwd = process.cwd(); export async function dev(vite, vite_config, svelte_config) { installPolyfills(); - // @ts-expect-error - globalThis.__SVELTEKIT_BROWSER__ = false; - - // @ts-expect-error - globalThis.__SVELTEKIT_DEV__ = true; - sync.init(svelte_config, vite_config.mode); /** @type {import('types').Respond} */ diff --git a/packages/kit/src/exports/vite/index.js b/packages/kit/src/exports/vite/index.js index 78221d9d30e6..729c51017a2a 100644 --- a/packages/kit/src/exports/vite/index.js +++ b/packages/kit/src/exports/vite/index.js @@ -261,8 +261,6 @@ function kit({ svelte_config }) { }, define: { __SVELTEKIT_APP_VERSION_POLL_INTERVAL__: '0', - __SVELTEKIT_BROWSER__: config_env.ssrBuild ? 'false' : 'true', - __SVELTEKIT_DEV__: 'true', __SVELTEKIT_EMBEDDED__: svelte_config.kit.embedded ? 'true' : 'false' }, publicDir: svelte_config.kit.files.assets, diff --git a/packages/kit/src/runtime/app/environment.js b/packages/kit/src/runtime/app/environment.js index b8f69708afae..e9a45aed151f 100644 --- a/packages/kit/src/runtime/app/environment.js +++ b/packages/kit/src/runtime/app/environment.js @@ -1,11 +1,13 @@ +import { BROWSER, DEV } from 'esm-env'; + /** * @type {import('$app/environment').browser} */ -export const browser = !import.meta.env.SSR; +export const browser = BROWSER; /** * @type {import('$app/environment').dev} */ -export const dev = __SVELTEKIT_DEV__; +export const dev = DEV; export { building, version } from '../env.js'; diff --git a/packages/kit/src/runtime/app/forms.js b/packages/kit/src/runtime/app/forms.js index 841c78c54475..734f91b993da 100644 --- a/packages/kit/src/runtime/app/forms.js +++ b/packages/kit/src/runtime/app/forms.js @@ -1,6 +1,7 @@ import * as devalue from 'devalue'; import { client } from '../client/singletons.js'; import { invalidateAll } from './navigation.js'; +import { BROWSER, DEV } from 'esm-env'; /** * @param {string} name @@ -11,10 +12,8 @@ function guard(name) { }; } -const ssr = import.meta.env.SSR; - /** @type {import('$app/forms').applyAction} */ -export const applyAction = ssr ? guard('applyAction') : client.apply_action; +export const applyAction = BROWSER ? client.apply_action : guard('applyAction'); /** @type {import('$app/forms').deserialize} */ export function deserialize(result) { @@ -27,7 +26,7 @@ export function deserialize(result) { /** @type {import('$app/forms').enhance} */ export function enhance(form, submit = () => {}) { - if (__SVELTEKIT_DEV__ && form.method !== 'post') { + if (DEV && form.method !== 'post') { throw new Error('use:enhance can only be used on
fields with method="POST"'); } diff --git a/packages/kit/src/runtime/app/navigation.js b/packages/kit/src/runtime/app/navigation.js index 7104f54d13cd..a7e8b75ecb17 100644 --- a/packages/kit/src/runtime/app/navigation.js +++ b/packages/kit/src/runtime/app/navigation.js @@ -1,3 +1,4 @@ +import { BROWSER } from 'esm-env'; import { client } from '../client/singletons.js'; /** @@ -9,18 +10,16 @@ function guard(name) { }; } -const ssr = import.meta.env.SSR; - -export const disableScrollHandling = ssr - ? guard('disableScrollHandling') - : client.disable_scroll_handling; -export const goto = ssr ? guard('goto') : client.goto; -export const invalidate = ssr ? guard('invalidate') : client.invalidate; -export const invalidateAll = ssr ? guard('invalidateAll') : client.invalidateAll; -export const preloadData = ssr ? guard('preloadData') : client.preload_data; -export const preloadCode = ssr ? guard('preloadCode') : client.preload_code; -export const beforeNavigate = ssr ? () => {} : client.before_navigate; -export const afterNavigate = ssr ? () => {} : client.after_navigate; +export const disableScrollHandling = BROWSER + ? client.disable_scroll_handling + : guard('disableScrollHandling'); +export const goto = BROWSER ? client.goto : guard('goto'); +export const invalidate = BROWSER ? client.invalidate : guard('invalidate'); +export const invalidateAll = BROWSER ? client.invalidateAll : guard('invalidateAll'); +export const preloadData = BROWSER ? client.preload_data : guard('preloadData'); +export const preloadCode = BROWSER ? client.preload_code : guard('preloadCode'); +export const beforeNavigate = BROWSER ? client.before_navigate : () => {}; +export const afterNavigate = BROWSER ? client.after_navigate : () => {}; // TODO remove for 1.0 release /** @param {any} _args */ diff --git a/packages/kit/src/runtime/client/client.js b/packages/kit/src/runtime/client/client.js index e0c096919f01..0bf95223e29b 100644 --- a/packages/kit/src/runtime/client/client.js +++ b/packages/kit/src/runtime/client/client.js @@ -1,3 +1,4 @@ +import { DEV } from 'esm-env'; import { onMount, tick } from 'svelte'; import { make_trackable, @@ -383,7 +384,7 @@ export function create_client({ target, base }) { /** @param {import('./types').NavigationFinished} result */ function initialize(result) { - if (__SVELTEKIT_DEV__ && document.querySelector('vite-error-overlay')) return; + if (DEV && document.querySelector('vite-error-overlay')) return; current = result.state; @@ -560,7 +561,7 @@ export function create_client({ target, base }) { const node = await loader(); - if (__SVELTEKIT_DEV__) { + if (DEV) { validate_common_exports(node.shared); } @@ -675,7 +676,7 @@ export function create_client({ target, base }) { } }); - if (__SVELTEKIT_DEV__) { + if (DEV) { try { lock_fetch(); data = (await node.shared.load.call(null, load_input)) ?? null; @@ -1313,7 +1314,7 @@ export function create_client({ target, base }) { }, disable_scroll_handling: () => { - if (__SVELTEKIT_DEV__ && started && !updating) { + if (DEV && started && !updating) { throw new Error('Can only disable scroll handling during navigation'); } @@ -1734,7 +1735,7 @@ export function create_client({ target, base }) { async function load_data(url, invalid) { const data_url = new URL(url); data_url.pathname = add_data_suffix(url.pathname); - if (__SVELTEKIT_DEV__ && url.searchParams.has('x-sveltekit-invalidated')) { + if (DEV && url.searchParams.has('x-sveltekit-invalidated')) { throw new Error('Cannot used reserved query parameter "x-sveltekit-invalidated"'); } data_url.searchParams.append( @@ -1827,7 +1828,7 @@ function add_url_properties(type, target) { } function pre_update() { - if (__SVELTEKIT_DEV__) { + if (DEV) { return () => { check_for_removed_attributes(); }; @@ -1866,7 +1867,7 @@ function reset_focus() { } } -if (__SVELTEKIT_DEV__) { +if (DEV) { // Nasty hack to silence harmless warnings the user can do nothing about const console_warn = console.warn; console.warn = function warn(...args) { diff --git a/packages/kit/src/runtime/client/fetcher.js b/packages/kit/src/runtime/client/fetcher.js index fb89843f8505..36666ef29c41 100644 --- a/packages/kit/src/runtime/client/fetcher.js +++ b/packages/kit/src/runtime/client/fetcher.js @@ -1,3 +1,4 @@ +import { DEV } from 'esm-env'; import { hash } from '../hash.js'; let loading = 0; @@ -12,7 +13,7 @@ export function unlock_fetch() { loading -= 1; } -if (import.meta.env.DEV) { +if (DEV) { let can_inspect_stack_trace = false; const check_stack_trace = async () => { diff --git a/packages/kit/src/runtime/client/start.js b/packages/kit/src/runtime/client/start.js index 7b113f53fbf8..16ad70ed0e90 100644 --- a/packages/kit/src/runtime/client/start.js +++ b/packages/kit/src/runtime/client/start.js @@ -1,3 +1,4 @@ +import { DEV } from 'esm-env'; import { create_client } from './client.js'; import { init } from './singletons.js'; import { set_paths } from '../paths.js'; @@ -21,7 +22,7 @@ export async function start({ env, hydrate, paths, target, version }) { set_paths(paths); set_version(version); - if (__SVELTEKIT_DEV__ && target === document.body) { + if (DEV && target === document.body) { console.warn( `Placing %sveltekit.body% directly inside is not recommended, as your app may break for users who have certain browser extensions installed.\n\nConsider wrapping it in an element:\n\n
\n %sveltekit.body%\n
` ); diff --git a/packages/kit/src/runtime/client/utils.js b/packages/kit/src/runtime/client/utils.js index 7f953d1f4dbd..8e1a047648d4 100644 --- a/packages/kit/src/runtime/client/utils.js +++ b/packages/kit/src/runtime/client/utils.js @@ -1,3 +1,4 @@ +import { BROWSER, DEV } from 'esm-env'; import { writable } from 'svelte/store'; import { assets } from '../paths.js'; import { version } from '../env.js'; @@ -50,7 +51,9 @@ function link_option(element, name) { element.getAttribute(`data-sveltekit-${name}`) ); - if (__SVELTEKIT_DEV__) validate_link_option(element, name, value); + if (DEV) { + validate_link_option(element, name, value); + } return value; } @@ -209,7 +212,7 @@ export function create_updated_store() { let timeout; async function check() { - if (import.meta.env.DEV || import.meta.env.SSR) return false; + if (DEV || !BROWSER) return false; clearTimeout(timeout); diff --git a/packages/kit/src/runtime/server/index.js b/packages/kit/src/runtime/server/index.js index dfce7d8f2703..1217079c62a5 100644 --- a/packages/kit/src/runtime/server/index.js +++ b/packages/kit/src/runtime/server/index.js @@ -1,3 +1,4 @@ +import { DEV } from 'esm-env'; import { is_endpoint_request, render_endpoint } from './endpoint.js'; import { render_page } from './page/index.js'; import { render_response } from './page/render.js'; @@ -202,7 +203,7 @@ export async function respond(request, options, state) { options.manifest._.nodes[route.page.leaf]() ]); - if (__SVELTEKIT_DEV__) { + if (DEV) { const layouts = nodes.slice(0, -1); const page = nodes.at(-1); @@ -224,7 +225,7 @@ export async function respond(request, options, state) { const node = await route.endpoint(); trailing_slash = node.trailingSlash; - if (__SVELTEKIT_DEV__) { + if (DEV) { validate_server_exports(node, /** @type {string} */ (route.endpoint_id)); } } diff --git a/packages/kit/src/utils/url.js b/packages/kit/src/utils/url.js index db4e6d882137..d0c917b2bb64 100644 --- a/packages/kit/src/utils/url.js +++ b/packages/kit/src/utils/url.js @@ -1,3 +1,5 @@ +import { BROWSER } from 'esm-env'; + const absolute = /^([a-z]+:)?\/?\//; const scheme = /^[a-z]+:/; @@ -101,7 +103,7 @@ export function make_trackable(url, callback) { }); } - if (!__SVELTEKIT_BROWSER__) { + if (!BROWSER) { // @ts-ignore tracked[Symbol.for('nodejs.util.inspect.custom')] = (depth, opts, inspect) => { return inspect(url, opts); diff --git a/packages/kit/src/utils/url.spec.js b/packages/kit/src/utils/url.spec.js index f405039f7fdd..383c30ea2e12 100644 --- a/packages/kit/src/utils/url.spec.js +++ b/packages/kit/src/utils/url.spec.js @@ -2,9 +2,6 @@ import * as assert from 'uvu/assert'; import { describe } from './unit_test.js'; import { resolve, normalize_path, make_trackable, disable_search } from './url.js'; -// @ts-expect-error define global required in url.js -globalThis.__SVELTEKIT_BROWSER__ = false; - describe('resolve', (test) => { test('resolves a root-relative path', () => { assert.equal(resolve('/a/b/c', '/x/y/z'), '/x/y/z'); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ee84774810dd..5a2b9aa66df8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -274,6 +274,7 @@ importers: '@types/set-cookie-parser': ^2.4.2 cookie: ^0.5.0 devalue: ^4.2.0 + esm-env: ^1.0.0 kleur: ^4.1.5 magic-string: ^0.27.0 marked: ^4.2.3 @@ -294,6 +295,7 @@ importers: '@types/cookie': 0.5.1 cookie: 0.5.0 devalue: 4.2.0 + esm-env: 1.0.0 kleur: 4.1.5 magic-string: 0.27.0 mime: 3.0.0 @@ -2275,6 +2277,10 @@ packages: engines: {node: '>=0.8.0'} dev: true + /esm-env/1.0.0: + resolution: {integrity: sha512-Cf6VksWPsTuW01vU9Mk/3vRue91Zevka5SjyNf3nEpokFRuqt/KjUQoGAwq9qMmhpLTHmXzSIrFRw8zxWzmFBA==} + dev: false + /esprima/4.0.1: resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} engines: {node: '>=4'}