@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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sveltejs/vite-plugin-svelte",
3
- "version": "6.0.0-next.0",
3
+ "version": "6.0.0-next.2",
4
4
  "license": "MIT",
5
5
  "author": "dominikg",
6
6
  "files": [
@@ -34,22 +34,22 @@
34
34
  },
35
35
  "homepage": "https://github.com/sveltejs/vite-plugin-svelte#readme",
36
36
  "dependencies": {
37
+ "@sveltejs/vite-plugin-svelte-inspector": "^5.0.0-next.0",
37
38
  "debug": "^4.4.1",
38
39
  "deepmerge": "^4.3.1",
39
40
  "kleur": "^4.1.5",
40
41
  "magic-string": "^0.30.17",
41
- "vitefu": "^1.0.6",
42
- "@sveltejs/vite-plugin-svelte-inspector": "^5.0.0-next.0"
42
+ "vitefu": "^1.0.7"
43
43
  },
44
44
  "peerDependencies": {
45
45
  "svelte": "^5.0.0",
46
- "vite": "^6.3.0 || ^7.0.0-beta.0"
46
+ "vite": "^6.3.0 || ^7.0.0"
47
47
  },
48
48
  "devDependencies": {
49
49
  "@types/debug": "^4.1.12",
50
- "sass": "^1.89.1",
51
- "svelte": "^5.33.18",
52
- "vite": "^7.0.0-beta.0"
50
+ "sass": "^1.89.2",
51
+ "svelte": "^5.34.9",
52
+ "vite": "^7.0.0"
53
53
  },
54
54
  "scripts": {
55
55
  "check:publint": "publint --strict",
package/src/index.js CHANGED
@@ -1,36 +1,19 @@
1
- import fs from 'node:fs';
2
1
  import process from 'node:process';
2
+ import { log } from './utils/log.js';
3
+ import { configure } from './plugins/configure.js';
4
+ import { preprocess } from './plugins/preprocess.js';
5
+ import { compile } from './plugins/compile.js';
6
+ import { loadCompiledCss } from './plugins/load-compiled-css.js';
7
+ import { setupOptimizer } from './plugins/setup-optimizer.js';
8
+ import { compileModule } from './plugins/compile-module.js';
3
9
  import { svelteInspector } from '@sveltejs/vite-plugin-svelte-inspector';
4
- import { handleHotUpdate } from './handle-hot-update.js';
5
- import { log, logCompilerWarnings } from './utils/log.js';
6
- import { createCompileSvelte } from './utils/compile.js';
7
- import {
8
- buildIdFilter,
9
- buildIdParser,
10
- buildModuleIdFilter,
11
- buildModuleIdParser
12
- } from './utils/id.js';
13
- import {
14
- buildExtraViteConfig,
15
- validateInlineOptions,
16
- resolveOptions,
17
- patchResolvedViteConfig,
18
- preResolveOptions,
19
- ensureConfigEnvironmentMainFields,
20
- ensureConfigEnvironmentConditions
21
- } from './utils/options.js';
22
- import { ensureWatchedFile, setupWatchers } from './utils/watch.js';
23
- import { toRollupError } from './utils/error.js';
24
- import { saveSvelteMetadata } from './utils/optimizer.js';
25
- import { VitePluginSvelteCache } from './utils/vite-plugin-svelte-cache.js';
26
- import { loadRaw } from './utils/load-raw.js';
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;
10
+ import { loadCustom } from './plugins/load-custom.js';
11
+ import { hotUpdate } from './plugins/hot-update.js';
32
12
 
33
13
  /**
14
+ * returns a list of plugins to handle svelte files
15
+ * plugins are named `vite-plugin-svelte:<task>`
16
+ *
34
17
  * @param {Partial<import('./public.d.ts').Options>} [inlineOptions]
35
18
  * @returns {import('vite').Plugin[]}
36
19
  */
@@ -38,231 +21,21 @@ export function svelte(inlineOptions) {
38
21
  if (process.env.DEBUG != null) {
39
22
  log.setLevel('debug');
40
23
  }
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
-
47
- validateInlineOptions(inlineOptions);
48
- const cache = new VitePluginSvelteCache();
49
- // updated in configResolved hook
50
- /** @type {import('./types/id.d.ts').IdParser} */
51
- let requestParser;
52
- /** @type {import('./types/id.d.ts').ModuleIdParser} */
53
- let moduleRequestParser;
54
- /** @type {import('./types/options.d.ts').ResolvedOptions} */
55
- let options;
56
- /** @type {import('vite').ResolvedConfig} */
57
- let viteConfig;
58
- /** @type {import('./types/compile.d.ts').CompileSvelte} */
59
- let compileSvelte;
60
-
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
- },
120
-
121
- configureServer(server) {
122
- options.server = server;
123
- setupWatchers(options, cache, requestParser);
124
- },
125
-
126
- load: {
127
- async handler(id, opts) {
128
- const ssr = !!opts?.ssr;
129
- const svelteRequest = requestParser(id, !!ssr);
130
- if (svelteRequest) {
131
- const { filename, query, raw } = svelteRequest;
132
- if (raw) {
133
- const code = await loadRaw(svelteRequest, compileSvelte, options);
134
- // prevent vite from injecting sourcemaps in the results.
135
- return {
136
- code,
137
- map: {
138
- mappings: ''
139
- }
140
- };
141
- } else {
142
- if (query.svelte && query.type === 'style') {
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
-
154
- return css;
155
- }
156
- }
157
- // prevent vite asset plugin from loading files as url that should be compiled in transform
158
- if (viteConfig.assetsInclude(filename)) {
159
- log.debug(`load returns raw content for ${filename}`, undefined, 'load');
160
- return fs.readFileSync(filename, 'utf-8');
161
- }
162
- }
163
- }
164
- }
165
- },
166
-
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
- },
178
-
179
- transform: {
180
- async handler(code, id, opts) {
181
- const ssr = !!opts?.ssr;
182
- const svelteRequest = requestParser(id, ssr);
183
- if (!svelteRequest || svelteRequest.query.type === 'style' || svelteRequest.raw) {
184
- return;
185
- }
186
- let compileData;
187
- try {
188
- compileData = await compileSvelte(svelteRequest, code, options);
189
- } catch (e) {
190
- cache.setError(svelteRequest, e);
191
- throw toRollupError(e, options);
192
- }
193
- logCompilerWarnings(svelteRequest, compileData.compiled.warnings, options);
194
- cache.update(compileData);
195
- if (compileData.dependencies?.length) {
196
- if (options.server) {
197
- for (const dep of compileData.dependencies) {
198
- ensureWatchedFile(options.server.watcher, dep, options.root);
199
- }
200
- } else if (options.isBuild && viteConfig.build.watch) {
201
- for (const dep of compileData.dependencies) {
202
- this.addWatchFile(dep);
203
- }
204
- }
205
- }
206
- return {
207
- ...compileData.compiled.js,
208
- moduleType: 'js',
209
- meta: {
210
- vite: {
211
- lang: compileData.lang
212
- }
213
- }
214
- };
215
- }
216
- },
217
-
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);
225
- }
226
- },
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) {
243
- const ssr = !!opts?.ssr;
244
- const moduleRequest = moduleRequestParser(id, ssr);
245
- if (!moduleRequest) {
246
- return;
247
- }
248
- try {
249
- const compileResult = svelteCompiler.compileModule(code, {
250
- dev: !viteConfig.isProduction,
251
- generate: ssr ? 'server' : 'client',
252
- filename: moduleRequest.filename
253
- });
254
- logCompilerWarnings(moduleRequest, compileResult.warnings, options);
255
- return compileResult.js;
256
- } catch (e) {
257
- throw toRollupError(e, options);
258
- }
259
- }
260
- }
261
- };
262
-
263
- /** @type {import('vite').Plugin[]} */
264
- const plugins = [compilePlugin, moduleCompilePlugin, svelteInspector()];
265
- return plugins;
24
+ /** @type {import('./types/plugin-api.js').PluginAPI} */
25
+ // @ts-expect-error initialize empty to guard against early use
26
+ const api = {}; // initialized by configure plugin, used in others
27
+ return [
28
+ { name: 'vite-plugin-svelte' }, // marker for detection logic in other plugins that expect this name
29
+ configure(api, inlineOptions),
30
+ setupOptimizer(api),
31
+ loadCompiledCss(api),
32
+ loadCustom(api),
33
+ preprocess(api),
34
+ compile(api),
35
+ compileModule(api),
36
+ hotUpdate(api),
37
+ svelteInspector()
38
+ ];
266
39
  }
267
40
 
268
41
  export { vitePreprocess } from './preprocess.js';
@@ -0,0 +1,51 @@
1
+ import { buildModuleIdFilter, buildModuleIdParser } from '../utils/id.js';
2
+ import * as svelteCompiler from 'svelte/compiler';
3
+ import { logCompilerWarnings } from '../utils/log.js';
4
+ import { toRollupError } from '../utils/error.js';
5
+
6
+ /**
7
+ * @param {import('../types/plugin-api.d.ts').PluginAPI} api
8
+ * @returns {import('vite').Plugin}
9
+ */
10
+ export function compileModule(api) {
11
+ /**
12
+ * @type {import("../types/options.js").ResolvedOptions}
13
+ */
14
+ let options;
15
+ /**
16
+ * @type {import("../types/id.js").ModuleIdParser}
17
+ */
18
+ let idParser;
19
+ /** @type {import('vite').Plugin} */
20
+ const plugin = {
21
+ name: 'vite-plugin-svelte:compile-module',
22
+ enforce: 'post',
23
+ async configResolved() {
24
+ options = api.options;
25
+ //@ts-expect-error transform defined below but filter not in type
26
+ plugin.transform.filter = buildModuleIdFilter(options);
27
+ idParser = buildModuleIdParser(options);
28
+ },
29
+ transform: {
30
+ async handler(code, id) {
31
+ const ssr = this.environment.config.consumer === 'server';
32
+ const moduleRequest = idParser(id, ssr);
33
+ if (!moduleRequest) {
34
+ return;
35
+ }
36
+ try {
37
+ const compileResult = svelteCompiler.compileModule(code, {
38
+ dev: !this.environment.config.isProduction,
39
+ generate: ssr ? 'server' : 'client',
40
+ filename: moduleRequest.filename
41
+ });
42
+ logCompilerWarnings(moduleRequest, compileResult.warnings, options);
43
+ return compileResult.js;
44
+ } catch (e) {
45
+ throw toRollupError(e, options);
46
+ }
47
+ }
48
+ }
49
+ };
50
+ return plugin;
51
+ }
@@ -0,0 +1,73 @@
1
+ import { toRollupError } from '../utils/error.js';
2
+ import { logCompilerWarnings } from '../utils/log.js';
3
+ import { ensureWatchedFile } from '../utils/watch.js';
4
+
5
+ /**
6
+ * @param {import('../types/plugin-api.d.ts').PluginAPI} api
7
+ * @returns {import('vite').Plugin}
8
+ */
9
+ export function compile(api) {
10
+ /**
11
+ * @type {import("../types/options.js").ResolvedOptions}
12
+ */
13
+ let options;
14
+
15
+ /**
16
+ * @type {import("../types/compile.d.ts").CompileSvelte}
17
+ */
18
+ let compileSvelte;
19
+ /** @type {import('vite').Plugin} */
20
+ const plugin = {
21
+ name: 'vite-plugin-svelte:compile',
22
+ configResolved() {
23
+ //@ts-expect-error defined below but filter not in type
24
+ plugin.transform.filter = api.idFilter;
25
+ options = api.options;
26
+ compileSvelte = api.compileSvelte;
27
+ },
28
+ transform: {
29
+ async handler(code, id) {
30
+ const ssr = this.environment.config.consumer === 'server';
31
+ const svelteRequest = api.idParser(id, ssr);
32
+ if (!svelteRequest || svelteRequest.raw) {
33
+ return;
34
+ }
35
+ const cache = api.getEnvironmentCache(this);
36
+ let compileData;
37
+ try {
38
+ const svelteMeta = this.getModuleInfo(id)?.meta?.svelte;
39
+ compileData = await compileSvelte(svelteRequest, code, options, svelteMeta?.preprocessed);
40
+ } catch (e) {
41
+ cache.setError(svelteRequest, e);
42
+ throw toRollupError(e, options);
43
+ }
44
+ if (compileData.compiled?.warnings) {
45
+ logCompilerWarnings(svelteRequest, compileData.compiled.warnings, options);
46
+ }
47
+
48
+ cache.update(compileData);
49
+ if (compileData.dependencies?.length) {
50
+ if (options.server) {
51
+ for (const dep of compileData.dependencies) {
52
+ ensureWatchedFile(options.server.watcher, dep, options.root);
53
+ }
54
+ } else if (options.isBuild && this.environment.config.build.watch) {
55
+ for (const dep of compileData.dependencies) {
56
+ this.addWatchFile(dep);
57
+ }
58
+ }
59
+ }
60
+ return {
61
+ ...compileData.compiled.js,
62
+ moduleType: 'js',
63
+ meta: {
64
+ vite: {
65
+ lang: compileData.lang
66
+ }
67
+ }
68
+ };
69
+ }
70
+ }
71
+ };
72
+ return plugin;
73
+ }
@@ -0,0 +1,99 @@
1
+ import process from 'node:process';
2
+ import { isDebugNamespaceEnabled, log } from '../utils/log.js';
3
+ import * as vite from 'vite';
4
+ import { VitePluginSvelteCache } from '../utils/vite-plugin-svelte-cache.js';
5
+ import { VitePluginSvelteStats } from '../utils/vite-plugin-svelte-stats.js';
6
+ import {
7
+ buildExtraViteConfig,
8
+ validateInlineOptions,
9
+ resolveOptions,
10
+ preResolveOptions,
11
+ ensureConfigEnvironmentMainFields,
12
+ ensureConfigEnvironmentConditions
13
+ } from '../utils/options.js';
14
+ import { buildIdFilter, buildIdParser } from '../utils/id.js';
15
+ import { createCompileSvelte } from '../utils/compile.js';
16
+
17
+ // @ts-expect-error rolldownVersion
18
+ const { version: viteVersion, rolldownVersion, perEnvironmentState } = vite;
19
+
20
+ /**
21
+ * @param {Partial<import('../public.d.ts').Options>} [inlineOptions]
22
+ * @param {import('../types/plugin-api.d.ts').PluginAPI} api
23
+ * @returns {import('vite').Plugin}
24
+ */
25
+ export function configure(api, inlineOptions) {
26
+ if (rolldownVersion) {
27
+ log.warn.once(
28
+ `!!! Support for rolldown-vite in vite-plugin-svelte is experimental (rolldown: ${rolldownVersion}, vite: ${viteVersion}) !!!
29
+ See https://github.com/sveltejs/vite-plugin-svelte/issues/1143 for a list of known issues and to report feedback.`.replace(
30
+ /\t+/g,
31
+ '\t'
32
+ )
33
+ );
34
+ }
35
+
36
+ validateInlineOptions(inlineOptions);
37
+
38
+ /**
39
+ * @type {import("../types/options.d.ts").PreResolvedOptions}
40
+ */
41
+ let preOptions;
42
+
43
+ /** @type {import('vite').Plugin} */
44
+ return {
45
+ name: 'vite-plugin-svelte:config',
46
+ api,
47
+ // make sure it runs first
48
+ enforce: 'pre',
49
+ config: {
50
+ order: 'pre',
51
+ async handler(config, configEnv) {
52
+ // setup logger
53
+ if (process.env.DEBUG) {
54
+ log.setLevel('debug');
55
+ } else if (config.logLevel) {
56
+ log.setLevel(config.logLevel);
57
+ }
58
+
59
+ preOptions = await preResolveOptions(inlineOptions, config, configEnv);
60
+ // extra vite config
61
+ const extraViteConfig = await buildExtraViteConfig(preOptions, config);
62
+ log.debug('additional vite config', extraViteConfig, 'config');
63
+ return extraViteConfig;
64
+ }
65
+ },
66
+ configResolved: {
67
+ order: 'pre',
68
+ handler(config) {
69
+ const options = resolveOptions(preOptions, config);
70
+ api.options = options;
71
+ if (isDebugNamespaceEnabled('stats')) {
72
+ api.options.stats = new VitePluginSvelteStats();
73
+ }
74
+ //@ts-expect-error perEnvironmentState uses a wider type for PluginContext
75
+ api.getEnvironmentCache = perEnvironmentState((_env) => new VitePluginSvelteCache());
76
+ api.idFilter = buildIdFilter(options);
77
+
78
+ api.idParser = buildIdParser(options);
79
+ api.compileSvelte = createCompileSvelte();
80
+ log.debug('resolved options', api.options, 'config');
81
+ }
82
+ },
83
+
84
+ configEnvironment(name, config, opts) {
85
+ ensureConfigEnvironmentMainFields(name, config, opts);
86
+ // @ts-expect-error the function above should make `resolve.mainFields` non-nullable
87
+ config.resolve.mainFields.unshift('svelte');
88
+
89
+ ensureConfigEnvironmentConditions(name, config, opts);
90
+ // @ts-expect-error the function above should make `resolve.conditions` non-nullable
91
+ config.resolve.conditions.push('svelte');
92
+ },
93
+
94
+ configureServer(server) {
95
+ const { options } = api;
96
+ options.server = server;
97
+ }
98
+ };
99
+ }