From 545286dade31ae1be9a0390113456dbd522c3637 Mon Sep 17 00:00:00 2001
From: Samuel Plumppu <6125097+Greenheart@users.noreply.github.com>
Date: Sun, 21 Aug 2022 11:00:13 +0200
Subject: [PATCH 01/15] WIP: Replace `sveltekit:prefetch` with
`data-sveltekit-prefetch` at build time.
---
packages/kit/src/runtime/client/client.js | 2 +-
packages/kit/src/vite/index.js | 40 +++++++++++++++++++
.../source/pages/prefetching/+page.svelte | 2 +-
3 files changed, 42 insertions(+), 2 deletions(-)
diff --git a/packages/kit/src/runtime/client/client.js b/packages/kit/src/runtime/client/client.js
index 214d8843ccb5..78240689435d 100644
--- a/packages/kit/src/runtime/client/client.js
+++ b/packages/kit/src/runtime/client/client.js
@@ -1065,7 +1065,7 @@ export function create_client({ target, base, trailing_slash }) {
/** @param {Event} event */
const trigger_prefetch = (event) => {
const a = find_anchor(event);
- if (a && a.href && a.hasAttribute('sveltekit:prefetch')) {
+ if (a && a.href && a.hasAttribute('data-sveltekit-prefetch')) {
prefetch(get_href(a));
}
};
diff --git a/packages/kit/src/vite/index.js b/packages/kit/src/vite/index.js
index 4f4471d952c0..0b8047d3f3ea 100644
--- a/packages/kit/src/vite/index.js
+++ b/packages/kit/src/vite/index.js
@@ -324,6 +324,46 @@ function kit() {
}
},
+ // IDEA: Maybe the attribute replacement could be done when rendering the chunks to avoid looping an extra time (as is the case with generateBundle).
+ // /** @type {import('rollup').RenderChunkHook} */
+ // renderChunk(code, chunk) {
+ // for (const [attribute, replacement] of [['sveltekit:prefetch', 'data-sveltekit-prefetch']]) {
+ // if (code.includes(attribute)) {
+ // console.log(`[${chunk.name}]: Replacing "${attribute}" with "${replacement}"`);
+
+ // return code.replace(attribute, replacement);
+ // }
+ // }
+
+ // return code;
+ // },
+
+ // TODO: Ensure the replacement only happens for attributes
+ // TODO: Ensure the replacement happens for prerendered HTML too
+ // This might be read from the svelte source file which means we need to replace it when server side rendering the HTML response too.
+ /**
+ * @param {import('rollup').OutputOptions} _options
+ * @param {{ [fileName: string]: any }} bundle
+ */
+ generateBundle(_options, bundle) {
+ for (const entry of Object.values(bundle)) {
+ if (entry.type !== 'chunk') continue;
+
+ for (const [attribute, replacement] of [
+ ['sveltekit:prefetch', 'data-sveltekit-prefetch']
+ ]) {
+ if (entry.code.includes(attribute)) {
+ console.log(`[${entry.fileName}]: Replacing "${attribute}" with "${replacement}"`);
+
+ bundle[entry.fileName] = {
+ ...entry,
+ code: entry.code.replaceAll(attribute, replacement)
+ };
+ }
+ }
+ }
+ },
+
/**
* Vite builds a single bundle. We need three bundles: client, server, and service worker.
* The user's package.json scripts will invoke the Vite CLI to execute the client build. We
diff --git a/packages/kit/test/apps/options/source/pages/prefetching/+page.svelte b/packages/kit/test/apps/options/source/pages/prefetching/+page.svelte
index 07b287bef1f4..dc742748eba9 100644
--- a/packages/kit/test/apps/options/source/pages/prefetching/+page.svelte
+++ b/packages/kit/test/apps/options/source/pages/prefetching/+page.svelte
@@ -1 +1 @@
-click me
+click me for sveltekit:prefetch
From ee56dc75f8b7f2f3239414e8396f52e51af111e2 Mon Sep 17 00:00:00 2001
From: Samuel Plumppu <6125097+Greenheart@users.noreply.github.com>
Date: Sun, 21 Aug 2022 22:01:26 +0200
Subject: [PATCH 02/15] WIP: Use svelte-preprocess to replace values.
Significant progress!
PoC works great if run from the user's svelte.config.js, but we need to extend the user config and still make it work. Currently it only works when run with the default svelte config loading.
---
packages/kit/src/core/config/index.js | 19 +++++++++++++++++++
packages/kit/src/vite/index.js | 13 +++++++++++++
.../source/pages/prefetching/+page.svelte | 2 ++
.../kit/test/apps/options/svelte.config.js | 16 +++++++++++++++-
4 files changed, 49 insertions(+), 1 deletion(-)
diff --git a/packages/kit/src/core/config/index.js b/packages/kit/src/core/config/index.js
index f903bb086b05..30d91eb790e0 100644
--- a/packages/kit/src/core/config/index.js
+++ b/packages/kit/src/core/config/index.js
@@ -2,6 +2,7 @@ import fs from 'fs';
import path from 'path';
import * as url from 'url';
import options from './options.js';
+import preprocess from 'svelte-preprocess';
/**
* Loads the template (src/app.html by default) and validates that it has the
@@ -63,6 +64,24 @@ function process_config(config, { cwd = process.cwd() } = {}) {
validated.kit.outDir = path.resolve(cwd, validated.kit.outDir);
+ const replaceSveltkitAttributes = preprocess({
+ // TODO: Update regex to only match attributes and not all string values, to prevent it from replacing text content.
+ // replace: [[/sveltekit\:prefetch/g, 'data-sveltekit-prefetch']]
+ replace: [
+ [/sveltekit:attribute/g, 'data-sveltekit-attribute'],
+ [/sveltekit\:prefetch/g, 'data-sveltekit-prefetch']
+ ]
+ });
+
+ // TODO: Update types of `config.preprocess` to get type safety here. Use correct typing and validation from vite-plugin-svelte
+ // TODO: This needs to support all valid configs for preprocess, possibly including objects and not just arrays.
+ // TODO: Ensure the svelte.preprocess API can run multiple instances of `svelte-preprocess` if the user has their own config too.
+ if (Array.isArray(validated.preprocess)) {
+ validated.preprocess.push(replaceSveltkitAttributes);
+ } else {
+ validated.preprocess = [replaceSveltkitAttributes];
+ }
+
for (const key in validated.kit.files) {
// @ts-expect-error this is typescript at its stupidest
validated.kit.files[key] = path.resolve(cwd, validated.kit.files[key]);
diff --git a/packages/kit/src/vite/index.js b/packages/kit/src/vite/index.js
index 0b8047d3f3ea..870a978dbe0c 100644
--- a/packages/kit/src/vite/index.js
+++ b/packages/kit/src/vite/index.js
@@ -62,6 +62,16 @@ const enforced_config = {
* @return {import('vite').Plugin[]}
*/
export function sveltekit() {
+ // TODO: find out if this is the right place to ensure we add preprocessing for replacing sveltekit specific attributes
+ // NOTE: OR maybe it is autimatically passed in, since it uses the svelte.config.js file where we might have additional preprocessing
+ // TODO: Ensure preprocessing works with multiple calls to `svelte-preprocess`.
+ // Seems like it should be find though, as it likely is using an internal closure to keep state, and returning the callback to actually execute the transform.
+
+ // IDEA: We could use svelte-preprocess to create the needed config for preprocessing `sveltekit:*`
+ // TODO: Update regex to only match attributes and not all string values, to prevent it from replacing text content.
+ // import preprocess from 'svelte-preprocess'
+ // preprocess({ replace: [/sveltekit\:prefetch/g, 'data-sveltekit-prefetch'] })
+
return [...svelte(), kit()];
}
@@ -197,6 +207,9 @@ function kit() {
async config(config, config_env) {
vite_config_env = config_env;
svelte_config = await load_config();
+
+ console.log('vite svelte.config.js preprocess', svelte_config.preprocess);
+
env = get_env(vite_config_env.mode, svelte_config.kit.env.publicPrefix);
// The config is created in build_server for SSR mode and passed inline
diff --git a/packages/kit/test/apps/options/source/pages/prefetching/+page.svelte b/packages/kit/test/apps/options/source/pages/prefetching/+page.svelte
index dc742748eba9..7cafcd653907 100644
--- a/packages/kit/test/apps/options/source/pages/prefetching/+page.svelte
+++ b/packages/kit/test/apps/options/source/pages/prefetching/+page.svelte
@@ -1 +1,3 @@
click me for sveltekit:prefetch
+
+click me for sveltekit:attribute
diff --git a/packages/kit/test/apps/options/svelte.config.js b/packages/kit/test/apps/options/svelte.config.js
index a5b1b65dc595..a740e299cf3d 100644
--- a/packages/kit/test/apps/options/svelte.config.js
+++ b/packages/kit/test/apps/options/svelte.config.js
@@ -1,3 +1,5 @@
+import preprocess from 'svelte-preprocess';
+
/** @type {import('@sveltejs/kit').Config} */
const config = {
extensions: ['.jesuslivesineveryone', '.whokilledthemuffinman', '.svelte.md', '.svelte'],
@@ -23,7 +25,19 @@ const config = {
base: '/path-base',
assets: 'https://cdn.example.com/stuff'
}
- }
+ },
+ preprocess: [
+ // IDEA: We could use svelte-preprocess to create the needed config for preprocessing `sveltekit:*`
+ // TODO: Update regex to only match attributes and not all string values, to prevent it from replacing text content.
+ // preprocess({
+ // // TODO: Find a way to create a combined preprocess() inside of sveltekit.
+ // // This works perfectly, but we shouldn't have to expose this detail to app developers. There must be a way to combine it.
+ // replace: [
+ // [/sveltekit\:attribute/g, 'data-sveltekit-attribute'],
+ // [/sveltekit\:prefetch/g, 'data-sveltekit-prefetch']
+ // ]
+ // })
+ ]
};
export default config;
From ca440d28028cc7b2a8052dc472ad2143b0afaf56 Mon Sep 17 00:00:00 2001
From: Samuel Plumppu <6125097+Greenheart@users.noreply.github.com>
Date: Mon, 22 Aug 2022 08:25:56 +0200
Subject: [PATCH 03/15] Improve attribute replacement and make it work even if
app devs have custom preprocessing config.
Auto-reloading doesn't work though, so that needs to be fixed, along with regex specificity.
---
packages/kit/src/core/config/index.js | 8 +--
packages/kit/src/runtime/client/client.js | 4 +-
packages/kit/src/vite/index.js | 55 ++-----------------
.../source/pages/prefetching/+page.svelte | 6 ++
.../kit/test/apps/options/svelte.config.js | 17 +++---
5 files changed, 23 insertions(+), 67 deletions(-)
diff --git a/packages/kit/src/core/config/index.js b/packages/kit/src/core/config/index.js
index 30d91eb790e0..bff17961bc75 100644
--- a/packages/kit/src/core/config/index.js
+++ b/packages/kit/src/core/config/index.js
@@ -66,16 +66,16 @@ function process_config(config, { cwd = process.cwd() } = {}) {
const replaceSveltkitAttributes = preprocess({
// TODO: Update regex to only match attributes and not all string values, to prevent it from replacing text content.
- // replace: [[/sveltekit\:prefetch/g, 'data-sveltekit-prefetch']]
+ // TODO: Ensure the replacement happens for prerendered HTML too
replace: [
- [/sveltekit:attribute/g, 'data-sveltekit-attribute'],
- [/sveltekit\:prefetch/g, 'data-sveltekit-prefetch']
+ [/sveltekit\:prefetch/g, 'data-sveltekit-prefetch'],
+ [/sveltekit\:reload/g, 'data-sveltekit-reload'],
+ [/sveltekit\:noscroll/g, 'data-sveltekit-noscroll']
]
});
// TODO: Update types of `config.preprocess` to get type safety here. Use correct typing and validation from vite-plugin-svelte
// TODO: This needs to support all valid configs for preprocess, possibly including objects and not just arrays.
- // TODO: Ensure the svelte.preprocess API can run multiple instances of `svelte-preprocess` if the user has their own config too.
if (Array.isArray(validated.preprocess)) {
validated.preprocess.push(replaceSveltkitAttributes);
} else {
diff --git a/packages/kit/src/runtime/client/client.js b/packages/kit/src/runtime/client/client.js
index 78240689435d..6ab977b64b66 100644
--- a/packages/kit/src/runtime/client/client.js
+++ b/packages/kit/src/runtime/client/client.js
@@ -1122,7 +1122,7 @@ export function create_client({ target, base, trailing_slash }) {
if (
a.hasAttribute('download') ||
rel.includes('external') ||
- a.hasAttribute('sveltekit:reload')
+ a.hasAttribute('data-sveltekit-reload')
) {
return;
}
@@ -1149,7 +1149,7 @@ export function create_client({ target, base, trailing_slash }) {
navigate({
url,
- scroll: a.hasAttribute('sveltekit:noscroll') ? scroll_state() : null,
+ scroll: a.hasAttribute('data-sveltekit-noscroll') ? scroll_state() : null,
keepfocus: false,
redirect_chain: [],
details: {
diff --git a/packages/kit/src/vite/index.js b/packages/kit/src/vite/index.js
index 870a978dbe0c..9a08d034f746 100644
--- a/packages/kit/src/vite/index.js
+++ b/packages/kit/src/vite/index.js
@@ -58,21 +58,14 @@ const enforced_config = {
root: true
};
+// TODO: Figure out how to reload the svelte.config.js when changes happen.
+const svelte_config = await load_config();
+
/**
* @return {import('vite').Plugin[]}
*/
export function sveltekit() {
- // TODO: find out if this is the right place to ensure we add preprocessing for replacing sveltekit specific attributes
- // NOTE: OR maybe it is autimatically passed in, since it uses the svelte.config.js file where we might have additional preprocessing
- // TODO: Ensure preprocessing works with multiple calls to `svelte-preprocess`.
- // Seems like it should be find though, as it likely is using an internal closure to keep state, and returning the callback to actually execute the transform.
-
- // IDEA: We could use svelte-preprocess to create the needed config for preprocessing `sveltekit:*`
- // TODO: Update regex to only match attributes and not all string values, to prevent it from replacing text content.
- // import preprocess from 'svelte-preprocess'
- // preprocess({ replace: [/sveltekit\:prefetch/g, 'data-sveltekit-prefetch'] })
-
- return [...svelte(), kit()];
+ return [...svelte({ configFile: false, ...svelte_config }), kit()];
}
/**
@@ -337,46 +330,6 @@ function kit() {
}
},
- // IDEA: Maybe the attribute replacement could be done when rendering the chunks to avoid looping an extra time (as is the case with generateBundle).
- // /** @type {import('rollup').RenderChunkHook} */
- // renderChunk(code, chunk) {
- // for (const [attribute, replacement] of [['sveltekit:prefetch', 'data-sveltekit-prefetch']]) {
- // if (code.includes(attribute)) {
- // console.log(`[${chunk.name}]: Replacing "${attribute}" with "${replacement}"`);
-
- // return code.replace(attribute, replacement);
- // }
- // }
-
- // return code;
- // },
-
- // TODO: Ensure the replacement only happens for attributes
- // TODO: Ensure the replacement happens for prerendered HTML too
- // This might be read from the svelte source file which means we need to replace it when server side rendering the HTML response too.
- /**
- * @param {import('rollup').OutputOptions} _options
- * @param {{ [fileName: string]: any }} bundle
- */
- generateBundle(_options, bundle) {
- for (const entry of Object.values(bundle)) {
- if (entry.type !== 'chunk') continue;
-
- for (const [attribute, replacement] of [
- ['sveltekit:prefetch', 'data-sveltekit-prefetch']
- ]) {
- if (entry.code.includes(attribute)) {
- console.log(`[${entry.fileName}]: Replacing "${attribute}" with "${replacement}"`);
-
- bundle[entry.fileName] = {
- ...entry,
- code: entry.code.replaceAll(attribute, replacement)
- };
- }
- }
- }
- },
-
/**
* Vite builds a single bundle. We need three bundles: client, server, and service worker.
* The user's package.json scripts will invoke the Vite CLI to execute the client build. We
diff --git a/packages/kit/test/apps/options/source/pages/prefetching/+page.svelte b/packages/kit/test/apps/options/source/pages/prefetching/+page.svelte
index 7cafcd653907..28ba6017045b 100644
--- a/packages/kit/test/apps/options/source/pages/prefetching/+page.svelte
+++ b/packages/kit/test/apps/options/source/pages/prefetching/+page.svelte
@@ -1,3 +1,9 @@
click me for sveltekit:prefetch click me for sveltekit:attribute
+
+click me for sveltekit:noscroll
+
+click me for sveltekit:reload
+
+click me for sveltekit:something
diff --git a/packages/kit/test/apps/options/svelte.config.js b/packages/kit/test/apps/options/svelte.config.js
index a740e299cf3d..59eed8019b5b 100644
--- a/packages/kit/test/apps/options/svelte.config.js
+++ b/packages/kit/test/apps/options/svelte.config.js
@@ -27,16 +27,13 @@ const config = {
}
},
preprocess: [
- // IDEA: We could use svelte-preprocess to create the needed config for preprocessing `sveltekit:*`
- // TODO: Update regex to only match attributes and not all string values, to prevent it from replacing text content.
- // preprocess({
- // // TODO: Find a way to create a combined preprocess() inside of sveltekit.
- // // This works perfectly, but we shouldn't have to expose this detail to app developers. There must be a way to combine it.
- // replace: [
- // [/sveltekit\:attribute/g, 'data-sveltekit-attribute'],
- // [/sveltekit\:prefetch/g, 'data-sveltekit-prefetch']
- // ]
- // })
+ // Test how combined user preprocessing works together with internal sveltekit preprocessing.
+ preprocess({
+ replace: [
+ [/sveltekit\:attribute/g, 'data-sveltekit-attribute'],
+ [/sveltekit\:something/g, 'data-sveltekit-something']
+ ]
+ })
]
};
From c512b27c461c6d5134649a5e77c87ecce5a02d28 Mon Sep 17 00:00:00 2001
From: Samuel Plumppu <6125097+Greenheart@users.noreply.github.com>
Date: Mon, 22 Aug 2022 08:36:19 +0200
Subject: [PATCH 04/15] WIP: Explore how to combine the svelte config by the
user with the options needed by sveltekit.
---
packages/kit/src/core/config/index.js | 34 +++++++++++++--------------
packages/kit/src/vite/index.js | 23 ++++++++++++++----
2 files changed, 36 insertions(+), 21 deletions(-)
diff --git a/packages/kit/src/core/config/index.js b/packages/kit/src/core/config/index.js
index bff17961bc75..f456df024452 100644
--- a/packages/kit/src/core/config/index.js
+++ b/packages/kit/src/core/config/index.js
@@ -64,23 +64,23 @@ function process_config(config, { cwd = process.cwd() } = {}) {
validated.kit.outDir = path.resolve(cwd, validated.kit.outDir);
- const replaceSveltkitAttributes = preprocess({
- // TODO: Update regex to only match attributes and not all string values, to prevent it from replacing text content.
- // TODO: Ensure the replacement happens for prerendered HTML too
- replace: [
- [/sveltekit\:prefetch/g, 'data-sveltekit-prefetch'],
- [/sveltekit\:reload/g, 'data-sveltekit-reload'],
- [/sveltekit\:noscroll/g, 'data-sveltekit-noscroll']
- ]
- });
-
- // TODO: Update types of `config.preprocess` to get type safety here. Use correct typing and validation from vite-plugin-svelte
- // TODO: This needs to support all valid configs for preprocess, possibly including objects and not just arrays.
- if (Array.isArray(validated.preprocess)) {
- validated.preprocess.push(replaceSveltkitAttributes);
- } else {
- validated.preprocess = [replaceSveltkitAttributes];
- }
+ // const replaceSveltkitAttributes = preprocess({
+ // // TODO: Update regex to only match attributes and not all string values, to prevent it from replacing text content.
+ // // TODO: Ensure the replacement happens for prerendered HTML too
+ // replace: [
+ // [/sveltekit\:prefetch/g, 'data-sveltekit-prefetch'],
+ // [/sveltekit\:reload/g, 'data-sveltekit-reload'],
+ // [/sveltekit\:noscroll/g, 'data-sveltekit-noscroll']
+ // ]
+ // });
+
+ // // TODO: Update types of `config.preprocess` to get type safety here. Use correct typing and validation from vite-plugin-svelte
+ // // TODO: This needs to support all valid configs for preprocess, possibly including objects and not just arrays.
+ // if (Array.isArray(validated.preprocess)) {
+ // validated.preprocess.push(replaceSveltkitAttributes);
+ // } else {
+ // validated.preprocess = [replaceSveltkitAttributes];
+ // }
for (const key in validated.kit.files) {
// @ts-expect-error this is typescript at its stupidest
diff --git a/packages/kit/src/vite/index.js b/packages/kit/src/vite/index.js
index 9a08d034f746..d5867d31a4b2 100644
--- a/packages/kit/src/vite/index.js
+++ b/packages/kit/src/vite/index.js
@@ -17,6 +17,7 @@ import { preview } from './preview/index.js';
import { get_aliases, resolve_entry, prevent_illegal_rollup_imports, get_env } from './utils.js';
import { fileURLToPath } from 'node:url';
import { create_module } from '../core/env.js';
+import preprocess from 'svelte-preprocess';
const cwd = process.cwd();
@@ -58,14 +59,28 @@ const enforced_config = {
root: true
};
-// TODO: Figure out how to reload the svelte.config.js when changes happen.
-const svelte_config = await load_config();
-
/**
* @return {import('vite').Plugin[]}
*/
export function sveltekit() {
- return [...svelte({ configFile: false, ...svelte_config }), kit()];
+ return [
+ ...svelte({
+ // IDEA: Maybe vite-plugin-svelte can me modified to allow extending the user's svelte.config.js
+ // This would allow us to add inlineOptions with the preprocessing we need, without overwriting preprocessing from the user's config.
+ preprocess: [
+ preprocess({
+ // // TODO: Update regex to only match attributes and not all string values, to prevent it from replacing text content.
+ // // TODO: Ensure the replacement happens for prerendered HTML too
+ replace: [
+ [/sveltekit\:prefetch/g, 'data-sveltekit-prefetch'],
+ [/sveltekit\:reload/g, 'data-sveltekit-reload'],
+ [/sveltekit\:noscroll/g, 'data-sveltekit-noscroll']
+ ]
+ })
+ ]
+ }),
+ kit()
+ ];
}
/**
From 17a0183207b99df981e2f6d768440acacd85ff14 Mon Sep 17 00:00:00 2001
From: Samuel Plumppu <6125097+Greenheart@users.noreply.github.com>
Date: Mon, 22 Aug 2022 21:58:54 +0200
Subject: [PATCH 05/15] Improve type definition for `config.preprocess` to
match what's used internally. Also allow object configs.
---
packages/kit/src/core/config/index.js | 33 +++++++++++++++++----------
packages/kit/types/index.d.ts | 3 ++-
2 files changed, 23 insertions(+), 13 deletions(-)
diff --git a/packages/kit/src/core/config/index.js b/packages/kit/src/core/config/index.js
index f456df024452..0d7bb5e6abf7 100644
--- a/packages/kit/src/core/config/index.js
+++ b/packages/kit/src/core/config/index.js
@@ -64,20 +64,29 @@ function process_config(config, { cwd = process.cwd() } = {}) {
validated.kit.outDir = path.resolve(cwd, validated.kit.outDir);
- // const replaceSveltkitAttributes = preprocess({
- // // TODO: Update regex to only match attributes and not all string values, to prevent it from replacing text content.
- // // TODO: Ensure the replacement happens for prerendered HTML too
- // replace: [
- // [/sveltekit\:prefetch/g, 'data-sveltekit-prefetch'],
- // [/sveltekit\:reload/g, 'data-sveltekit-reload'],
- // [/sveltekit\:noscroll/g, 'data-sveltekit-noscroll']
- // ]
- // });
-
- // // TODO: Update types of `config.preprocess` to get type safety here. Use correct typing and validation from vite-plugin-svelte
- // // TODO: This needs to support all valid configs for preprocess, possibly including objects and not just arrays.
+ const replaceSveltkitAttributes = preprocess({
+ // TODO: Update regex to only match attributes and not all string values, to prevent it from replacing text content.
+ // TODO: Ensure the replacement happens for prerendered HTML too
+ // TODO: Ensure the replacement happens for SvelteKit packages too
+ replace: [
+ [/sveltekit\:prefetch/g, 'data-sveltekit-prefetch'],
+ [/sveltekit\:reload/g, 'data-sveltekit-reload'],
+ [/sveltekit\:noscroll/g, 'data-sveltekit-noscroll']
+ ]
+ });
+
+ /** @ts-expect-error RecursiveRequired is messing up the regular Config which is all we need for `preprocess` */
+ validated.preprocess = Array.isArray(validated.preprocess)
+ ? [...validated.preprocess, replaceSveltkitAttributes]
+ : typeof validated.preprocess === 'object'
+ ? [validated.preprocess, replaceSveltkitAttributes]
+ : [replaceSveltkitAttributes];
+
+ // NOTE: This would be much cleaner with distinct if/else statements, but would require fixing the types.
// if (Array.isArray(validated.preprocess)) {
// validated.preprocess.push(replaceSveltkitAttributes);
+ // } else if (typeof validated.preprocess === 'object') {
+ // validated.preprocess = [validated.preprocess, replaceSveltkitAttributes];
// } else {
// validated.preprocess = [replaceSveltkitAttributes];
// }
diff --git a/packages/kit/types/index.d.ts b/packages/kit/types/index.d.ts
index 294330e193fe..009f15def3f8 100644
--- a/packages/kit/types/index.d.ts
+++ b/packages/kit/types/index.d.ts
@@ -4,6 +4,7 @@
import './ambient.js';
import { CompileOptions } from 'svelte/types/compiler/interfaces';
+import type { SvelteOptions } from '@sveltejs/vite-plugin-svelte';
import {
AdapterEntry,
CspDirectives,
@@ -113,7 +114,7 @@ export interface Config {
exports?: (filepath: string) => boolean;
files?: (filepath: string) => boolean;
};
- preprocess?: any;
+ preprocess?: SvelteOptions['preprocess'];
[key: string]: any;
}
From 0aabdde38cc766a5ef18dabbba15caa4bd9d891c Mon Sep 17 00:00:00 2001
From: Samuel Plumppu <6125097+Greenheart@users.noreply.github.com>
Date: Mon, 22 Aug 2022 22:42:52 +0200
Subject: [PATCH 06/15] Use API from vite-plugin-svelte to add internal
SvelteKit preprocessing
Much cleaner solution, which also should be a tiny bit more performant than before.
---
packages/kit/src/core/config/index.js | 28 ----------------
packages/kit/src/vite/index.js | 32 ++++++++-----------
.../kit/test/apps/options/svelte.config.js | 1 -
3 files changed, 14 insertions(+), 47 deletions(-)
diff --git a/packages/kit/src/core/config/index.js b/packages/kit/src/core/config/index.js
index 0d7bb5e6abf7..f903bb086b05 100644
--- a/packages/kit/src/core/config/index.js
+++ b/packages/kit/src/core/config/index.js
@@ -2,7 +2,6 @@ import fs from 'fs';
import path from 'path';
import * as url from 'url';
import options from './options.js';
-import preprocess from 'svelte-preprocess';
/**
* Loads the template (src/app.html by default) and validates that it has the
@@ -64,33 +63,6 @@ function process_config(config, { cwd = process.cwd() } = {}) {
validated.kit.outDir = path.resolve(cwd, validated.kit.outDir);
- const replaceSveltkitAttributes = preprocess({
- // TODO: Update regex to only match attributes and not all string values, to prevent it from replacing text content.
- // TODO: Ensure the replacement happens for prerendered HTML too
- // TODO: Ensure the replacement happens for SvelteKit packages too
- replace: [
- [/sveltekit\:prefetch/g, 'data-sveltekit-prefetch'],
- [/sveltekit\:reload/g, 'data-sveltekit-reload'],
- [/sveltekit\:noscroll/g, 'data-sveltekit-noscroll']
- ]
- });
-
- /** @ts-expect-error RecursiveRequired is messing up the regular Config which is all we need for `preprocess` */
- validated.preprocess = Array.isArray(validated.preprocess)
- ? [...validated.preprocess, replaceSveltkitAttributes]
- : typeof validated.preprocess === 'object'
- ? [validated.preprocess, replaceSveltkitAttributes]
- : [replaceSveltkitAttributes];
-
- // NOTE: This would be much cleaner with distinct if/else statements, but would require fixing the types.
- // if (Array.isArray(validated.preprocess)) {
- // validated.preprocess.push(replaceSveltkitAttributes);
- // } else if (typeof validated.preprocess === 'object') {
- // validated.preprocess = [validated.preprocess, replaceSveltkitAttributes];
- // } else {
- // validated.preprocess = [replaceSveltkitAttributes];
- // }
-
for (const key in validated.kit.files) {
// @ts-expect-error this is typescript at its stupidest
validated.kit.files[key] = path.resolve(cwd, validated.kit.files[key]);
diff --git a/packages/kit/src/vite/index.js b/packages/kit/src/vite/index.js
index d5867d31a4b2..dd675375633b 100644
--- a/packages/kit/src/vite/index.js
+++ b/packages/kit/src/vite/index.js
@@ -63,24 +63,7 @@ const enforced_config = {
* @return {import('vite').Plugin[]}
*/
export function sveltekit() {
- return [
- ...svelte({
- // IDEA: Maybe vite-plugin-svelte can me modified to allow extending the user's svelte.config.js
- // This would allow us to add inlineOptions with the preprocessing we need, without overwriting preprocessing from the user's config.
- preprocess: [
- preprocess({
- // // TODO: Update regex to only match attributes and not all string values, to prevent it from replacing text content.
- // // TODO: Ensure the replacement happens for prerendered HTML too
- replace: [
- [/sveltekit\:prefetch/g, 'data-sveltekit-prefetch'],
- [/sveltekit\:reload/g, 'data-sveltekit-reload'],
- [/sveltekit\:noscroll/g, 'data-sveltekit-noscroll']
- ]
- })
- ]
- }),
- kit()
- ];
+ return [...svelte(), kit()];
}
/**
@@ -208,6 +191,19 @@ function kit() {
return {
name: 'vite-plugin-svelte-kit',
+ api: {
+ // Replace custom attributes with valid HTML attributes
+ sveltePreprocess: preprocess({
+ // TODO: Update regex to only match attributes and not all string values, to prevent it from replacing text content.
+ // TODO: Ensure the replacement happens for SvelteKit packages too
+ replace: [
+ [/sveltekit\:prefetch/g, 'data-sveltekit-prefetch'],
+ [/sveltekit\:reload/g, 'data-sveltekit-reload'],
+ [/sveltekit\:noscroll/g, 'data-sveltekit-noscroll']
+ ]
+ })
+ },
+
/**
* Build the SvelteKit-provided Vite config to be merged with the user's vite.config.js file.
* @see https://vitejs.dev/guide/api-plugin.html#config
diff --git a/packages/kit/test/apps/options/svelte.config.js b/packages/kit/test/apps/options/svelte.config.js
index 59eed8019b5b..76f4628eae83 100644
--- a/packages/kit/test/apps/options/svelte.config.js
+++ b/packages/kit/test/apps/options/svelte.config.js
@@ -27,7 +27,6 @@ const config = {
}
},
preprocess: [
- // Test how combined user preprocessing works together with internal sveltekit preprocessing.
preprocess({
replace: [
[/sveltekit\:attribute/g, 'data-sveltekit-attribute'],
From bc03a40c28dae09db3fa7c5ca1048a55696da396 Mon Sep 17 00:00:00 2001
From: Samuel Plumppu <6125097+Greenheart@users.noreply.github.com>
Date: Mon, 22 Aug 2022 23:54:51 +0200
Subject: [PATCH 07/15] Cleanup
---
packages/kit/src/vite/index.js | 2 --
.../test/apps/options/source/pages/prefetching/+page.svelte | 6 ++++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/packages/kit/src/vite/index.js b/packages/kit/src/vite/index.js
index dd675375633b..4cca6882534d 100644
--- a/packages/kit/src/vite/index.js
+++ b/packages/kit/src/vite/index.js
@@ -212,8 +212,6 @@ function kit() {
vite_config_env = config_env;
svelte_config = await load_config();
- console.log('vite svelte.config.js preprocess', svelte_config.preprocess);
-
env = get_env(vite_config_env.mode, svelte_config.kit.env.publicPrefix);
// The config is created in build_server for SSR mode and passed inline
diff --git a/packages/kit/test/apps/options/source/pages/prefetching/+page.svelte b/packages/kit/test/apps/options/source/pages/prefetching/+page.svelte
index 28ba6017045b..16e618d3a7d2 100644
--- a/packages/kit/test/apps/options/source/pages/prefetching/+page.svelte
+++ b/packages/kit/test/apps/options/source/pages/prefetching/+page.svelte
@@ -1,9 +1,11 @@
click me for sveltekit:prefetch
-click me for sveltekit:attribute
- click me for sveltekit:noscroll click me for sveltekit:reload
+
+
click me for sveltekit:something
+
+click me for sveltekit:attribute
From 6c21f2338f8e3eb6cd68b3c0aa18595fdd7755ef Mon Sep 17 00:00:00 2001
From: Samuel Plumppu <6125097+Greenheart@users.noreply.github.com>
Date: Tue, 23 Aug 2022 08:06:07 +0200
Subject: [PATCH 08/15] Breaking: Rename sveltekit:prefetch to
data-sveltekit-precfetch
---
documentation/docs/09-a-options.md | 6 +++---
documentation/docs/80-migrating.md | 4 ++--
.../templates/default/src/lib/header/Header.svelte | 6 +++---
.../core/prerender/fixtures/basic-href/input.html | 4 ++--
packages/kit/src/vite/index.js | 14 --------------
.../options/source/pages/prefetching/+page.svelte | 12 +-----------
packages/kit/test/apps/options/svelte.config.js | 12 +-----------
packages/kit/types/ambient.d.ts | 2 +-
sites/kit.svelte.dev/src/lib/docs/Contents.svelte | 6 +++---
.../src/lib/search/SearchResultList.svelte | 2 +-
sites/kit.svelte.dev/src/routes/+page.svelte | 6 +++---
11 files changed, 20 insertions(+), 54 deletions(-)
diff --git a/documentation/docs/09-a-options.md b/documentation/docs/09-a-options.md
index ac5f6206ac8f..d6e7e7a67caf 100644
--- a/documentation/docs/09-a-options.md
+++ b/documentation/docs/09-a-options.md
@@ -2,16 +2,16 @@
title: Anchor options
---
-### sveltekit:prefetch
+### data-sveltekit-prefetch
SvelteKit uses code splitting to break your app into small chunks (one per route), ensuring fast startup times.
For _dynamic_ routes, such as our `src/routes/blog/[slug]/+page.svelte` example, that's not enough. In order to render the blog post, we need to fetch the data for it, and we can't do that until we know what `slug` is. In the worst case, that could cause lag as the browser waits for the data to come back from the server.
-We can mitigate that by _prefetching_ the data. Adding a `sveltekit:prefetch` attribute to a link...
+We can mitigate that by _prefetching_ the data. Adding a `data-sveltekit-prefetch` attribute to a link...
```html
-What is SvelteKit?
+What is SvelteKit?
```
...will cause SvelteKit to run the page's `load` function as soon as the user hovers over the link (on a desktop) or touches it (on mobile), rather than waiting for the `click` event to trigger navigation. Typically, this buys us an extra couple of hundred milliseconds, which is the difference between a user interface that feels laggy, and one that feels snappy.
diff --git a/documentation/docs/80-migrating.md b/documentation/docs/80-migrating.md
index ce59f49a194a..342e3f03bc60 100644
--- a/documentation/docs/80-migrating.md
+++ b/documentation/docs/80-migrating.md
@@ -135,8 +135,8 @@ This caused problems and is no longer the case in SvelteKit. Instead, relative U
#### <a> attributes
-- `sapper:prefetch` is now `sveltekit:prefetch`
-- `sapper:noscroll` is now `sveltekit:noscroll`
+- `sapper:prefetch` is now `data-sveltekit-prefetch`
+- `sapper:noscroll` is now `data-sveltekit-noscroll`
### Endpoints
diff --git a/packages/create-svelte/templates/default/src/lib/header/Header.svelte b/packages/create-svelte/templates/default/src/lib/header/Header.svelte
index 9d3120f3e6fd..4293c2389930 100644
--- a/packages/create-svelte/templates/default/src/lib/header/Header.svelte
+++ b/packages/create-svelte/templates/default/src/lib/header/Header.svelte
@@ -15,12 +15,12 @@