@sveltejs/vite-plugin-svelte 6.0.0-next.1 → 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.1",
3
+ "version": "6.0.0-next.2",
4
4
  "license": "MIT",
5
5
  "author": "dominikg",
6
6
  "files": [
@@ -43,13 +43,13 @@
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
50
  "sass": "^1.89.2",
51
- "svelte": "^5.34.7",
52
- "vite": "^7.0.0-beta.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,235 +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
- See https://github.com/sveltejs/vite-plugin-svelte/issues/1143 for a list of known issues and to report feedback.`.replace(
45
- /\t+/g,
46
- '\t'
47
- )
48
- );
49
- }
50
-
51
- validateInlineOptions(inlineOptions);
52
- const cache = new VitePluginSvelteCache();
53
- // updated in configResolved hook
54
- /** @type {import('./types/id.d.ts').IdParser} */
55
- let requestParser;
56
- /** @type {import('./types/id.d.ts').ModuleIdParser} */
57
- let moduleRequestParser;
58
- /** @type {import('./types/options.d.ts').ResolvedOptions} */
59
- let options;
60
- /** @type {import('vite').ResolvedConfig} */
61
- let viteConfig;
62
- /** @type {import('./types/compile.d.ts').CompileSvelte} */
63
- let compileSvelte;
64
-
65
- /** @type {import('vite').Plugin} */
66
- const compilePlugin = {
67
- name: 'vite-plugin-svelte',
68
- // make sure our resolver runs before vite internal resolver to resolve svelte field correctly
69
- enforce: 'pre',
70
- /** @type {import('./types/plugin-api.d.ts').PluginAPI} */
71
- api: {},
72
- async config(config, configEnv) {
73
- // setup logger
74
- if (process.env.DEBUG) {
75
- log.setLevel('debug');
76
- } else if (config.logLevel) {
77
- log.setLevel(config.logLevel);
78
- }
79
- // @ts-expect-error temporarily lend the options variable until fixed in configResolved
80
- options = await preResolveOptions(inlineOptions, config, configEnv);
81
- // extra vite config
82
- const extraViteConfig = await buildExtraViteConfig(options, config);
83
- log.debug('additional vite config', extraViteConfig, 'config');
84
- return extraViteConfig;
85
- },
86
-
87
- configEnvironment(name, config, opts) {
88
- ensureConfigEnvironmentMainFields(name, config, opts);
89
- // @ts-expect-error the function above should make `resolve.mainFields` non-nullable
90
- config.resolve.mainFields.unshift('svelte');
91
-
92
- ensureConfigEnvironmentConditions(name, config, opts);
93
- // @ts-expect-error the function above should make `resolve.conditions` non-nullable
94
- config.resolve.conditions.push('svelte');
95
- },
96
-
97
- async configResolved(config) {
98
- options = resolveOptions(options, config, cache);
99
- patchResolvedViteConfig(config, options);
100
- const filter = buildIdFilter(options);
101
- //@ts-expect-error transform defined below but filter not in type
102
- compilePlugin.transform.filter = filter;
103
- //@ts-expect-error load defined below but filter not in type
104
- compilePlugin.load.filter = filter;
105
-
106
- requestParser = buildIdParser(options);
107
- compileSvelte = createCompileSvelte();
108
- viteConfig = config;
109
- // TODO deep clone to avoid mutability from outside?
110
- compilePlugin.api.options = options;
111
- log.debug('resolved options', options, 'config');
112
- log.debug('filters', filter, 'config');
113
- },
114
-
115
- async buildStart() {
116
- if (!options.prebundleSvelteLibraries) return;
117
- const isSvelteMetadataChanged = await saveSvelteMetadata(viteConfig.cacheDir, options);
118
- if (isSvelteMetadataChanged) {
119
- // Force Vite to optimize again. Although we mutate the config here, it works because
120
- // Vite's optimizer runs after `buildStart()`.
121
- viteConfig.optimizeDeps.force = true;
122
- }
123
- },
124
-
125
- configureServer(server) {
126
- options.server = server;
127
- setupWatchers(options, cache, requestParser);
128
- },
129
-
130
- load: {
131
- async handler(id, opts) {
132
- const ssr = !!opts?.ssr;
133
- const svelteRequest = requestParser(id, !!ssr);
134
- if (svelteRequest) {
135
- const { filename, query, raw } = svelteRequest;
136
- if (raw) {
137
- const code = await loadRaw(svelteRequest, compileSvelte, options);
138
- // prevent vite from injecting sourcemaps in the results.
139
- return {
140
- code,
141
- map: {
142
- mappings: ''
143
- }
144
- };
145
- } else {
146
- if (query.svelte && query.type === 'style') {
147
- const cachedCss = cache.getCSS(svelteRequest);
148
- if (cachedCss) {
149
- const { hasGlobal, ...css } = cachedCss;
150
- if (hasGlobal === false) {
151
- // hasGlobal was added in svelte 5.26.0, so make sure it is boolean false
152
- css.meta ??= {};
153
- css.meta.vite ??= {};
154
- css.meta.vite.cssScopeTo = [svelteRequest.filename, 'default'];
155
- }
156
- css.moduleType = 'css';
157
-
158
- return css;
159
- }
160
- }
161
- // prevent vite asset plugin from loading files as url that should be compiled in transform
162
- if (viteConfig.assetsInclude(filename)) {
163
- log.debug(`load returns raw content for ${filename}`, undefined, 'load');
164
- return fs.readFileSync(filename, 'utf-8');
165
- }
166
- }
167
- }
168
- }
169
- },
170
-
171
- resolveId: {
172
- // we don't use our generic filter here but a reduced one that only matches our virtual css
173
- filter: { id: SVELTE_VIRTUAL_STYLE_ID_REGEX },
174
- handler(id) {
175
- // return cssId with root prefix so postcss pipeline of vite finds the directory correctly
176
- // see https://github.com/sveltejs/vite-plugin-svelte/issues/14
177
- log.debug(`resolveId resolved virtual css module ${id}`, undefined, 'resolve');
178
- // TODO: do we have to repeat the dance for constructing the virtual id here? our transform added it that way
179
- return id;
180
- }
181
- },
182
-
183
- transform: {
184
- async handler(code, id, opts) {
185
- const ssr = !!opts?.ssr;
186
- const svelteRequest = requestParser(id, ssr);
187
- if (!svelteRequest || svelteRequest.query.type === 'style' || svelteRequest.raw) {
188
- return;
189
- }
190
- let compileData;
191
- try {
192
- compileData = await compileSvelte(svelteRequest, code, options);
193
- } catch (e) {
194
- cache.setError(svelteRequest, e);
195
- throw toRollupError(e, options);
196
- }
197
- logCompilerWarnings(svelteRequest, compileData.compiled.warnings, options);
198
- cache.update(compileData);
199
- if (compileData.dependencies?.length) {
200
- if (options.server) {
201
- for (const dep of compileData.dependencies) {
202
- ensureWatchedFile(options.server.watcher, dep, options.root);
203
- }
204
- } else if (options.isBuild && viteConfig.build.watch) {
205
- for (const dep of compileData.dependencies) {
206
- this.addWatchFile(dep);
207
- }
208
- }
209
- }
210
- return {
211
- ...compileData.compiled.js,
212
- moduleType: 'js',
213
- meta: {
214
- vite: {
215
- lang: compileData.lang
216
- }
217
- }
218
- };
219
- }
220
- },
221
-
222
- handleHotUpdate(ctx) {
223
- if (!options.compilerOptions.hmr || !options.emitCss) {
224
- return;
225
- }
226
- const svelteRequest = requestParser(ctx.file, false, ctx.timestamp);
227
- if (svelteRequest) {
228
- return handleHotUpdate(compileSvelte, ctx, svelteRequest, cache, options);
229
- }
230
- },
231
- async buildEnd() {
232
- await options.stats?.finishAll();
233
- }
234
- };
235
-
236
- /** @type {import('vite').Plugin} */
237
- const moduleCompilePlugin = {
238
- name: 'vite-plugin-svelte-module',
239
- enforce: 'post',
240
- async configResolved() {
241
- //@ts-expect-error transform defined below but filter not in type
242
- moduleCompilePlugin.transform.filter = buildModuleIdFilter(options);
243
- moduleRequestParser = buildModuleIdParser(options);
244
- },
245
- transform: {
246
- async handler(code, id, opts) {
247
- const ssr = !!opts?.ssr;
248
- const moduleRequest = moduleRequestParser(id, ssr);
249
- if (!moduleRequest) {
250
- return;
251
- }
252
- try {
253
- const compileResult = svelteCompiler.compileModule(code, {
254
- dev: !viteConfig.isProduction,
255
- generate: ssr ? 'server' : 'client',
256
- filename: moduleRequest.filename
257
- });
258
- logCompilerWarnings(moduleRequest, compileResult.warnings, options);
259
- return compileResult.js;
260
- } catch (e) {
261
- throw toRollupError(e, options);
262
- }
263
- }
264
- }
265
- };
266
-
267
- /** @type {import('vite').Plugin[]} */
268
- const plugins = [compilePlugin, moduleCompilePlugin, svelteInspector()];
269
- 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
+ ];
270
39
  }
271
40
 
272
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
+ }