@sveltejs/vite-plugin-svelte 5.0.3 → 6.0.0-next.0
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 +12 -15
- package/src/index.js +139 -106
- package/src/preprocess.js +43 -3
- package/src/public.d.ts +4 -4
- package/src/types/compile.d.ts +6 -0
- package/src/types/id.d.ts +7 -0
- package/src/utils/compile.js +1 -1
- package/src/utils/constants.js +13 -3
- package/src/utils/error.js +4 -2
- package/src/utils/id.js +58 -40
- package/src/utils/{esbuild.js → optimizer-plugins.js} +88 -70
- package/src/utils/options.js +66 -35
- package/types/index.d.ts +4 -4
- package/types/index.d.ts.map +5 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sveltejs/vite-plugin-svelte",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "6.0.0-next.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"author": "dominikg",
|
|
6
6
|
"files": [
|
|
@@ -11,14 +11,12 @@
|
|
|
11
11
|
"types": "types/index.d.ts",
|
|
12
12
|
"exports": {
|
|
13
13
|
".": {
|
|
14
|
-
"
|
|
15
|
-
|
|
16
|
-
"default": "./src/index.js"
|
|
17
|
-
}
|
|
14
|
+
"types": "./types/index.d.ts",
|
|
15
|
+
"default": "./src/index.js"
|
|
18
16
|
}
|
|
19
17
|
},
|
|
20
18
|
"engines": {
|
|
21
|
-
"node": "^
|
|
19
|
+
"node": "^20.19 || ^22.12 || >=24"
|
|
22
20
|
},
|
|
23
21
|
"repository": {
|
|
24
22
|
"type": "git",
|
|
@@ -36,23 +34,22 @@
|
|
|
36
34
|
},
|
|
37
35
|
"homepage": "https://github.com/sveltejs/vite-plugin-svelte#readme",
|
|
38
36
|
"dependencies": {
|
|
39
|
-
"
|
|
40
|
-
"debug": "^4.4.0",
|
|
37
|
+
"debug": "^4.4.1",
|
|
41
38
|
"deepmerge": "^4.3.1",
|
|
42
39
|
"kleur": "^4.1.5",
|
|
43
|
-
"magic-string": "^0.30.
|
|
44
|
-
"vitefu": "^1.0.
|
|
40
|
+
"magic-string": "^0.30.17",
|
|
41
|
+
"vitefu": "^1.0.6",
|
|
42
|
+
"@sveltejs/vite-plugin-svelte-inspector": "^5.0.0-next.0"
|
|
45
43
|
},
|
|
46
44
|
"peerDependencies": {
|
|
47
45
|
"svelte": "^5.0.0",
|
|
48
|
-
"vite": "^6.0.0"
|
|
46
|
+
"vite": "^6.3.0 || ^7.0.0-beta.0"
|
|
49
47
|
},
|
|
50
48
|
"devDependencies": {
|
|
51
49
|
"@types/debug": "^4.1.12",
|
|
52
|
-
"
|
|
53
|
-
"
|
|
54
|
-
"
|
|
55
|
-
"vite": "^6.0.3"
|
|
50
|
+
"sass": "^1.89.1",
|
|
51
|
+
"svelte": "^5.33.18",
|
|
52
|
+
"vite": "^7.0.0-beta.0"
|
|
56
53
|
},
|
|
57
54
|
"scripts": {
|
|
58
55
|
"check:publint": "publint --strict",
|
package/src/index.js
CHANGED
|
@@ -4,7 +4,12 @@ import { svelteInspector } from '@sveltejs/vite-plugin-svelte-inspector';
|
|
|
4
4
|
import { handleHotUpdate } from './handle-hot-update.js';
|
|
5
5
|
import { log, logCompilerWarnings } from './utils/log.js';
|
|
6
6
|
import { createCompileSvelte } from './utils/compile.js';
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
buildIdFilter,
|
|
9
|
+
buildIdParser,
|
|
10
|
+
buildModuleIdFilter,
|
|
11
|
+
buildModuleIdParser
|
|
12
|
+
} from './utils/id.js';
|
|
8
13
|
import {
|
|
9
14
|
buildExtraViteConfig,
|
|
10
15
|
validateInlineOptions,
|
|
@@ -20,6 +25,10 @@ import { saveSvelteMetadata } from './utils/optimizer.js';
|
|
|
20
25
|
import { VitePluginSvelteCache } from './utils/vite-plugin-svelte-cache.js';
|
|
21
26
|
import { loadRaw } from './utils/load-raw.js';
|
|
22
27
|
import * as svelteCompiler from 'svelte/compiler';
|
|
28
|
+
import { SVELTE_VIRTUAL_STYLE_ID_REGEX } from './utils/constants.js';
|
|
29
|
+
import * as vite from 'vite';
|
|
30
|
+
// @ts-expect-error rolldownVersion
|
|
31
|
+
const { version: viteVersion, rolldownVersion } = vite;
|
|
23
32
|
|
|
24
33
|
/**
|
|
25
34
|
* @param {Partial<import('./public.d.ts').Options>} [inlineOptions]
|
|
@@ -29,6 +38,12 @@ export function svelte(inlineOptions) {
|
|
|
29
38
|
if (process.env.DEBUG != null) {
|
|
30
39
|
log.setLevel('debug');
|
|
31
40
|
}
|
|
41
|
+
if (rolldownVersion) {
|
|
42
|
+
log.warn.once(
|
|
43
|
+
`!!! Support for rolldown-vite in vite-plugin-svelte is experimental (rolldown: ${rolldownVersion}, vite: ${viteVersion}) !!!`
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
|
|
32
47
|
validateInlineOptions(inlineOptions);
|
|
33
48
|
const cache = new VitePluginSvelteCache();
|
|
34
49
|
// updated in configResolved hook
|
|
@@ -42,67 +57,74 @@ export function svelte(inlineOptions) {
|
|
|
42
57
|
let viteConfig;
|
|
43
58
|
/** @type {import('./types/compile.d.ts').CompileSvelte} */
|
|
44
59
|
let compileSvelte;
|
|
45
|
-
/** @type {import('./types/plugin-api.d.ts').PluginAPI} */
|
|
46
|
-
const api = {};
|
|
47
|
-
/** @type {import('vite').Plugin[]} */
|
|
48
|
-
const plugins = [
|
|
49
|
-
{
|
|
50
|
-
name: 'vite-plugin-svelte',
|
|
51
|
-
// make sure our resolver runs before vite internal resolver to resolve svelte field correctly
|
|
52
|
-
enforce: 'pre',
|
|
53
|
-
api,
|
|
54
|
-
async config(config, configEnv) {
|
|
55
|
-
// setup logger
|
|
56
|
-
if (process.env.DEBUG) {
|
|
57
|
-
log.setLevel('debug');
|
|
58
|
-
} else if (config.logLevel) {
|
|
59
|
-
log.setLevel(config.logLevel);
|
|
60
|
-
}
|
|
61
|
-
// @ts-expect-error temporarily lend the options variable until fixed in configResolved
|
|
62
|
-
options = await preResolveOptions(inlineOptions, config, configEnv);
|
|
63
|
-
// extra vite config
|
|
64
|
-
const extraViteConfig = await buildExtraViteConfig(options, config);
|
|
65
|
-
log.debug('additional vite config', extraViteConfig, 'config');
|
|
66
|
-
return extraViteConfig;
|
|
67
|
-
},
|
|
68
|
-
|
|
69
|
-
configEnvironment(name, config, opts) {
|
|
70
|
-
ensureConfigEnvironmentMainFields(name, config, opts);
|
|
71
|
-
// @ts-expect-error the function above should make `resolve.mainFields` non-nullable
|
|
72
|
-
config.resolve.mainFields.unshift('svelte');
|
|
73
|
-
|
|
74
|
-
ensureConfigEnvironmentConditions(name, config, opts);
|
|
75
|
-
// @ts-expect-error the function above should make `resolve.conditions` non-nullable
|
|
76
|
-
config.resolve.conditions.push('svelte');
|
|
77
|
-
},
|
|
78
|
-
|
|
79
|
-
async configResolved(config) {
|
|
80
|
-
options = resolveOptions(options, config, cache);
|
|
81
|
-
patchResolvedViteConfig(config, options);
|
|
82
|
-
requestParser = buildIdParser(options);
|
|
83
|
-
compileSvelte = createCompileSvelte();
|
|
84
|
-
viteConfig = config;
|
|
85
|
-
// TODO deep clone to avoid mutability from outside?
|
|
86
|
-
api.options = options;
|
|
87
|
-
log.debug('resolved options', options, 'config');
|
|
88
|
-
},
|
|
89
|
-
|
|
90
|
-
async buildStart() {
|
|
91
|
-
if (!options.prebundleSvelteLibraries) return;
|
|
92
|
-
const isSvelteMetadataChanged = await saveSvelteMetadata(viteConfig.cacheDir, options);
|
|
93
|
-
if (isSvelteMetadataChanged) {
|
|
94
|
-
// Force Vite to optimize again. Although we mutate the config here, it works because
|
|
95
|
-
// Vite's optimizer runs after `buildStart()`.
|
|
96
|
-
viteConfig.optimizeDeps.force = true;
|
|
97
|
-
}
|
|
98
|
-
},
|
|
99
60
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
61
|
+
/** @type {import('vite').Plugin} */
|
|
62
|
+
const compilePlugin = {
|
|
63
|
+
name: 'vite-plugin-svelte',
|
|
64
|
+
// make sure our resolver runs before vite internal resolver to resolve svelte field correctly
|
|
65
|
+
enforce: 'pre',
|
|
66
|
+
/** @type {import('./types/plugin-api.d.ts').PluginAPI} */
|
|
67
|
+
api: {},
|
|
68
|
+
async config(config, configEnv) {
|
|
69
|
+
// setup logger
|
|
70
|
+
if (process.env.DEBUG) {
|
|
71
|
+
log.setLevel('debug');
|
|
72
|
+
} else if (config.logLevel) {
|
|
73
|
+
log.setLevel(config.logLevel);
|
|
74
|
+
}
|
|
75
|
+
// @ts-expect-error temporarily lend the options variable until fixed in configResolved
|
|
76
|
+
options = await preResolveOptions(inlineOptions, config, configEnv);
|
|
77
|
+
// extra vite config
|
|
78
|
+
const extraViteConfig = await buildExtraViteConfig(options, config);
|
|
79
|
+
log.debug('additional vite config', extraViteConfig, 'config');
|
|
80
|
+
return extraViteConfig;
|
|
81
|
+
},
|
|
82
|
+
|
|
83
|
+
configEnvironment(name, config, opts) {
|
|
84
|
+
ensureConfigEnvironmentMainFields(name, config, opts);
|
|
85
|
+
// @ts-expect-error the function above should make `resolve.mainFields` non-nullable
|
|
86
|
+
config.resolve.mainFields.unshift('svelte');
|
|
87
|
+
|
|
88
|
+
ensureConfigEnvironmentConditions(name, config, opts);
|
|
89
|
+
// @ts-expect-error the function above should make `resolve.conditions` non-nullable
|
|
90
|
+
config.resolve.conditions.push('svelte');
|
|
91
|
+
},
|
|
92
|
+
|
|
93
|
+
async configResolved(config) {
|
|
94
|
+
options = resolveOptions(options, config, cache);
|
|
95
|
+
patchResolvedViteConfig(config, options);
|
|
96
|
+
const filter = buildIdFilter(options);
|
|
97
|
+
//@ts-expect-error transform defined below but filter not in type
|
|
98
|
+
compilePlugin.transform.filter = filter;
|
|
99
|
+
//@ts-expect-error load defined below but filter not in type
|
|
100
|
+
compilePlugin.load.filter = filter;
|
|
101
|
+
|
|
102
|
+
requestParser = buildIdParser(options);
|
|
103
|
+
compileSvelte = createCompileSvelte();
|
|
104
|
+
viteConfig = config;
|
|
105
|
+
// TODO deep clone to avoid mutability from outside?
|
|
106
|
+
compilePlugin.api.options = options;
|
|
107
|
+
log.debug('resolved options', options, 'config');
|
|
108
|
+
log.debug('filters', filter, 'config');
|
|
109
|
+
},
|
|
110
|
+
|
|
111
|
+
async buildStart() {
|
|
112
|
+
if (!options.prebundleSvelteLibraries) return;
|
|
113
|
+
const isSvelteMetadataChanged = await saveSvelteMetadata(viteConfig.cacheDir, options);
|
|
114
|
+
if (isSvelteMetadataChanged) {
|
|
115
|
+
// Force Vite to optimize again. Although we mutate the config here, it works because
|
|
116
|
+
// Vite's optimizer runs after `buildStart()`.
|
|
117
|
+
viteConfig.optimizeDeps.force = true;
|
|
118
|
+
}
|
|
119
|
+
},
|
|
104
120
|
|
|
105
|
-
|
|
121
|
+
configureServer(server) {
|
|
122
|
+
options.server = server;
|
|
123
|
+
setupWatchers(options, cache, requestParser);
|
|
124
|
+
},
|
|
125
|
+
|
|
126
|
+
load: {
|
|
127
|
+
async handler(id, opts) {
|
|
106
128
|
const ssr = !!opts?.ssr;
|
|
107
129
|
const svelteRequest = requestParser(id, !!ssr);
|
|
108
130
|
if (svelteRequest) {
|
|
@@ -118,8 +140,17 @@ export function svelte(inlineOptions) {
|
|
|
118
140
|
};
|
|
119
141
|
} else {
|
|
120
142
|
if (query.svelte && query.type === 'style') {
|
|
121
|
-
const
|
|
122
|
-
if (
|
|
143
|
+
const cachedCss = cache.getCSS(svelteRequest);
|
|
144
|
+
if (cachedCss) {
|
|
145
|
+
const { hasGlobal, ...css } = cachedCss;
|
|
146
|
+
if (hasGlobal === false) {
|
|
147
|
+
// hasGlobal was added in svelte 5.26.0, so make sure it is boolean false
|
|
148
|
+
css.meta ??= {};
|
|
149
|
+
css.meta.vite ??= {};
|
|
150
|
+
css.meta.vite.cssScopeTo = [svelteRequest.filename, 'default'];
|
|
151
|
+
}
|
|
152
|
+
css.moduleType = 'css';
|
|
153
|
+
|
|
123
154
|
return css;
|
|
124
155
|
}
|
|
125
156
|
}
|
|
@@ -130,30 +161,23 @@ export function svelte(inlineOptions) {
|
|
|
130
161
|
}
|
|
131
162
|
}
|
|
132
163
|
}
|
|
133
|
-
}
|
|
164
|
+
}
|
|
165
|
+
},
|
|
134
166
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
log.debug(
|
|
147
|
-
`resolveId resolved virtual css module ${svelteRequest.cssId}`,
|
|
148
|
-
undefined,
|
|
149
|
-
'resolve'
|
|
150
|
-
);
|
|
151
|
-
return svelteRequest.cssId;
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
},
|
|
167
|
+
resolveId: {
|
|
168
|
+
// we don't use our generic filter here but a reduced one that only matches our virtual css
|
|
169
|
+
filter: { id: SVELTE_VIRTUAL_STYLE_ID_REGEX },
|
|
170
|
+
handler(id) {
|
|
171
|
+
// return cssId with root prefix so postcss pipeline of vite finds the directory correctly
|
|
172
|
+
// see https://github.com/sveltejs/vite-plugin-svelte/issues/14
|
|
173
|
+
log.debug(`resolveId resolved virtual css module ${id}`, undefined, 'resolve');
|
|
174
|
+
// TODO: do we have to repeat the dance for constructing the virtual id here? our transform added it that way
|
|
175
|
+
return id;
|
|
176
|
+
}
|
|
177
|
+
},
|
|
155
178
|
|
|
156
|
-
|
|
179
|
+
transform: {
|
|
180
|
+
async handler(code, id, opts) {
|
|
157
181
|
const ssr = !!opts?.ssr;
|
|
158
182
|
const svelteRequest = requestParser(id, ssr);
|
|
159
183
|
if (!svelteRequest || svelteRequest.query.type === 'style' || svelteRequest.raw) {
|
|
@@ -181,34 +205,41 @@ export function svelte(inlineOptions) {
|
|
|
181
205
|
}
|
|
182
206
|
return {
|
|
183
207
|
...compileData.compiled.js,
|
|
208
|
+
moduleType: 'js',
|
|
184
209
|
meta: {
|
|
185
210
|
vite: {
|
|
186
211
|
lang: compileData.lang
|
|
187
212
|
}
|
|
188
213
|
}
|
|
189
214
|
};
|
|
190
|
-
}
|
|
215
|
+
}
|
|
216
|
+
},
|
|
191
217
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
}
|
|
200
|
-
},
|
|
201
|
-
async buildEnd() {
|
|
202
|
-
await options.stats?.finishAll();
|
|
218
|
+
handleHotUpdate(ctx) {
|
|
219
|
+
if (!options.compilerOptions.hmr || !options.emitCss) {
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
const svelteRequest = requestParser(ctx.file, false, ctx.timestamp);
|
|
223
|
+
if (svelteRequest) {
|
|
224
|
+
return handleHotUpdate(compileSvelte, ctx, svelteRequest, cache, options);
|
|
203
225
|
}
|
|
204
226
|
},
|
|
205
|
-
{
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
227
|
+
async buildEnd() {
|
|
228
|
+
await options.stats?.finishAll();
|
|
229
|
+
}
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
/** @type {import('vite').Plugin} */
|
|
233
|
+
const moduleCompilePlugin = {
|
|
234
|
+
name: 'vite-plugin-svelte-module',
|
|
235
|
+
enforce: 'post',
|
|
236
|
+
async configResolved() {
|
|
237
|
+
//@ts-expect-error transform defined below but filter not in type
|
|
238
|
+
moduleCompilePlugin.transform.filter = buildModuleIdFilter(options);
|
|
239
|
+
moduleRequestParser = buildModuleIdParser(options);
|
|
240
|
+
},
|
|
241
|
+
transform: {
|
|
242
|
+
async handler(code, id, opts) {
|
|
212
243
|
const ssr = !!opts?.ssr;
|
|
213
244
|
const moduleRequest = moduleRequestParser(id, ssr);
|
|
214
245
|
if (!moduleRequest) {
|
|
@@ -226,9 +257,11 @@ export function svelte(inlineOptions) {
|
|
|
226
257
|
throw toRollupError(e, options);
|
|
227
258
|
}
|
|
228
259
|
}
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
|
|
260
|
+
}
|
|
261
|
+
};
|
|
262
|
+
|
|
263
|
+
/** @type {import('vite').Plugin[]} */
|
|
264
|
+
const plugins = [compilePlugin, moduleCompilePlugin, svelteInspector()];
|
|
232
265
|
return plugins;
|
|
233
266
|
}
|
|
234
267
|
|
package/src/preprocess.js
CHANGED
|
@@ -1,7 +1,16 @@
|
|
|
1
1
|
import process from 'node:process';
|
|
2
|
-
import
|
|
2
|
+
import * as vite from 'vite';
|
|
3
3
|
import { mapToRelative, removeLangSuffix } from './utils/sourcemaps.js';
|
|
4
|
-
|
|
4
|
+
const {
|
|
5
|
+
isCSSRequest,
|
|
6
|
+
preprocessCSS,
|
|
7
|
+
resolveConfig,
|
|
8
|
+
transformWithEsbuild,
|
|
9
|
+
//@ts-expect-error rolldown types don't exist
|
|
10
|
+
rolldownVersion,
|
|
11
|
+
//@ts-expect-error rolldown types don't exist
|
|
12
|
+
transformWithOxc
|
|
13
|
+
} = vite;
|
|
5
14
|
/**
|
|
6
15
|
* @typedef {(code: string, filename: string) => Promise<{ code: string; map?: any; deps?: Set<string> }>} CssTransform
|
|
7
16
|
*/
|
|
@@ -18,7 +27,7 @@ export function vitePreprocess(opts) {
|
|
|
18
27
|
/** @type {import('svelte/compiler').PreprocessorGroup} */
|
|
19
28
|
const preprocessor = { name: 'vite-preprocess' };
|
|
20
29
|
if (opts?.script === true) {
|
|
21
|
-
preprocessor.script = viteScript().script;
|
|
30
|
+
preprocessor.script = rolldownVersion ? viteScriptOxc().script : viteScript().script;
|
|
22
31
|
}
|
|
23
32
|
if (opts?.style !== false) {
|
|
24
33
|
const styleOpts = typeof opts?.style == 'object' ? opts?.style : undefined;
|
|
@@ -57,6 +66,37 @@ function viteScript() {
|
|
|
57
66
|
};
|
|
58
67
|
}
|
|
59
68
|
|
|
69
|
+
/**
|
|
70
|
+
* @returns {{ script: import('svelte/compiler').Preprocessor }}
|
|
71
|
+
*/
|
|
72
|
+
function viteScriptOxc() {
|
|
73
|
+
return {
|
|
74
|
+
async script({ attributes, content, filename = '' }) {
|
|
75
|
+
const lang = /** @type {string} */ (attributes.lang);
|
|
76
|
+
if (!supportedScriptLangs.includes(lang)) return;
|
|
77
|
+
const { code, map } = await transformWithOxc(content, filename, {
|
|
78
|
+
lang,
|
|
79
|
+
target: 'esnext'
|
|
80
|
+
// TODO, how to pass tsconfig compilerOptions (or not needed as config is loaded for file
|
|
81
|
+
/*tsconfigRaw: {
|
|
82
|
+
compilerOptions: {
|
|
83
|
+
// svelte typescript needs this flag to work with type imports
|
|
84
|
+
importsNotUsedAsValues: 'preserve',
|
|
85
|
+
preserveValueImports: true
|
|
86
|
+
}
|
|
87
|
+
}*/
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
mapToRelative(map, filename);
|
|
91
|
+
|
|
92
|
+
return {
|
|
93
|
+
code,
|
|
94
|
+
map
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
|
|
60
100
|
/**
|
|
61
101
|
* @param {import('vite').ResolvedConfig | import('vite').InlineConfig} config
|
|
62
102
|
* @returns {{ style: import('svelte/compiler').Preprocessor }}
|
package/src/public.d.ts
CHANGED
|
@@ -22,14 +22,14 @@ export interface PluginOptions {
|
|
|
22
22
|
*
|
|
23
23
|
* @see https://github.com/micromatch/picomatch
|
|
24
24
|
*/
|
|
25
|
-
include?: Arrayable<string>;
|
|
25
|
+
include?: Arrayable<string | RegExp>;
|
|
26
26
|
/**
|
|
27
27
|
* A `picomatch` pattern, or array of patterns, which specifies the files to be ignored by the
|
|
28
28
|
* plugin. By default, no files are ignored.
|
|
29
29
|
*
|
|
30
30
|
* @see https://github.com/micromatch/picomatch
|
|
31
31
|
*/
|
|
32
|
-
exclude?: Arrayable<string>;
|
|
32
|
+
exclude?: Arrayable<string | RegExp>;
|
|
33
33
|
/**
|
|
34
34
|
* Emit Svelte styles as virtual CSS files for Vite and other plugins to process
|
|
35
35
|
*
|
|
@@ -187,8 +187,8 @@ interface CompileModuleOptions {
|
|
|
187
187
|
* @default ['.ts','.js']
|
|
188
188
|
*/
|
|
189
189
|
extensions?: string[];
|
|
190
|
-
include?: Arrayable<string>;
|
|
191
|
-
exclude?: Arrayable<string>;
|
|
190
|
+
include?: Arrayable<string | RegExp>;
|
|
191
|
+
exclude?: Arrayable<string | RegExp>;
|
|
192
192
|
}
|
|
193
193
|
|
|
194
194
|
type Arrayable<T> = T | T[];
|
package/src/types/compile.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { Processed, CompileResult } from 'svelte/compiler';
|
|
2
2
|
import type { SvelteRequest } from './id.d.ts';
|
|
3
3
|
import type { ResolvedOptions } from './options.d.ts';
|
|
4
|
+
import type { CustomPluginOptionsVite } from 'vite';
|
|
4
5
|
|
|
5
6
|
export type CompileSvelte = (
|
|
6
7
|
svelteRequest: SvelteRequest,
|
|
@@ -12,6 +13,11 @@ export interface Code {
|
|
|
12
13
|
code: string;
|
|
13
14
|
map?: any;
|
|
14
15
|
dependencies?: any[];
|
|
16
|
+
hasGlobal?: boolean;
|
|
17
|
+
moduleType?: string; //rolldown-vite
|
|
18
|
+
meta?: {
|
|
19
|
+
vite?: CustomPluginOptionsVite;
|
|
20
|
+
};
|
|
15
21
|
}
|
|
16
22
|
|
|
17
23
|
export interface CompileData {
|
package/src/types/id.d.ts
CHANGED
|
@@ -39,6 +39,13 @@ export interface SvelteModuleRequest {
|
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
export type IdParser = (id: string, ssr: boolean, timestamp?: number) => SvelteRequest | undefined;
|
|
42
|
+
|
|
43
|
+
export type IdFilter = {
|
|
44
|
+
id: {
|
|
45
|
+
include: Array<string | RegExp>;
|
|
46
|
+
exclude: Array<string | RegExp>;
|
|
47
|
+
};
|
|
48
|
+
};
|
|
42
49
|
export type ModuleIdParser = (
|
|
43
50
|
id: string,
|
|
44
51
|
ssr: boolean,
|
package/src/utils/compile.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import * as svelte from 'svelte/compiler';
|
|
2
|
-
|
|
3
2
|
import { safeBase64Hash } from './hash.js';
|
|
4
3
|
import { log } from './log.js';
|
|
5
4
|
|
|
@@ -133,6 +132,7 @@ export function createCompileSvelte() {
|
|
|
133
132
|
let compiled;
|
|
134
133
|
try {
|
|
135
134
|
compiled = svelte.compile(finalCode, { ...finalCompileOptions, filename });
|
|
135
|
+
|
|
136
136
|
// patch output with partial accept until svelte does it
|
|
137
137
|
// TODO remove later
|
|
138
138
|
if (
|
package/src/utils/constants.js
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
import { createRequire } from 'node:module';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
const sveltePkg = createRequire(import.meta.url)('svelte/package.json');
|
|
4
|
+
|
|
5
|
+
// list of svelte runtime dependencies to optimize together with svelte itself
|
|
6
|
+
export const SVELTE_RUNTIME_DEPENDENCIES = [
|
|
7
|
+
'clsx' // avoids dev server restart after page load with npm + vite6 (see #1067)
|
|
8
|
+
].filter((dep) => !!sveltePkg.dependencies?.[dep]);
|
|
9
|
+
|
|
10
|
+
export const SVELTE_IMPORTS = Object.entries(sveltePkg.exports)
|
|
6
11
|
.map(([name, config]) => {
|
|
7
12
|
// ignore type only
|
|
8
13
|
if (typeof config === 'object' && Object.keys(config).length === 1 && config.types) {
|
|
@@ -24,3 +29,8 @@ export const FAQ_LINK_MISSING_EXPORTS_CONDITION =
|
|
|
24
29
|
export const DEFAULT_SVELTE_EXT = ['.svelte'];
|
|
25
30
|
export const DEFAULT_SVELTE_MODULE_INFIX = ['.svelte.'];
|
|
26
31
|
export const DEFAULT_SVELTE_MODULE_EXT = ['.js', '.ts'];
|
|
32
|
+
|
|
33
|
+
export const SVELTE_VIRTUAL_STYLE_SUFFIX = '?svelte&type=style&lang.css';
|
|
34
|
+
export const SVELTE_VIRTUAL_STYLE_ID_REGEX = new RegExp(
|
|
35
|
+
`${SVELTE_VIRTUAL_STYLE_SUFFIX.replace(/[?.]/g, '\\$&')}$`
|
|
36
|
+
);
|
package/src/utils/error.js
CHANGED
|
@@ -31,11 +31,13 @@ export function toRollupError(error, options) {
|
|
|
31
31
|
* convert an error thrown by svelte.compile to an esbuild PartialMessage
|
|
32
32
|
* @param {import('svelte/compiler').Warning & Error & {frame?: string}} error a svelte compiler error, which is a mix of Warning and an error
|
|
33
33
|
* @param {import('../types/options.d.ts').ResolvedOptions} options
|
|
34
|
-
* @returns {
|
|
34
|
+
* @returns {any} the converted error as esbuild PartialMessage
|
|
35
|
+
*
|
|
36
|
+
* note: typed any to avoid esbuild devDependency for a single internal type import
|
|
35
37
|
*/
|
|
36
38
|
export function toESBuildError(error, options) {
|
|
37
39
|
const { filename, frame, start, stack } = error;
|
|
38
|
-
/** @type
|
|
40
|
+
/** @type any */
|
|
39
41
|
const partialMessage = {
|
|
40
42
|
text: buildExtendedLogMessage(error)
|
|
41
43
|
};
|
package/src/utils/id.js
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { normalizePath } from 'vite';
|
|
2
2
|
import fs from 'node:fs';
|
|
3
|
-
import path from 'node:path';
|
|
4
3
|
import process from 'node:process';
|
|
5
4
|
import { log } from './log.js';
|
|
6
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
DEFAULT_SVELTE_EXT,
|
|
7
|
+
DEFAULT_SVELTE_MODULE_EXT,
|
|
8
|
+
DEFAULT_SVELTE_MODULE_INFIX
|
|
9
|
+
} from './constants.js';
|
|
10
|
+
import { arraify } from './options.js';
|
|
7
11
|
|
|
8
12
|
const VITE_FS_PREFIX = '/@fs/';
|
|
9
13
|
const IS_WINDOWS = process.platform === 'win32';
|
|
@@ -154,34 +158,34 @@ function stripRoot(normalizedFilename, normalizedRoot) {
|
|
|
154
158
|
}
|
|
155
159
|
|
|
156
160
|
/**
|
|
157
|
-
*
|
|
158
|
-
* @param {
|
|
159
|
-
* @
|
|
160
|
-
* @returns {(filename: string) => boolean}
|
|
161
|
+
*
|
|
162
|
+
* @param {string} s
|
|
163
|
+
* @returns {string}
|
|
161
164
|
*/
|
|
162
|
-
function
|
|
163
|
-
|
|
164
|
-
return (filename) => rollupFilter(filename) && extensions.some((ext) => filename.endsWith(ext));
|
|
165
|
+
function escapeRE(s) {
|
|
166
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
165
167
|
}
|
|
166
168
|
|
|
167
169
|
/**
|
|
168
|
-
* @param {import('../
|
|
169
|
-
* @
|
|
170
|
-
* @param {string[]} infixes
|
|
171
|
-
* @param {string[]} extensions
|
|
172
|
-
* @returns {(filename: string) => boolean}
|
|
170
|
+
* @param {import('../types/options.d.ts').ResolvedOptions} options
|
|
171
|
+
* @returns {import('../types/id.d.ts').IdFilter}
|
|
173
172
|
*/
|
|
174
|
-
function
|
|
175
|
-
const
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
173
|
+
export function buildIdFilter(options) {
|
|
174
|
+
const { include = [], exclude = [], extensions = DEFAULT_SVELTE_EXT } = options;
|
|
175
|
+
// this regex combines configured extensions and looks for them at the end of the string or directly before first ? or #
|
|
176
|
+
const extensionsRE = new RegExp(
|
|
177
|
+
`^[^?#]+\\.(?:${extensions
|
|
178
|
+
.map((e) => (e.startsWith('.') ? e.slice(1) : e))
|
|
179
|
+
.map(escapeRE)
|
|
180
|
+
.join('|')})(?:[?#]|$)`
|
|
181
|
+
);
|
|
182
|
+
const filter = {
|
|
183
|
+
id: {
|
|
184
|
+
include: [extensionsRE, .../**@type {Array<string|RegExp>}*/ arraify(include)],
|
|
185
|
+
exclude: /**@type {Array<string|RegExp>}*/ arraify(exclude)
|
|
186
|
+
}
|
|
184
187
|
};
|
|
188
|
+
return filter;
|
|
185
189
|
}
|
|
186
190
|
|
|
187
191
|
/**
|
|
@@ -189,36 +193,50 @@ function buildModuleFilter(include, exclude, infixes, extensions) {
|
|
|
189
193
|
* @returns {import('../types/id.d.ts').IdParser}
|
|
190
194
|
*/
|
|
191
195
|
export function buildIdParser(options) {
|
|
192
|
-
const
|
|
193
|
-
const normalizedRoot = normalizePath(root);
|
|
194
|
-
const filter = buildFilter(include, exclude, extensions ?? []);
|
|
196
|
+
const normalizedRoot = normalizePath(options.root);
|
|
195
197
|
return (id, ssr, timestamp = Date.now()) => {
|
|
196
198
|
const { filename, rawQuery } = splitId(id);
|
|
197
|
-
|
|
198
|
-
return parseToSvelteRequest(id, filename, rawQuery, normalizedRoot, timestamp, ssr);
|
|
199
|
-
}
|
|
199
|
+
return parseToSvelteRequest(id, filename, rawQuery, normalizedRoot, timestamp, ssr);
|
|
200
200
|
};
|
|
201
201
|
}
|
|
202
202
|
|
|
203
203
|
/**
|
|
204
204
|
* @param {import('../types/options.d.ts').ResolvedOptions} options
|
|
205
|
-
* @returns {import('../types/id.d.ts').
|
|
205
|
+
* @returns {import('../types/id.d.ts').IdFilter}
|
|
206
206
|
*/
|
|
207
|
-
export function
|
|
207
|
+
export function buildModuleIdFilter(options) {
|
|
208
208
|
const {
|
|
209
|
-
include,
|
|
210
|
-
exclude,
|
|
211
209
|
infixes = DEFAULT_SVELTE_MODULE_INFIX,
|
|
210
|
+
include = [],
|
|
211
|
+
exclude = [],
|
|
212
212
|
extensions = DEFAULT_SVELTE_MODULE_EXT
|
|
213
|
-
} = options
|
|
213
|
+
} = options.experimental?.compileModule ?? {};
|
|
214
|
+
// this regex combines configured infixes and extensions
|
|
215
|
+
// and looks for them at the end of the string or directly before first ? or #
|
|
216
|
+
const infixWithExtRE = new RegExp(
|
|
217
|
+
`^[^?#]+(?:${infixes.map(escapeRE).join('|')})(?:[^.\\\\/]+\\.)*(?:${extensions
|
|
218
|
+
.map((e) => (e.startsWith('.') ? e.slice(1) : e))
|
|
219
|
+
.map(escapeRE)
|
|
220
|
+
.join('|')})(?:[?#]|$)`
|
|
221
|
+
);
|
|
222
|
+
return {
|
|
223
|
+
id: {
|
|
224
|
+
include: [infixWithExtRE, .../**@type {Array<string|RegExp>}*/ arraify(include)],
|
|
225
|
+
exclude: /**@type {Array<string|RegExp>}*/ arraify(exclude)
|
|
226
|
+
}
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* @param {import('../types/options.d.ts').ResolvedOptions} options
|
|
232
|
+
* @returns {import('../types/id.d.ts').ModuleIdParser}
|
|
233
|
+
*/
|
|
234
|
+
export function buildModuleIdParser(options) {
|
|
214
235
|
const root = options.root;
|
|
215
236
|
const normalizedRoot = normalizePath(root);
|
|
216
|
-
const filter = buildModuleFilter(include, exclude, infixes, extensions);
|
|
217
237
|
return (id, ssr, timestamp = Date.now()) => {
|
|
218
238
|
const { filename, rawQuery } = splitId(id);
|
|
219
|
-
|
|
220
|
-
return parseToSvelteModuleRequest(id, filename, rawQuery, normalizedRoot, timestamp, ssr);
|
|
221
|
-
}
|
|
239
|
+
return parseToSvelteModuleRequest(id, filename, rawQuery, normalizedRoot, timestamp, ssr);
|
|
222
240
|
};
|
|
223
241
|
}
|
|
224
242
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { readFileSync } from 'node:fs';
|
|
2
2
|
import * as svelte from 'svelte/compiler';
|
|
3
3
|
import { log } from './log.js';
|
|
4
|
-
import { toESBuildError } from './error.js';
|
|
4
|
+
import { toESBuildError, toRollupError } from './error.js';
|
|
5
5
|
import { safeBase64Hash } from './hash.js';
|
|
6
6
|
import { normalize } from './id.js';
|
|
7
7
|
|
|
@@ -9,42 +9,94 @@ import { normalize } from './id.js';
|
|
|
9
9
|
* @typedef {NonNullable<import('vite').DepOptimizationOptions['esbuildOptions']>} EsbuildOptions
|
|
10
10
|
* @typedef {NonNullable<EsbuildOptions['plugins']>[number]} EsbuildPlugin
|
|
11
11
|
*/
|
|
12
|
+
/**
|
|
13
|
+
* @typedef {NonNullable<import('vite').Rollup.Plugin>} RollupPlugin
|
|
14
|
+
*/
|
|
12
15
|
|
|
13
|
-
export const
|
|
14
|
-
export const
|
|
16
|
+
export const optimizeSveltePluginName = 'vite-plugin-svelte:optimize';
|
|
17
|
+
export const optimizeSvelteModulePluginName = 'vite-plugin-svelte-module:optimize';
|
|
15
18
|
|
|
16
19
|
/**
|
|
20
|
+
* @param {EsbuildPlugin} plugin
|
|
17
21
|
* @param {import('../types/options.d.ts').ResolvedOptions} options
|
|
18
|
-
* @returns {EsbuildPlugin}
|
|
19
22
|
*/
|
|
20
|
-
export function
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
23
|
+
export function patchESBuildOptimizerPlugin(plugin, options) {
|
|
24
|
+
const components = plugin.name === optimizeSveltePluginName;
|
|
25
|
+
const compileFn = components ? compileSvelte : compileSvelteModule;
|
|
26
|
+
const statsName = components ? 'prebundle library components' : 'prebundle library modules';
|
|
27
|
+
const filter = components ? /\.svelte(?:\?.*)?$/ : /\.svelte\.[jt]s(?:\?.*)?$/;
|
|
28
|
+
plugin.setup = (build) => {
|
|
29
|
+
if (build.initialOptions.plugins?.some((v) => v.name === 'vite:dep-scan')) return;
|
|
27
30
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
logResult: (c) => c.stats.length > 1
|
|
34
|
-
});
|
|
31
|
+
/** @type {import('../types/vite-plugin-svelte-stats.d.ts').StatCollection | undefined} */
|
|
32
|
+
let statsCollection;
|
|
33
|
+
build.onStart(() => {
|
|
34
|
+
statsCollection = options.stats?.startCollection(statsName, {
|
|
35
|
+
logResult: (c) => c.stats.length > 1
|
|
35
36
|
});
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
37
|
+
});
|
|
38
|
+
build.onLoad({ filter }, async ({ path: filename }) => {
|
|
39
|
+
const code = readFileSync(filename, 'utf8');
|
|
40
|
+
try {
|
|
41
|
+
const result = await compileFn(options, { filename, code }, statsCollection);
|
|
42
|
+
const contents = result.map
|
|
43
|
+
? result.code + '//# sourceMappingURL=' + result.map.toUrl()
|
|
44
|
+
: result.code;
|
|
45
|
+
return { contents };
|
|
46
|
+
} catch (e) {
|
|
47
|
+
return { errors: [toESBuildError(e, options)] };
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
build.onEnd(() => {
|
|
51
|
+
statsCollection?.finish();
|
|
52
|
+
});
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* @param {RollupPlugin} plugin
|
|
58
|
+
* @param {import('../types/options.d.ts').ResolvedOptions} options
|
|
59
|
+
*/
|
|
60
|
+
export function patchRolldownOptimizerPlugin(plugin, options) {
|
|
61
|
+
const components = plugin.name === optimizeSveltePluginName;
|
|
62
|
+
const compileFn = components ? compileSvelte : compileSvelteModule;
|
|
63
|
+
const statsName = components ? 'prebundle library components' : 'prebundle library modules';
|
|
64
|
+
const includeRe = components ? /^[^?#]+\.svelte(?:[?#]|$)/ : /^[^?#]+\.svelte\.[jt]s(?:[?#]|$)/;
|
|
65
|
+
/** @type {import('../types/vite-plugin-svelte-stats.d.ts').StatCollection | undefined} */
|
|
66
|
+
let statsCollection;
|
|
67
|
+
|
|
68
|
+
plugin.options = (opts) => {
|
|
69
|
+
// @ts-expect-error plugins is an array here
|
|
70
|
+
const isScanner = opts.plugins.some(
|
|
71
|
+
(/** @type {{ name: string; }} */ p) => p.name === 'vite:dep-scan:resolve'
|
|
72
|
+
);
|
|
73
|
+
if (isScanner) {
|
|
74
|
+
delete plugin.buildStart;
|
|
75
|
+
delete plugin.transform;
|
|
76
|
+
delete plugin.buildEnd;
|
|
77
|
+
} else {
|
|
78
|
+
plugin.transform = {
|
|
79
|
+
filter: { id: includeRe },
|
|
80
|
+
/**
|
|
81
|
+
* @param {string} code
|
|
82
|
+
* @param {string} filename
|
|
83
|
+
*/
|
|
84
|
+
async handler(code, filename) {
|
|
85
|
+
try {
|
|
86
|
+
return await compileFn(options, { filename, code }, statsCollection);
|
|
87
|
+
} catch (e) {
|
|
88
|
+
throw toRollupError(e, options);
|
|
89
|
+
}
|
|
43
90
|
}
|
|
44
|
-
}
|
|
45
|
-
|
|
91
|
+
};
|
|
92
|
+
plugin.buildStart = () => {
|
|
93
|
+
statsCollection = options.stats?.startCollection(statsName, {
|
|
94
|
+
logResult: (c) => c.stats.length > 1
|
|
95
|
+
});
|
|
96
|
+
};
|
|
97
|
+
plugin.buildEnd = () => {
|
|
46
98
|
statsCollection?.finish();
|
|
47
|
-
}
|
|
99
|
+
};
|
|
48
100
|
}
|
|
49
101
|
};
|
|
50
102
|
}
|
|
@@ -53,7 +105,7 @@ export function esbuildSveltePlugin(options) {
|
|
|
53
105
|
* @param {import('../types/options.d.ts').ResolvedOptions} options
|
|
54
106
|
* @param {{ filename: string, code: string }} input
|
|
55
107
|
* @param {import('../types/vite-plugin-svelte-stats.d.ts').StatCollection} [statsCollection]
|
|
56
|
-
* @returns {Promise<
|
|
108
|
+
* @returns {Promise<import('../types/compile.d.ts').Code>}
|
|
57
109
|
*/
|
|
58
110
|
async function compileSvelte(options, { filename, code }, statsCollection) {
|
|
59
111
|
let css = options.compilerOptions.css;
|
|
@@ -114,44 +166,9 @@ async function compileSvelte(options, { filename, code }, statsCollection) {
|
|
|
114
166
|
if (endStat) {
|
|
115
167
|
endStat();
|
|
116
168
|
}
|
|
117
|
-
return compiled.js.map
|
|
118
|
-
? compiled.js.code + '//# sourceMappingURL=' + compiled.js.map.toUrl()
|
|
119
|
-
: compiled.js.code;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
/**
|
|
123
|
-
* @param {import('../types/options.d.ts').ResolvedOptions} options
|
|
124
|
-
* @returns {EsbuildPlugin}
|
|
125
|
-
*/
|
|
126
|
-
export function esbuildSvelteModulePlugin(options) {
|
|
127
169
|
return {
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
// Skip in scanning phase as Vite already handles scanning Svelte files.
|
|
131
|
-
// Otherwise this would heavily slow down the scanning phase.
|
|
132
|
-
if (build.initialOptions.plugins?.some((v) => v.name === 'vite:dep-scan')) return;
|
|
133
|
-
|
|
134
|
-
const filter = /\.svelte\.[jt]s(?:\?.*)?$/;
|
|
135
|
-
/** @type {import('../types/vite-plugin-svelte-stats.d.ts').StatCollection | undefined} */
|
|
136
|
-
let statsCollection;
|
|
137
|
-
build.onStart(() => {
|
|
138
|
-
statsCollection = options.stats?.startCollection('prebundle library modules', {
|
|
139
|
-
logResult: (c) => c.stats.length > 1
|
|
140
|
-
});
|
|
141
|
-
});
|
|
142
|
-
build.onLoad({ filter }, async ({ path: filename }) => {
|
|
143
|
-
const code = readFileSync(filename, 'utf8');
|
|
144
|
-
try {
|
|
145
|
-
const contents = await compileSvelteModule(options, { filename, code }, statsCollection);
|
|
146
|
-
return { contents };
|
|
147
|
-
} catch (e) {
|
|
148
|
-
return { errors: [toESBuildError(e, options)] };
|
|
149
|
-
}
|
|
150
|
-
});
|
|
151
|
-
build.onEnd(() => {
|
|
152
|
-
statsCollection?.finish();
|
|
153
|
-
});
|
|
154
|
-
}
|
|
170
|
+
...compiled.js,
|
|
171
|
+
moduleType: 'js'
|
|
155
172
|
};
|
|
156
173
|
}
|
|
157
174
|
|
|
@@ -159,7 +176,7 @@ export function esbuildSvelteModulePlugin(options) {
|
|
|
159
176
|
* @param {import('../types/options.d.ts').ResolvedOptions} options
|
|
160
177
|
* @param {{ filename: string; code: string }} input
|
|
161
178
|
* @param {import('../types/vite-plugin-svelte-stats.d.ts').StatCollection} [statsCollection]
|
|
162
|
-
* @returns {Promise<
|
|
179
|
+
* @returns {Promise<import('../types/compile.d.ts').Code>}
|
|
163
180
|
*/
|
|
164
181
|
async function compileSvelteModule(options, { filename, code }, statsCollection) {
|
|
165
182
|
const endStat = statsCollection?.start(filename);
|
|
@@ -171,7 +188,8 @@ async function compileSvelteModule(options, { filename, code }, statsCollection)
|
|
|
171
188
|
if (endStat) {
|
|
172
189
|
endStat();
|
|
173
190
|
}
|
|
174
|
-
return
|
|
175
|
-
|
|
176
|
-
:
|
|
191
|
+
return {
|
|
192
|
+
...compiled.js,
|
|
193
|
+
moduleType: 'js'
|
|
194
|
+
};
|
|
177
195
|
}
|
package/src/utils/options.js
CHANGED
|
@@ -1,27 +1,31 @@
|
|
|
1
1
|
import process from 'node:process';
|
|
2
|
-
import
|
|
2
|
+
import * as vite from 'vite';
|
|
3
|
+
const {
|
|
3
4
|
defaultClientMainFields,
|
|
4
5
|
defaultServerMainFields,
|
|
5
6
|
defaultClientConditions,
|
|
6
7
|
defaultServerConditions,
|
|
7
|
-
normalizePath
|
|
8
|
-
|
|
8
|
+
normalizePath,
|
|
9
|
+
//@ts-expect-error rolldownVersion not in type
|
|
10
|
+
rolldownVersion
|
|
11
|
+
} = vite;
|
|
9
12
|
import { isDebugNamespaceEnabled, log } from './log.js';
|
|
10
13
|
import { loadSvelteConfig } from './load-svelte-config.js';
|
|
11
14
|
import {
|
|
12
15
|
DEFAULT_SVELTE_EXT,
|
|
13
16
|
FAQ_LINK_MISSING_EXPORTS_CONDITION,
|
|
14
17
|
SVELTE_EXPORT_CONDITIONS,
|
|
15
|
-
SVELTE_IMPORTS
|
|
18
|
+
SVELTE_IMPORTS,
|
|
19
|
+
SVELTE_RUNTIME_DEPENDENCIES
|
|
16
20
|
} from './constants.js';
|
|
17
21
|
|
|
18
22
|
import path from 'node:path';
|
|
19
23
|
import {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
} from './
|
|
24
|
+
optimizeSvelteModulePluginName,
|
|
25
|
+
optimizeSveltePluginName,
|
|
26
|
+
patchESBuildOptimizerPlugin,
|
|
27
|
+
patchRolldownOptimizerPlugin
|
|
28
|
+
} from './optimizer-plugins.js';
|
|
25
29
|
import { addExtraPreprocessors } from './preprocess.js';
|
|
26
30
|
import deepmerge from 'deepmerge';
|
|
27
31
|
import {
|
|
@@ -385,17 +389,39 @@ export async function buildExtraViteConfig(options, config) {
|
|
|
385
389
|
extraViteConfig.optimizeDeps = {
|
|
386
390
|
...extraViteConfig.optimizeDeps,
|
|
387
391
|
// Experimental Vite API to allow these extensions to be scanned and prebundled
|
|
388
|
-
extensions: options.extensions ?? ['.svelte']
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
392
|
+
extensions: options.extensions ?? ['.svelte']
|
|
393
|
+
};
|
|
394
|
+
// Add optimizer plugins to prebundle Svelte files.
|
|
395
|
+
// Currently a placeholder as more information is needed after Vite config is resolved,
|
|
396
|
+
// the added plugins are patched in `patchResolvedViteConfig()`
|
|
397
|
+
if (rolldownVersion) {
|
|
398
|
+
/**
|
|
399
|
+
*
|
|
400
|
+
* @param {string} name
|
|
401
|
+
* @returns {import('vite').Rollup.Plugin}
|
|
402
|
+
*/
|
|
403
|
+
const placeholderRolldownOptimizerPlugin = (name) => ({
|
|
404
|
+
name,
|
|
405
|
+
options() {},
|
|
406
|
+
buildStart() {},
|
|
407
|
+
buildEnd() {},
|
|
408
|
+
transform: { filter: { id: /^$/ }, handler() {} }
|
|
409
|
+
});
|
|
410
|
+
//@ts-expect-error rolldown types not finished
|
|
411
|
+
extraViteConfig.optimizeDeps.rollupOptions = {
|
|
393
412
|
plugins: [
|
|
394
|
-
|
|
395
|
-
|
|
413
|
+
placeholderRolldownOptimizerPlugin(optimizeSveltePluginName),
|
|
414
|
+
placeholderRolldownOptimizerPlugin(optimizeSvelteModulePluginName)
|
|
396
415
|
]
|
|
397
|
-
}
|
|
398
|
-
}
|
|
416
|
+
};
|
|
417
|
+
} else {
|
|
418
|
+
extraViteConfig.optimizeDeps.esbuildOptions = {
|
|
419
|
+
plugins: [
|
|
420
|
+
{ name: optimizeSveltePluginName, setup: () => {} },
|
|
421
|
+
{ name: optimizeSvelteModulePluginName, setup: () => {} }
|
|
422
|
+
]
|
|
423
|
+
};
|
|
424
|
+
}
|
|
399
425
|
}
|
|
400
426
|
|
|
401
427
|
// enable hmrPartialAccept if not explicitly disabled
|
|
@@ -550,8 +576,9 @@ function buildExtraConfigForSvelte(config) {
|
|
|
550
576
|
const svelteImportsToInclude = SVELTE_IMPORTS.filter(
|
|
551
577
|
(si) => !(si.endsWith('/server') || si.includes('/server/'))
|
|
552
578
|
);
|
|
579
|
+
svelteImportsToInclude.push(...SVELTE_RUNTIME_DEPENDENCIES.map((dep) => `svelte > ${dep}`));
|
|
553
580
|
log.debug(
|
|
554
|
-
`adding bare svelte packages to optimizeDeps.include: ${svelteImportsToInclude.join(', ')} `,
|
|
581
|
+
`adding bare svelte packages and runtime dependencies to optimizeDeps.include: ${svelteImportsToInclude.join(', ')} `,
|
|
555
582
|
undefined,
|
|
556
583
|
'config'
|
|
557
584
|
);
|
|
@@ -592,19 +619,23 @@ export function patchResolvedViteConfig(viteConfig, options) {
|
|
|
592
619
|
}
|
|
593
620
|
}
|
|
594
621
|
}
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
622
|
+
if (rolldownVersion) {
|
|
623
|
+
const plugins =
|
|
624
|
+
// @ts-expect-error not typed
|
|
625
|
+
viteConfig.optimizeDeps.rollupOptions?.plugins?.filter((p) =>
|
|
626
|
+
[optimizeSveltePluginName, optimizeSvelteModulePluginName].includes(p.name)
|
|
627
|
+
) ?? [];
|
|
628
|
+
for (const plugin of plugins) {
|
|
629
|
+
patchRolldownOptimizerPlugin(plugin, options);
|
|
630
|
+
}
|
|
631
|
+
} else {
|
|
632
|
+
const plugins =
|
|
633
|
+
viteConfig.optimizeDeps.esbuildOptions?.plugins?.filter((p) =>
|
|
634
|
+
[optimizeSveltePluginName, optimizeSvelteModulePluginName].includes(p.name)
|
|
635
|
+
) ?? [];
|
|
636
|
+
for (const plugin of plugins) {
|
|
637
|
+
patchESBuildOptimizerPlugin(plugin, options);
|
|
638
|
+
}
|
|
608
639
|
}
|
|
609
640
|
}
|
|
610
641
|
|
|
@@ -645,9 +676,9 @@ export function ensureConfigEnvironmentConditions(name, config, opts) {
|
|
|
645
676
|
|
|
646
677
|
/**
|
|
647
678
|
* @template T
|
|
648
|
-
* @param {T | T[]} value
|
|
679
|
+
* @param {T | T[] | null | undefined } value
|
|
649
680
|
* @returns {T[]}
|
|
650
681
|
*/
|
|
651
|
-
function arraify(value) {
|
|
652
|
-
return Array.isArray(value) ? value : [value];
|
|
682
|
+
export function arraify(value) {
|
|
683
|
+
return value == null ? [] : Array.isArray(value) ? value : [value];
|
|
653
684
|
}
|
package/types/index.d.ts
CHANGED
|
@@ -22,14 +22,14 @@ declare module '@sveltejs/vite-plugin-svelte' {
|
|
|
22
22
|
*
|
|
23
23
|
* @see https://github.com/micromatch/picomatch
|
|
24
24
|
*/
|
|
25
|
-
include?: Arrayable<string>;
|
|
25
|
+
include?: Arrayable<string | RegExp>;
|
|
26
26
|
/**
|
|
27
27
|
* A `picomatch` pattern, or array of patterns, which specifies the files to be ignored by the
|
|
28
28
|
* plugin. By default, no files are ignored.
|
|
29
29
|
*
|
|
30
30
|
* @see https://github.com/micromatch/picomatch
|
|
31
31
|
*/
|
|
32
|
-
exclude?: Arrayable<string>;
|
|
32
|
+
exclude?: Arrayable<string | RegExp>;
|
|
33
33
|
/**
|
|
34
34
|
* Emit Svelte styles as virtual CSS files for Vite and other plugins to process
|
|
35
35
|
*
|
|
@@ -187,8 +187,8 @@ declare module '@sveltejs/vite-plugin-svelte' {
|
|
|
187
187
|
* @default ['.ts','.js']
|
|
188
188
|
*/
|
|
189
189
|
extensions?: string[];
|
|
190
|
-
include?: Arrayable<string>;
|
|
191
|
-
exclude?: Arrayable<string>;
|
|
190
|
+
include?: Arrayable<string | RegExp>;
|
|
191
|
+
exclude?: Arrayable<string | RegExp>;
|
|
192
192
|
}
|
|
193
193
|
|
|
194
194
|
type Arrayable<T> = T | T[];
|
package/types/index.d.ts.map
CHANGED
|
@@ -3,8 +3,12 @@
|
|
|
3
3
|
"file": "index.d.ts",
|
|
4
4
|
"names": [
|
|
5
5
|
"Options",
|
|
6
|
+
"PluginOptionsInline",
|
|
6
7
|
"PluginOptions",
|
|
7
8
|
"SvelteConfig",
|
|
9
|
+
"ExperimentalOptions",
|
|
10
|
+
"CompileModuleOptions",
|
|
11
|
+
"Arrayable",
|
|
8
12
|
"VitePreprocessOptions",
|
|
9
13
|
"svelte",
|
|
10
14
|
"vitePreprocess",
|
|
@@ -22,6 +26,6 @@
|
|
|
22
26
|
null,
|
|
23
27
|
null
|
|
24
28
|
],
|
|
25
|
-
"mappings": ";;;;aAIYA,OAAOA
|
|
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",
|
|
26
30
|
"ignoreList": []
|
|
27
31
|
}
|