@sveltejs/vite-plugin-svelte 6.0.0-next.0 → 6.0.0-next.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6,10 +6,9 @@ import path from 'node:path';
6
6
  /**
7
7
  * @param {import('../types/options.d.ts').ResolvedOptions} options
8
8
  * @param {import('./vite-plugin-svelte-cache.js').VitePluginSvelteCache} cache
9
- * @param {import('../types/id.d.ts').IdParser} requestParser
10
9
  * @returns {void}
11
10
  */
12
- export function setupWatchers(options, cache, requestParser) {
11
+ export function setupWatchers(options, cache) {
13
12
  const { server, configFile: svelteConfigFile } = options;
14
13
  if (!server) {
15
14
  return;
@@ -30,16 +29,7 @@ export function setupWatchers(options, cache, requestParser) {
30
29
  }
31
30
  });
32
31
  };
33
- /** @type {(filename: string) => void} */
34
- const removeUnlinkedFromCache = (filename) => {
35
- const svelteRequest = requestParser(filename, false);
36
- if (svelteRequest) {
37
- const removedFromCache = cache.remove(svelteRequest);
38
- if (removedFromCache) {
39
- log.debug(`cleared VitePluginSvelteCache for deleted file ${filename}`, undefined, 'hmr');
40
- }
41
- }
42
- };
32
+
43
33
  /** @type {(filename: string) => void} */
44
34
  const triggerViteRestart = (filename) => {
45
35
  if (serverConfig.middlewareMode) {
@@ -63,7 +53,7 @@ export function setupWatchers(options, cache, requestParser) {
63
53
  const listenerCollection = {
64
54
  add: [],
65
55
  change: [emitChangeEventOnDependants],
66
- unlink: [removeUnlinkedFromCache, emitChangeEventOnDependants]
56
+ unlink: [emitChangeEventOnDependants]
67
57
  };
68
58
 
69
59
  if (svelteConfigFile !== false) {
package/types/index.d.ts CHANGED
@@ -206,6 +206,11 @@ declare module '@sveltejs/vite-plugin-svelte' {
206
206
  */
207
207
  style?: boolean | InlineConfig | ResolvedConfig;
208
208
  }
209
+ /**
210
+ * returns a list of plugins to handle svelte files
211
+ * plugins are named `vite-plugin-svelte:<task>`
212
+ *
213
+ * */
209
214
  export function svelte(inlineOptions?: Partial<Options>): import("vite").Plugin[];
210
215
  export function vitePreprocess(opts?: VitePreprocessOptions): import("svelte/compiler").PreprocessorGroup;
211
216
  export function loadSvelteConfig(viteConfig?: import("vite").UserConfig, inlineOptions?: Partial<Options>): Promise<Partial<SvelteConfig> | undefined>;
@@ -26,6 +26,6 @@
26
26
  null,
27
27
  null
28
28
  ],
29
- "mappings": ";;;;aAIYA,OAAOA;;WAETC,mBAAmBA;;;;;;;;;;;kBAWZC,aAAaA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAgGbC,YAAYA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WAiDnBC,mBAAmBA;;;;;;;;;;;;;;;;WAgBnBC,oBAAoBA;;;;;;;;;;;;;;;MAezBC,SAASA;;kBAEGC,qBAAqBA;;;;;;;;;;;;;iBC/JtBC,MAAMA;iBCXNC,cAAcA;iBCORC,gBAAgBA",
29
+ "mappings": ";;;;aAIYA,OAAOA;;WAETC,mBAAmBA;;;;;;;;;;;kBAWZC,aAAaA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAgGbC,YAAYA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WAiDnBC,mBAAmBA;;;;;;;;;;;;;;;;WAgBnBC,oBAAoBA;;;;;;;;;;;;;;;MAezBC,SAASA;;kBAEGC,qBAAqBA;;;;;;;;;;;;;;;;;;iBChLtBC,MAAMA;iBCMNC,cAAcA;iBCFRC,gBAAgBA",
30
30
  "ignoreList": []
31
31
  }
@@ -1,145 +0,0 @@
1
- import { log, logCompilerWarnings } from './utils/log.js';
2
- import { toRollupError } from './utils/error.js';
3
-
4
- /**
5
- * Vite-specific HMR handling
6
- *
7
- * @param {Function} compileSvelte
8
- * @param {import('vite').HmrContext} ctx
9
- * @param {import('./types/id.d.ts').SvelteRequest} svelteRequest
10
- * @param {import('./utils/vite-plugin-svelte-cache.js').VitePluginSvelteCache} cache
11
- * @param {import('./types/options.d.ts').ResolvedOptions} options
12
- * @returns {Promise<import('vite').ModuleNode[] | void>}
13
- */
14
- export async function handleHotUpdate(compileSvelte, ctx, svelteRequest, cache, options) {
15
- if (!cache.has(svelteRequest)) {
16
- // file hasn't been requested yet (e.g. async component)
17
- log.debug(
18
- `handleHotUpdate called before initial transform for ${svelteRequest.id}`,
19
- undefined,
20
- 'hmr'
21
- );
22
- return;
23
- }
24
- const { read, server, modules } = ctx;
25
-
26
- const cachedJS = cache.getJS(svelteRequest);
27
- const cachedCss = cache.getCSS(svelteRequest);
28
-
29
- const content = await read();
30
- /** @type {import('./types/compile.d.ts').CompileData} */
31
- let compileData;
32
- try {
33
- compileData = await compileSvelte(svelteRequest, content, options);
34
- cache.update(compileData);
35
- } catch (e) {
36
- cache.setError(svelteRequest, e);
37
- throw toRollupError(e, options);
38
- }
39
-
40
- const affectedModules = [...modules];
41
-
42
- const cssIdx = modules.findIndex((m) => m.id === svelteRequest.cssId);
43
- if (cssIdx > -1) {
44
- const cssUpdated = cssChanged(cachedCss, compileData.compiled.css);
45
- if (!cssUpdated) {
46
- log.debug(`skipping unchanged css for ${svelteRequest.cssId}`, undefined, 'hmr');
47
- affectedModules.splice(cssIdx, 1);
48
- }
49
- }
50
- const jsIdx = modules.findIndex((m) => m.id === svelteRequest.id);
51
- if (jsIdx > -1) {
52
- const jsUpdated = jsChanged(cachedJS, compileData.compiled.js, svelteRequest.filename);
53
- if (!jsUpdated) {
54
- log.debug(`skipping unchanged js for ${svelteRequest.id}`, undefined, 'hmr');
55
- affectedModules.splice(jsIdx, 1);
56
- // transform won't be called, log warnings here
57
- logCompilerWarnings(svelteRequest, compileData.compiled.warnings, options);
58
- }
59
- }
60
-
61
- // TODO is this enough? see also: https://github.com/vitejs/vite/issues/2274
62
- const ssrModulesToInvalidate = affectedModules.filter((m) => !!m.ssrTransformResult);
63
- if (ssrModulesToInvalidate.length > 0) {
64
- log.debug(
65
- `invalidating modules ${ssrModulesToInvalidate.map((m) => m.id).join(', ')}`,
66
- undefined,
67
- 'hmr'
68
- );
69
- ssrModulesToInvalidate.forEach((moduleNode) => server.moduleGraph.invalidateModule(moduleNode));
70
- }
71
- if (affectedModules.length > 0) {
72
- log.debug(
73
- `handleHotUpdate for ${svelteRequest.id} result: ${affectedModules
74
- .map((m) => m.id)
75
- .join(', ')}`,
76
- undefined,
77
- 'hmr'
78
- );
79
- }
80
- return affectedModules;
81
- }
82
-
83
- /**
84
- * @param {import('./types/compile.d.ts').Code | null} [prev]
85
- * @param {import('./types/compile.d.ts').Code | null} [next]
86
- * @returns {boolean}
87
- */
88
- function cssChanged(prev, next) {
89
- return !isCodeEqual(prev?.code, next?.code);
90
- }
91
-
92
- /**
93
- * @param {import('./types/compile.d.ts').Code | null} [prev]
94
- * @param {import('./types/compile.d.ts').Code | null} [next]
95
- * @param {string} [filename]
96
- * @returns {boolean}
97
- */
98
- function jsChanged(prev, next, filename) {
99
- const prevJs = prev?.code;
100
- const nextJs = next?.code;
101
- const isStrictEqual = isCodeEqual(prevJs, nextJs);
102
- if (isStrictEqual) {
103
- return false;
104
- }
105
- const isLooseEqual = isCodeEqual(normalizeJsCode(prevJs), normalizeJsCode(nextJs));
106
- if (!isStrictEqual && isLooseEqual) {
107
- log.debug(
108
- `ignoring compiler output js change for ${filename} as it is equal to previous output after normalization`,
109
- undefined,
110
- 'hmr'
111
- );
112
- }
113
- return !isLooseEqual;
114
- }
115
-
116
- /**
117
- * @param {string} [prev]
118
- * @param {string} [next]
119
- * @returns {boolean}
120
- */
121
- function isCodeEqual(prev, next) {
122
- if (!prev && !next) {
123
- return true;
124
- }
125
- if ((!prev && next) || (prev && !next)) {
126
- return false;
127
- }
128
- return prev === next;
129
- }
130
-
131
- /**
132
- * remove code that only changes metadata and does not require a js update for the component to keep working
133
- *
134
- * 1) add_location() calls. These add location metadata to elements, only used by some dev tools
135
- * 2) ... maybe more (or less) in the future
136
- *
137
- * @param {string} [code]
138
- * @returns {string | undefined}
139
- */
140
- function normalizeJsCode(code) {
141
- if (!code) {
142
- return code;
143
- }
144
- return code.replace(/\s*\badd_location\s*\([^)]*\)\s*;?/g, '');
145
- }
@@ -1,125 +0,0 @@
1
- import fs from 'node:fs';
2
- import { toRollupError } from './error.js';
3
- import { log } from './log.js';
4
-
5
- /**
6
- * utility function to compile ?raw and ?direct requests in load hook
7
- *
8
- * @param {import('../types/id.d.ts').SvelteRequest} svelteRequest
9
- * @param {import('../types/compile.d.ts').CompileSvelte} compileSvelte
10
- * @param {import('../types/options.d.ts').ResolvedOptions} options
11
- * @returns {Promise<string>}
12
- */
13
- export async function loadRaw(svelteRequest, compileSvelte, options) {
14
- const { id, filename, query } = svelteRequest;
15
-
16
- // raw svelte subrequest, compile on the fly and return requested subpart
17
- let compileData;
18
- const source = fs.readFileSync(filename, 'utf-8');
19
- try {
20
- //avoid compileSvelte doing extra ssr stuff unless requested
21
- svelteRequest.ssr = query.compilerOptions?.generate === 'server';
22
- compileData = await compileSvelte(svelteRequest, source, {
23
- ...options,
24
- // don't use dynamic vite-plugin-svelte defaults here to ensure stable result between ssr,dev and build
25
- compilerOptions: {
26
- dev: false,
27
- css: 'external',
28
- hmr: false,
29
- ...svelteRequest.query.compilerOptions
30
- },
31
- emitCss: true
32
- });
33
- } catch (e) {
34
- throw toRollupError(e, options);
35
- }
36
- let result;
37
- if (query.type === 'style') {
38
- result = compileData.compiled.css ?? { code: '', map: null };
39
- } else if (query.type === 'script') {
40
- result = compileData.compiled.js;
41
- } else if (query.type === 'preprocessed') {
42
- result = compileData.preprocessed;
43
- } else if (query.type === 'all' && query.raw) {
44
- return allToRawExports(compileData, source);
45
- } else {
46
- throw new Error(
47
- `invalid "type=${query.type}" in ${id}. supported are script, style, preprocessed, all`
48
- );
49
- }
50
- if (query.direct) {
51
- const supportedDirectTypes = ['script', 'style'];
52
- if (!supportedDirectTypes.includes(query.type)) {
53
- throw new Error(
54
- `invalid "type=${
55
- query.type
56
- }" combined with direct in ${id}. supported are: ${supportedDirectTypes.join(', ')}`
57
- );
58
- }
59
- log.debug(`load returns direct result for ${id}`, undefined, 'load');
60
- let directOutput = result.code;
61
- // @ts-expect-error might not be SourceMap but toUrl check should suffice
62
- if (query.sourcemap && result.map?.toUrl) {
63
- // @ts-expect-error toUrl might not exist
64
- const map = `sourceMappingURL=${result.map.toUrl()}`;
65
- if (query.type === 'style') {
66
- directOutput += `\n\n/*# ${map} */\n`;
67
- } else if (query.type === 'script') {
68
- directOutput += `\n\n//# ${map}\n`;
69
- }
70
- }
71
- return directOutput;
72
- } else if (query.raw) {
73
- log.debug(`load returns raw result for ${id}`, undefined, 'load');
74
- return toRawExports(result);
75
- } else {
76
- throw new Error(`invalid raw mode in ${id}, supported are raw, direct`);
77
- }
78
- }
79
-
80
- /**
81
- * turn compileData and source into a flat list of raw exports
82
- *
83
- * @param {import('../types/compile.d.ts').CompileData} compileData
84
- * @param {string} source
85
- */
86
- function allToRawExports(compileData, source) {
87
- // flatten CompileData
88
- /** @type {Partial<import('../types/compile.d.ts').CompileData & { source: string }>} */
89
- const exports = {
90
- ...compileData,
91
- ...compileData.compiled,
92
- source
93
- };
94
- delete exports.compiled;
95
- delete exports.filename; // absolute path, remove to avoid it in output
96
- return toRawExports(exports);
97
- }
98
-
99
- /**
100
- * turn object into raw exports.
101
- *
102
- * every prop is returned as a const export, and if prop 'code' exists it is additionally added as default export
103
- *
104
- * eg {'foo':'bar','code':'baz'} results in
105
- *
106
- * ```js
107
- * export const code='baz'
108
- * export const foo='bar'
109
- * export default code
110
- * ```
111
- * @param {object} object
112
- * @returns {string}
113
- */
114
- function toRawExports(object) {
115
- let exports =
116
- Object.entries(object)
117
- .filter(([_key, value]) => typeof value !== 'function') // preprocess output has a toString function that's enumerable
118
- .sort(([a], [b]) => (a < b ? -1 : a === b ? 0 : 1))
119
- .map(([key, value]) => `export const ${key}=${JSON.stringify(value)}`)
120
- .join('\n') + '\n';
121
- if (Object.prototype.hasOwnProperty.call(object, 'code')) {
122
- exports += 'export default code\n';
123
- }
124
- return exports;
125
- }
@@ -1,53 +0,0 @@
1
- import { promises as fs } from 'node:fs';
2
- import path from 'node:path';
3
-
4
- // List of options that changes the prebundling result
5
- /** @type {(keyof import('../types/options.d.ts').ResolvedOptions)[]} */
6
- const PREBUNDLE_SENSITIVE_OPTIONS = [
7
- 'compilerOptions',
8
- 'configFile',
9
- 'experimental',
10
- 'extensions',
11
- 'ignorePluginPreprocessors',
12
- 'preprocess'
13
- ];
14
-
15
- /**
16
- * @param {string} cacheDir
17
- * @param {import('../types/options.d.ts').ResolvedOptions} options
18
- * @returns {Promise<boolean>} Whether the Svelte metadata has changed
19
- */
20
- export async function saveSvelteMetadata(cacheDir, options) {
21
- const svelteMetadata = generateSvelteMetadata(options);
22
- const svelteMetadataPath = path.resolve(cacheDir, '_svelte_metadata.json');
23
-
24
- const currentSvelteMetadata = JSON.stringify(svelteMetadata, (_, value) => {
25
- // Handle preprocessors
26
- return typeof value === 'function' ? value.toString() : value;
27
- });
28
-
29
- /** @type {string | undefined} */
30
- let existingSvelteMetadata;
31
- try {
32
- existingSvelteMetadata = await fs.readFile(svelteMetadataPath, 'utf8');
33
- } catch {
34
- // ignore
35
- }
36
-
37
- await fs.mkdir(cacheDir, { recursive: true });
38
- await fs.writeFile(svelteMetadataPath, currentSvelteMetadata);
39
- return currentSvelteMetadata !== existingSvelteMetadata;
40
- }
41
-
42
- /**
43
- * @param {import('../types/options.d.ts').ResolvedOptions} options
44
- * @returns {Partial<import('../types/options.d.ts').ResolvedOptions>}
45
- */
46
- function generateSvelteMetadata(options) {
47
- /** @type {Record<string, any>} */
48
- const metadata = {};
49
- for (const key of PREBUNDLE_SENSITIVE_OPTIONS) {
50
- metadata[key] = options[key];
51
- }
52
- return metadata;
53
- }