@sveltejs/vite-plugin-svelte 6.0.0-next.1 → 6.0.0-next.3
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.
- package/package.json +5 -5
- package/src/index.js +27 -258
- package/src/plugins/compile-module.js +51 -0
- package/src/plugins/compile.js +65 -0
- package/src/plugins/configure.js +97 -0
- package/src/plugins/hot-update.js +181 -0
- package/src/plugins/load-compiled-css.js +44 -0
- package/src/plugins/load-custom.js +42 -0
- package/src/plugins/preprocess.js +205 -0
- package/src/{utils/optimizer-plugins.js → plugins/setup-optimizer.js} +153 -8
- package/src/preprocess.js +6 -4
- package/src/public.d.ts +7 -0
- package/src/types/compile.d.ts +10 -4
- package/src/types/id.d.ts +1 -8
- package/src/types/plugin-api.d.ts +6 -7
- package/src/utils/compile.js +14 -53
- package/src/utils/constants.js +4 -4
- package/src/utils/dependencies.js +0 -29
- package/src/utils/id.js +7 -4
- package/src/utils/options.js +8 -90
- package/src/utils/preprocess.js +15 -99
- package/src/utils/vite-plugin-svelte-stats.js +59 -11
- package/src/utils/watch.js +4 -29
- package/types/index.d.ts +12 -0
- package/types/index.d.ts.map +1 -1
- package/src/handle-hot-update.js +0 -145
- package/src/utils/load-raw.js +0 -125
- package/src/utils/optimizer.js +0 -53
- package/src/utils/vite-plugin-svelte-cache.js +0 -212
package/src/utils/watch.js
CHANGED
|
@@ -5,41 +5,16 @@ import path from 'node:path';
|
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* @param {import('../types/options.d.ts').ResolvedOptions} options
|
|
8
|
-
* @param {import('./vite-plugin-svelte-cache.js').VitePluginSvelteCache} cache
|
|
9
|
-
* @param {import('../types/id.d.ts').IdParser} requestParser
|
|
10
8
|
* @returns {void}
|
|
11
9
|
*/
|
|
12
|
-
export function setupWatchers(options
|
|
10
|
+
export function setupWatchers(options) {
|
|
13
11
|
const { server, configFile: svelteConfigFile } = options;
|
|
14
12
|
if (!server) {
|
|
15
13
|
return;
|
|
16
14
|
}
|
|
17
15
|
const { watcher, ws } = server;
|
|
18
16
|
const { root, server: serverConfig } = server.config;
|
|
19
|
-
|
|
20
|
-
const emitChangeEventOnDependants = (filename) => {
|
|
21
|
-
const dependants = cache.getDependants(filename);
|
|
22
|
-
dependants.forEach((dependant) => {
|
|
23
|
-
if (fs.existsSync(dependant)) {
|
|
24
|
-
log.debug(
|
|
25
|
-
`emitting virtual change event for "${dependant}" because dependency "${filename}" changed`,
|
|
26
|
-
undefined,
|
|
27
|
-
'hmr'
|
|
28
|
-
);
|
|
29
|
-
watcher.emit('change', dependant);
|
|
30
|
-
}
|
|
31
|
-
});
|
|
32
|
-
};
|
|
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
|
-
};
|
|
17
|
+
|
|
43
18
|
/** @type {(filename: string) => void} */
|
|
44
19
|
const triggerViteRestart = (filename) => {
|
|
45
20
|
if (serverConfig.middlewareMode) {
|
|
@@ -62,8 +37,8 @@ export function setupWatchers(options, cache, requestParser) {
|
|
|
62
37
|
/** @type {Record<string, Function[]>} */
|
|
63
38
|
const listenerCollection = {
|
|
64
39
|
add: [],
|
|
65
|
-
change: [
|
|
66
|
-
unlink: [
|
|
40
|
+
change: [],
|
|
41
|
+
unlink: []
|
|
67
42
|
};
|
|
68
43
|
|
|
69
44
|
if (svelteConfigFile !== false) {
|
package/types/index.d.ts
CHANGED
|
@@ -173,6 +173,13 @@ declare module '@sveltejs/vite-plugin-svelte' {
|
|
|
173
173
|
*/
|
|
174
174
|
disableSvelteResolveWarnings?: boolean;
|
|
175
175
|
|
|
176
|
+
/**
|
|
177
|
+
* disable api.sveltePreprocess deprecation warnings
|
|
178
|
+
*
|
|
179
|
+
* @default false
|
|
180
|
+
*/
|
|
181
|
+
disableApiSveltePreprocessWarnings?: boolean;
|
|
182
|
+
|
|
176
183
|
compileModule?: CompileModuleOptions;
|
|
177
184
|
}
|
|
178
185
|
|
|
@@ -206,6 +213,11 @@ declare module '@sveltejs/vite-plugin-svelte' {
|
|
|
206
213
|
*/
|
|
207
214
|
style?: boolean | InlineConfig | ResolvedConfig;
|
|
208
215
|
}
|
|
216
|
+
/**
|
|
217
|
+
* returns a list of plugins to handle svelte files
|
|
218
|
+
* plugins are named `vite-plugin-svelte:<task>`
|
|
219
|
+
*
|
|
220
|
+
* */
|
|
209
221
|
export function svelte(inlineOptions?: Partial<Options>): import("vite").Plugin[];
|
|
210
222
|
export function vitePreprocess(opts?: VitePreprocessOptions): import("svelte/compiler").PreprocessorGroup;
|
|
211
223
|
export function loadSvelteConfig(viteConfig?: import("vite").UserConfig, inlineOptions?: Partial<Options>): Promise<Partial<SvelteConfig> | undefined>;
|
package/types/index.d.ts.map
CHANGED
|
@@ -26,6 +26,6 @@
|
|
|
26
26
|
null,
|
|
27
27
|
null
|
|
28
28
|
],
|
|
29
|
-
"mappings": ";;;;aAIYA,OAAOA;;WAETC,mBAAmBA;;;;;;;;;;;kBAWZC,aAAaA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAgGbC,YAAYA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WAiDnBC,mBAAmBA
|
|
29
|
+
"mappings": ";;;;aAIYA,OAAOA;;WAETC,mBAAmBA;;;;;;;;;;;kBAWZC,aAAaA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAgGbC,YAAYA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WAiDnBC,mBAAmBA;;;;;;;;;;;;;;;;;;;;;;;WAuBnBC,oBAAoBA;;;;;;;;;;;;;;;MAezBC,SAASA;;kBAEGC,qBAAqBA;;;;;;;;;;;;;;;;;;iBCvLtBC,MAAMA;iBCMNC,cAAcA;iBCFRC,gBAAgBA",
|
|
30
30
|
"ignoreList": []
|
|
31
31
|
}
|
package/src/handle-hot-update.js
DELETED
|
@@ -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
|
-
}
|
package/src/utils/load-raw.js
DELETED
|
@@ -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
|
-
}
|
package/src/utils/optimizer.js
DELETED
|
@@ -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
|
-
}
|
|
@@ -1,212 +0,0 @@
|
|
|
1
|
-
import { readFileSync } from 'node:fs';
|
|
2
|
-
import { dirname } from 'node:path';
|
|
3
|
-
import { findClosestPkgJsonPath } from 'vitefu';
|
|
4
|
-
import { normalizePath } from 'vite';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* @typedef {{
|
|
8
|
-
* name: string;
|
|
9
|
-
* version: string;
|
|
10
|
-
* svelte?: string;
|
|
11
|
-
* path: string;
|
|
12
|
-
* }} PackageInfo
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* @class
|
|
17
|
-
*/
|
|
18
|
-
export class VitePluginSvelteCache {
|
|
19
|
-
/** @type {Map<string, import('../types/compile.d.ts').Code | null>} */
|
|
20
|
-
#css = new Map();
|
|
21
|
-
/** @type {Map<string, import('../types/compile.d.ts').Code | null>} */
|
|
22
|
-
#js = new Map();
|
|
23
|
-
/** @type {Map<string, string[]>} */
|
|
24
|
-
#dependencies = new Map();
|
|
25
|
-
/** @type {Map<string, Set<string>>} */
|
|
26
|
-
#dependants = new Map();
|
|
27
|
-
/** @type {Map<string, any>} */
|
|
28
|
-
#errors = new Map();
|
|
29
|
-
/** @type {PackageInfo[]} */
|
|
30
|
-
#packageInfos = [];
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* @param {import('../types/compile.d.ts').CompileData} compileData
|
|
34
|
-
*/
|
|
35
|
-
update(compileData) {
|
|
36
|
-
this.#errors.delete(compileData.normalizedFilename);
|
|
37
|
-
this.#updateCSS(compileData);
|
|
38
|
-
this.#updateJS(compileData);
|
|
39
|
-
this.#updateDependencies(compileData);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* @param {import('../types/id.d.ts').SvelteRequest} svelteRequest
|
|
44
|
-
* @returns {boolean}
|
|
45
|
-
*/
|
|
46
|
-
has(svelteRequest) {
|
|
47
|
-
const id = svelteRequest.normalizedFilename;
|
|
48
|
-
return this.#errors.has(id) || this.#js.has(id) || this.#css.has(id);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* @param {import('../types/id.d.ts').SvelteRequest} svelteRequest
|
|
53
|
-
* @param {any} error
|
|
54
|
-
*/
|
|
55
|
-
setError(svelteRequest, error) {
|
|
56
|
-
// keep dependency info, otherwise errors in dependants would not trigger an update after fixing
|
|
57
|
-
// because they are no longer watched
|
|
58
|
-
this.remove(svelteRequest, true);
|
|
59
|
-
this.#errors.set(svelteRequest.normalizedFilename, error);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* @param {import('../types/compile.d.ts').CompileData} compileData
|
|
64
|
-
*/
|
|
65
|
-
#updateCSS(compileData) {
|
|
66
|
-
this.#css.set(compileData.normalizedFilename, compileData.compiled.css);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* @param {import('../types/compile.d.ts').CompileData} compileData
|
|
71
|
-
*/
|
|
72
|
-
#updateJS(compileData) {
|
|
73
|
-
if (!compileData.ssr) {
|
|
74
|
-
// do not cache SSR js
|
|
75
|
-
this.#js.set(compileData.normalizedFilename, compileData.compiled.js);
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* @param {import('../types/compile.d.ts').CompileData} compileData
|
|
81
|
-
*/
|
|
82
|
-
#updateDependencies(compileData) {
|
|
83
|
-
const id = compileData.normalizedFilename;
|
|
84
|
-
const prevDependencies = this.#dependencies.get(id) || [];
|
|
85
|
-
const dependencies = compileData.dependencies;
|
|
86
|
-
this.#dependencies.set(id, dependencies);
|
|
87
|
-
const removed = prevDependencies.filter((d) => !dependencies.includes(d));
|
|
88
|
-
const added = dependencies.filter((d) => !prevDependencies.includes(d));
|
|
89
|
-
added.forEach((d) => {
|
|
90
|
-
if (!this.#dependants.has(d)) {
|
|
91
|
-
this.#dependants.set(d, new Set());
|
|
92
|
-
}
|
|
93
|
-
/** @type {Set<string>} */ (this.#dependants.get(d)).add(compileData.filename);
|
|
94
|
-
});
|
|
95
|
-
removed.forEach((d) => {
|
|
96
|
-
/** @type {Set<string>} */ (this.#dependants.get(d)).delete(compileData.filename);
|
|
97
|
-
});
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* @param {import('../types/id.d.ts').SvelteRequest} svelteRequest
|
|
102
|
-
* @param {boolean} [keepDependencies]
|
|
103
|
-
* @returns {boolean}
|
|
104
|
-
*/
|
|
105
|
-
remove(svelteRequest, keepDependencies = false) {
|
|
106
|
-
const id = svelteRequest.normalizedFilename;
|
|
107
|
-
let removed = false;
|
|
108
|
-
if (this.#errors.delete(id)) {
|
|
109
|
-
removed = true;
|
|
110
|
-
}
|
|
111
|
-
if (this.#js.delete(id)) {
|
|
112
|
-
removed = true;
|
|
113
|
-
}
|
|
114
|
-
if (this.#css.delete(id)) {
|
|
115
|
-
removed = true;
|
|
116
|
-
}
|
|
117
|
-
if (!keepDependencies) {
|
|
118
|
-
const dependencies = this.#dependencies.get(id);
|
|
119
|
-
if (dependencies) {
|
|
120
|
-
removed = true;
|
|
121
|
-
dependencies.forEach((d) => {
|
|
122
|
-
const dependants = this.#dependants.get(d);
|
|
123
|
-
if (dependants && dependants.has(svelteRequest.filename)) {
|
|
124
|
-
dependants.delete(svelteRequest.filename);
|
|
125
|
-
}
|
|
126
|
-
});
|
|
127
|
-
this.#dependencies.delete(id);
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
return removed;
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
/**
|
|
135
|
-
* @param {import('../types/id.d.ts').SvelteRequest} svelteRequest
|
|
136
|
-
* @returns {import('../types/compile.d.ts').Code | undefined | null}
|
|
137
|
-
*/
|
|
138
|
-
getCSS(svelteRequest) {
|
|
139
|
-
return this.#css.get(svelteRequest.normalizedFilename);
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
/**
|
|
143
|
-
* @param {import('../types/id.d.ts').SvelteRequest} svelteRequest
|
|
144
|
-
* @returns {import('../types/compile.d.ts').Code | undefined | null}
|
|
145
|
-
*/
|
|
146
|
-
getJS(svelteRequest) {
|
|
147
|
-
if (!svelteRequest.ssr) {
|
|
148
|
-
// SSR js isn't cached
|
|
149
|
-
return this.#js.get(svelteRequest.normalizedFilename);
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
/**
|
|
153
|
-
* @param {import('../types/id.d.ts').SvelteRequest} svelteRequest
|
|
154
|
-
* @returns {any}
|
|
155
|
-
*/
|
|
156
|
-
getError(svelteRequest) {
|
|
157
|
-
return this.#errors.get(svelteRequest.normalizedFilename);
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
/**
|
|
161
|
-
* @param {string} path
|
|
162
|
-
* @returns {string[]}
|
|
163
|
-
*/
|
|
164
|
-
getDependants(path) {
|
|
165
|
-
const dependants = this.#dependants.get(path);
|
|
166
|
-
return dependants ? [...dependants] : [];
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
/**
|
|
170
|
-
* @param {string} file
|
|
171
|
-
* @returns {Promise<PackageInfo>}
|
|
172
|
-
*/
|
|
173
|
-
async getPackageInfo(file) {
|
|
174
|
-
let info = this.#packageInfos.find((pi) => file.startsWith(pi.path));
|
|
175
|
-
if (!info) {
|
|
176
|
-
info = await findPackageInfo(file);
|
|
177
|
-
this.#packageInfos.push(info);
|
|
178
|
-
}
|
|
179
|
-
return info;
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
/**
|
|
184
|
-
* utility to get some info from the closest package.json with a "name" set
|
|
185
|
-
*
|
|
186
|
-
* @param {string} file to find info for
|
|
187
|
-
* @returns {Promise<PackageInfo>}
|
|
188
|
-
*/
|
|
189
|
-
async function findPackageInfo(file) {
|
|
190
|
-
/** @type {PackageInfo} */
|
|
191
|
-
const info = {
|
|
192
|
-
name: '$unknown',
|
|
193
|
-
version: '0.0.0-unknown',
|
|
194
|
-
path: '$unknown'
|
|
195
|
-
};
|
|
196
|
-
let path = await findClosestPkgJsonPath(file, (pkgPath) => {
|
|
197
|
-
const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
|
|
198
|
-
if (pkg.name != null) {
|
|
199
|
-
info.name = pkg.name;
|
|
200
|
-
if (pkg.version != null) {
|
|
201
|
-
info.version = pkg.version;
|
|
202
|
-
}
|
|
203
|
-
info.svelte = pkg.svelte;
|
|
204
|
-
return true;
|
|
205
|
-
}
|
|
206
|
-
return false;
|
|
207
|
-
});
|
|
208
|
-
// return normalized path with appended '/' so .startsWith works for future file checks
|
|
209
|
-
path = normalizePath(dirname(path ?? file)) + '/';
|
|
210
|
-
info.path = path;
|
|
211
|
-
return info;
|
|
212
|
-
}
|