From 43f75d9bf38d39ce4c04818e0c3f9365fbc33dfb Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Wed, 17 Aug 2022 16:36:39 -0400 Subject: [PATCH] use relative asset paths (#4250) * use relative asset paths * complete merge * oops, think i messed up the merge * configure vite to use relative base * remove unused app_dir * fix version.json * use absolute base for SSR, if specified * handle fallback case, explain prefixing logic a bit * oops * always use relative paths for client bundle * changeset * fix ssr chunkFileNames * bump vite version, add worker.rollupOptions config * fix test * ugh --- .changeset/wicked-spoons-leave.md | 5 +++ CONTRIBUTING.md | 3 +- .../routes/fallback/[...rest]/+page.svelte | 1 + packages/adapter-static/test/test.js | 5 ++- .../templates/default/package.json | 2 +- .../templates/default/package.template.json | 2 +- .../templates/skeleton/package.template.json | 2 +- .../kit/src/runtime/server/page/render.js | 32 +++++++++++++++---- packages/kit/src/vite/build/build_server.js | 1 - packages/kit/src/vite/build/utils.js | 26 ++++++++------- packages/kit/src/vite/dev/index.js | 1 - packages/kit/src/vite/index.js | 4 +-- packages/kit/types/internal.d.ts | 1 - pnpm-lock.yaml | 4 +-- sites/kit.svelte.dev/package.json | 2 +- 15 files changed, 60 insertions(+), 31 deletions(-) create mode 100644 .changeset/wicked-spoons-leave.md create mode 100644 packages/adapter-static/test/apps/spa/src/routes/fallback/[...rest]/+page.svelte diff --git a/.changeset/wicked-spoons-leave.md b/.changeset/wicked-spoons-leave.md new file mode 100644 index 000000000000..b83f016ce693 --- /dev/null +++ b/.changeset/wicked-spoons-leave.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/kit': patch +--- + +Use relative asset paths where possible diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ef527cd886a1..9f5643fa9833 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -48,6 +48,7 @@ You may need to install some dependencies first, e.g. with `npx playwright insta If there are tests that fail on the CI, you can retrieve the failed screenshots by going to the summary page of the CI run. You can usually find this by clicking on "Details" of the check results, click "Summary" at the top-left corner, and then scroll to the bottom "Artifacts" section to download the archive. It is very easy to introduce flakiness in a browser test. If you try to fix the flakiness in a test, you can run it until failure to gain some confidence you've fixed the test with a command like: + ``` npx playwright test --workers=1 --repeat-each 1000 --max-failures 1 -g "accepts a Request object" ``` @@ -60,7 +61,7 @@ If you would like to test local changes to Vite or another dependency, you can b { // ... "dependencies": { - "vite": "^2.0.0" + "vite": "^3.0.0" }, "pnpm": { "overrides": { diff --git a/packages/adapter-static/test/apps/spa/src/routes/fallback/[...rest]/+page.svelte b/packages/adapter-static/test/apps/spa/src/routes/fallback/[...rest]/+page.svelte new file mode 100644 index 000000000000..671b43ec7195 --- /dev/null +++ b/packages/adapter-static/test/apps/spa/src/routes/fallback/[...rest]/+page.svelte @@ -0,0 +1 @@ +

the fallback page was rendered

diff --git a/packages/adapter-static/test/test.js b/packages/adapter-static/test/test.js index ffc1f4072e7e..97bef6e5d5ce 100644 --- a/packages/adapter-static/test/test.js +++ b/packages/adapter-static/test/test.js @@ -14,8 +14,11 @@ run('prerendered', (test) => { }); run('spa', (test) => { - test('generates a fallback page', ({ cwd }) => { + test('generates a fallback page', async ({ base, cwd, page }) => { assert.ok(fs.existsSync(`${cwd}/build/200.html`)); + + await page.goto(`${base}/fallback/a/b/c`); + assert.equal(await page.textContent('h1'), 'the fallback page was rendered'); }); test('does not prerender pages without prerender=true', ({ cwd }) => { diff --git a/packages/create-svelte/templates/default/package.json b/packages/create-svelte/templates/default/package.json index bf068924231d..ce127a154cdc 100644 --- a/packages/create-svelte/templates/default/package.json +++ b/packages/create-svelte/templates/default/package.json @@ -13,7 +13,7 @@ "svelte": "^3.48.0", "svelte-preprocess": "^4.10.6", "typescript": "^4.7.4", - "vite": "^3.0.0" + "vite": "^3.0.4" }, "type": "module", "dependencies": { diff --git a/packages/create-svelte/templates/default/package.template.json b/packages/create-svelte/templates/default/package.template.json index 3e51b6a62117..d4cc74df2dfb 100644 --- a/packages/create-svelte/templates/default/package.template.json +++ b/packages/create-svelte/templates/default/package.template.json @@ -11,7 +11,7 @@ "@sveltejs/adapter-auto": "next", "@sveltejs/kit": "next", "svelte": "^3.46.0", - "vite": "^3.0.0" + "vite": "^3.0.4" }, "type": "module", "dependencies": { diff --git a/packages/create-svelte/templates/skeleton/package.template.json b/packages/create-svelte/templates/skeleton/package.template.json index 9b213b5b1501..0d2623c4e954 100644 --- a/packages/create-svelte/templates/skeleton/package.template.json +++ b/packages/create-svelte/templates/skeleton/package.template.json @@ -11,7 +11,7 @@ "@sveltejs/adapter-auto": "workspace:*", "@sveltejs/kit": "workspace:*", "svelte": "^3.44.0", - "vite": "^3.0.0" + "vite": "^3.0.4" }, "type": "module" } diff --git a/packages/kit/src/runtime/server/page/render.js b/packages/kit/src/runtime/server/page/render.js index 31d9f494a8dd..019229d131cd 100644 --- a/packages/kit/src/runtime/server/page/render.js +++ b/packages/kit/src/runtime/server/page/render.js @@ -150,9 +150,31 @@ export async function render_response({ const target = hash(body); + /** + * The prefix to use for static assets. Replaces `%sveltekit.assets%` in the template + * @type {string} + */ + let assets; + + if (options.paths.assets) { + // if an asset path is specified, use it + assets = options.paths.assets; + } else if (state.prerendering?.fallback) { + // if we're creating a fallback page, asset paths need to be root-relative + assets = options.paths.base; + } else { + // otherwise we want asset paths to be relative to the page, so that they + // will work in odd contexts like IPFS, the internet archive, and so on + const segments = event.url.pathname.slice(options.paths.base.length).split('/').slice(2); + assets = segments.length > 0 ? segments.map(() => '..').join('/') : '.'; + } + + /** @param {string} path */ + const prefixed = (path) => (path.startsWith('/') ? path : `${assets}/${path}`); + // prettier-ignore const init_app = ` - import { set_public_env, start } from ${s(options.prefix + entry.file)}; + import { set_public_env, start } from ${s(prefixed(entry.file))}; set_public_env(${s(options.public_env)}); @@ -195,7 +217,7 @@ export async function render_response({ } for (const dep of stylesheets) { - const path = options.prefix + dep; + const path = prefixed(dep); const attributes = []; if (csp.style_needs_nonce) { @@ -217,7 +239,7 @@ export async function render_response({ if (page_config.router || page_config.hydrate) { for (const dep of modulepreloads) { - const path = options.prefix + dep; + const path = prefixed(dep); link_header_preloads.add(`<${encodeURI(path)}>; rel="modulepreload"; nopush`); if (state.prerendering) { head += `\n\t`; @@ -292,10 +314,6 @@ export async function render_response({ } } - const segments = event.url.pathname.slice(options.paths.base.length).split('/').slice(2); - const assets = - options.paths.assets || (segments.length > 0 ? segments.map(() => '..').join('/') : '.'); - // TODO flush chunks as early as we can const html = (await resolve_opts.transformPageChunk({ diff --git a/packages/kit/src/vite/build/build_server.js b/packages/kit/src/vite/build/build_server.js index e0a778c5f66f..7414463b8ec9 100644 --- a/packages/kit/src/vite/build/build_server.js +++ b/packages/kit/src/vite/build/build_server.js @@ -69,7 +69,6 @@ export class Server { manifest, method_override: ${s(config.kit.methodOverride)}, paths: { base, assets }, - prefix: assets + '/', prerender: { default: ${config.kit.prerender.default}, enabled: ${config.kit.prerender.enabled} diff --git a/packages/kit/src/vite/build/utils.js b/packages/kit/src/vite/build/utils.js index 35cdc330a750..a1b3da9f8768 100644 --- a/packages/kit/src/vite/build/utils.js +++ b/packages/kit/src/vite/build/utils.js @@ -88,9 +88,11 @@ export function find_deps(manifest, entry, add_dynamic_css) { * @return {import('vite').UserConfig} */ export const get_default_config = function ({ config, input, ssr, outDir }) { + const prefix = `${config.kit.appDir}/immutable`; + return { appType: 'custom', - base: assets_base(config.kit), + base: ssr ? assets_base(config.kit) : './', build: { cssCodeSplit: true, // don't use the default name to avoid collisions with 'static/manifest.json' @@ -101,11 +103,9 @@ export const get_default_config = function ({ config, input, ssr, outDir }) { input, output: { format: 'esm', - entryFileNames: ssr ? '[name].js' : `${config.kit.appDir}/immutable/[name]-[hash].js`, - chunkFileNames: ssr - ? 'chunks/[name].js' - : `${config.kit.appDir}/immutable/chunks/[name]-[hash].js`, - assetFileNames: `${config.kit.appDir}/immutable/assets/[name]-[hash][extname]` + entryFileNames: ssr ? '[name].js' : `${prefix}/[name]-[hash].js`, + chunkFileNames: ssr ? 'chunks/[name].js' : `${prefix}/chunks/[name]-[hash].js`, + assetFileNames: `${prefix}/assets/[name]-[hash][extname]` }, preserveEntrySignatures: 'strict' }, @@ -125,6 +125,14 @@ export const get_default_config = function ({ config, input, ssr, outDir }) { }, ssr: { noExternal: ['@sveltejs/kit'] + }, + worker: { + rollupOptions: { + output: { + entryFileNames: `${prefix}/workers/[name]-[hash].js`, + chunkFileNames: `${prefix}/workers/chunks/[name]-[hash].js` + } + } } }; }; @@ -134,11 +142,7 @@ export const get_default_config = function ({ config, input, ssr, outDir }) { * @returns {string} */ export function assets_base(config) { - // TODO this is so that Vite's preloading works. Unfortunately, it fails - // during `svelte-kit preview`, because we use a local asset path. This - // may be fixed in Vite 3: https://github.com/vitejs/vite/issues/2009 - const { base, assets } = config.paths; - return `${assets || base}/`; + return config.paths.assets || config.paths.base || './'; } const method_names = new Set(['GET', 'HEAD', 'PUT', 'POST', 'DELETE', 'PATCH']); diff --git a/packages/kit/src/vite/dev/index.js b/packages/kit/src/vite/dev/index.js index 0c20b7a914fb..c67f11fe247d 100644 --- a/packages/kit/src/vite/dev/index.js +++ b/packages/kit/src/vite/dev/index.js @@ -432,7 +432,6 @@ export async function dev(vite, vite_config, svelte_config, illegal_imports) { base: svelte_config.kit.paths.base, assets }, - prefix: '', prerender: { default: svelte_config.kit.prerender.default, enabled: svelte_config.kit.prerender.enabled diff --git a/packages/kit/src/vite/index.js b/packages/kit/src/vite/index.js index 70a9cf482ad0..a5ef0f32ee80 100644 --- a/packages/kit/src/vite/index.js +++ b/packages/kit/src/vite/index.js @@ -207,7 +207,7 @@ function kit() { paths = { build_dir: `${svelte_config.kit.outDir}/build`, output_dir: `${svelte_config.kit.outDir}/output`, - client_out_dir: `${svelte_config.kit.outDir}/output/client/` + client_out_dir: `${svelte_config.kit.outDir}/output/client` }; illegal_imports = new Set([ @@ -230,7 +230,7 @@ function kit() { /** @type {import('vite').UserConfig} */ const result = { appType: 'custom', - base: '/', + base: './', build: { rollupOptions: { // Vite dependency crawler needs an explicit JS entry point diff --git a/packages/kit/types/internal.d.ts b/packages/kit/types/internal.d.ts index a9938d281c95..9738ab5a07da 100644 --- a/packages/kit/types/internal.d.ts +++ b/packages/kit/types/internal.d.ts @@ -239,7 +239,6 @@ export interface SSROptions { base: string; assets: string; }; - prefix: string; prerender: { default: boolean; enabled: boolean; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d13023cd996c..92e3c04316db 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -247,7 +247,7 @@ importers: svelte: ^3.48.0 svelte-preprocess: ^4.10.6 typescript: ^4.7.4 - vite: ^3.0.0 + vite: ^3.0.4 dependencies: '@fontsource/fira-mono': 4.5.8 '@lukeed/uuid': 2.0.0 @@ -556,7 +556,7 @@ importers: shiki-twoslash: ^3.0.2 svelte: ^3.48.0 typescript: ^4.7.4 - vite: ^3.0.0 + vite: ^3.0.4 vite-imagetools: ^4.0.3 devDependencies: '@sveltejs/adapter-auto': link:../../packages/adapter-auto diff --git a/sites/kit.svelte.dev/package.json b/sites/kit.svelte.dev/package.json index 616f17709c90..5be7b5e4436b 100644 --- a/sites/kit.svelte.dev/package.json +++ b/sites/kit.svelte.dev/package.json @@ -21,7 +21,7 @@ "shiki-twoslash": "^3.0.2", "svelte": "^3.48.0", "typescript": "^4.7.4", - "vite": "^3.0.0", + "vite": "^3.0.4", "vite-imagetools": "^4.0.3" }, "type": "module"