@sveltejs/vite-plugin-svelte 4.0.0-next.0 → 4.0.0-next.1

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": "4.0.0-next.0",
3
+ "version": "4.0.0-next.1",
4
4
  "license": "MIT",
5
5
  "author": "dominikg",
6
6
  "files": [
@@ -41,7 +41,7 @@
41
41
  "kleur": "^4.1.5",
42
42
  "magic-string": "^0.30.10",
43
43
  "vitefu": "^0.2.5",
44
- "@sveltejs/vite-plugin-svelte-inspector": "^3.0.0-next.0"
44
+ "@sveltejs/vite-plugin-svelte-inspector": "^3.0.0-next.1"
45
45
  },
46
46
  "peerDependencies": {
47
47
  "svelte": "^5.0.0-next.96 || ^5.0.0",
package/src/index.js CHANGED
@@ -200,6 +200,7 @@ export function svelte(inlineOptions) {
200
200
  }
201
201
  try {
202
202
  const compileResult = svelteCompiler.compileModule(code, {
203
+ dev: !viteConfig.isProduction,
203
204
  generate: ssr ? 'server' : 'client',
204
205
  filename: moduleRequest.filename
205
206
  });
package/src/public.d.ts CHANGED
@@ -175,6 +175,15 @@ interface ExperimentalOptions {
175
175
  }
176
176
 
177
177
  interface CompileModuleOptions {
178
+ /**
179
+ * infix that must be present in filename
180
+ * @default ['.svelte.']
181
+ */
182
+ infixes?: string[];
183
+ /**
184
+ * module extensions
185
+ * @default ['.ts','.js']
186
+ */
178
187
  extensions?: string[];
179
188
  include?: Arrayable<string>;
180
189
  exclude?: Arrayable<string>;
@@ -128,12 +128,11 @@ export function createCompileSvelte() {
128
128
  ...dynamicCompileOptions
129
129
  }
130
130
  : compileOptions;
131
-
132
131
  const endStat = stats?.start(filename);
133
132
  /** @type {import('svelte/compiler').CompileResult} */
134
133
  let compiled;
135
134
  try {
136
- compiled = svelte.compile(finalCode, finalCompileOptions);
135
+ compiled = svelte.compile(finalCode, { ...finalCompileOptions, filename: filename });
137
136
  // patch output with partial accept until svelte does it
138
137
  // TODO remove later
139
138
  if (
@@ -20,3 +20,7 @@ export const SVELTE_EXPORT_CONDITIONS = ['svelte'];
20
20
 
21
21
  export const FAQ_LINK_MISSING_EXPORTS_CONDITION =
22
22
  'https://github.com/sveltejs/vite-plugin-svelte/blob/main/docs/faq.md#missing-exports-condition';
23
+
24
+ export const DEFAULT_SVELTE_EXT = ['.svelte'];
25
+ export const DEFAULT_SVELTE_MODULE_INFIX = ['.svelte.'];
26
+ export const DEFAULT_SVELTE_MODULE_EXT = ['.js', '.ts'];
@@ -9,8 +9,7 @@ import { toESBuildError } from './error.js';
9
9
  */
10
10
 
11
11
  export const facadeEsbuildSveltePluginName = 'vite-plugin-svelte:facade';
12
-
13
- const svelteModuleExtension = '.svelte.js';
12
+ export const facadeEsbuildSvelteModulePluginName = 'vite-plugin-svelte-module:facade';
14
13
 
15
14
  /**
16
15
  * @param {import('../types/options.d.ts').ResolvedOptions} options
@@ -24,18 +23,15 @@ export function esbuildSveltePlugin(options) {
24
23
  // Otherwise this would heavily slow down the scanning phase.
25
24
  if (build.initialOptions.plugins?.some((v) => v.name === 'vite:dep-scan')) return;
26
25
 
27
- const svelteExtensions = (options.extensions ?? ['.svelte']).map((ext) => ext.slice(1));
28
- svelteExtensions.push(svelteModuleExtension.slice(1));
29
-
30
- const svelteFilter = new RegExp('\\.(' + svelteExtensions.join('|') + ')(\\?.*)?$');
26
+ const filter = /\.svelte(?:\?.*)?$/;
31
27
  /** @type {import('../types/vite-plugin-svelte-stats.d.ts').StatCollection | undefined} */
32
28
  let statsCollection;
33
29
  build.onStart(() => {
34
- statsCollection = options.stats?.startCollection('prebundle libraries', {
30
+ statsCollection = options.stats?.startCollection('prebundle library components', {
35
31
  logResult: (c) => c.stats.length > 1
36
32
  });
37
33
  });
38
- build.onLoad({ filter: svelteFilter }, async ({ path: filename }) => {
34
+ build.onLoad({ filter }, async ({ path: filename }) => {
39
35
  const code = readFileSync(filename, 'utf8');
40
36
  try {
41
37
  const contents = await compileSvelte(options, { filename, code }, statsCollection);
@@ -58,19 +54,6 @@ export function esbuildSveltePlugin(options) {
58
54
  * @returns {Promise<string>}
59
55
  */
60
56
  async function compileSvelte(options, { filename, code }, statsCollection) {
61
- if (filename.endsWith(svelteModuleExtension)) {
62
- const endStat = statsCollection?.start(filename);
63
- const compiled = svelte.compileModule(code, {
64
- filename,
65
- generate: 'client'
66
- });
67
- if (endStat) {
68
- endStat();
69
- }
70
- return compiled.js.map
71
- ? compiled.js.code + '//# sourceMappingURL=' + compiled.js.map.toUrl()
72
- : compiled.js.code;
73
- }
74
57
  let css = options.compilerOptions.css;
75
58
  if (css !== 'injected') {
76
59
  // TODO ideally we'd be able to externalize prebundled styles too, but for now always put them in the js
@@ -78,6 +61,7 @@ async function compileSvelte(options, { filename, code }, statsCollection) {
78
61
  }
79
62
  /** @type {import('svelte/compiler').CompileOptions} */
80
63
  const compileOptions = {
64
+ dev: true, // default to dev: true because prebundling is only used in dev
81
65
  ...options.compilerOptions,
82
66
  css,
83
67
  filename,
@@ -127,3 +111,60 @@ async function compileSvelte(options, { filename, code }, statsCollection) {
127
111
  ? compiled.js.code + '//# sourceMappingURL=' + compiled.js.map.toUrl()
128
112
  : compiled.js.code;
129
113
  }
114
+
115
+ /**
116
+ * @param {import('../types/options.d.ts').ResolvedOptions} options
117
+ * @returns {EsbuildPlugin}
118
+ */
119
+ export function esbuildSvelteModulePlugin(options) {
120
+ return {
121
+ name: 'vite-plugin-svelte-module:optimize-svelte',
122
+ setup(build) {
123
+ // Skip in scanning phase as Vite already handles scanning Svelte files.
124
+ // Otherwise this would heavily slow down the scanning phase.
125
+ if (build.initialOptions.plugins?.some((v) => v.name === 'vite:dep-scan')) return;
126
+
127
+ const filter = /\.svelte\.[jt]s(?:\?.*)?$/;
128
+ /** @type {import('../types/vite-plugin-svelte-stats.d.ts').StatCollection | undefined} */
129
+ let statsCollection;
130
+ build.onStart(() => {
131
+ statsCollection = options.stats?.startCollection('prebundle library modules', {
132
+ logResult: (c) => c.stats.length > 1
133
+ });
134
+ });
135
+ build.onLoad({ filter }, async ({ path: filename }) => {
136
+ const code = readFileSync(filename, 'utf8');
137
+ try {
138
+ const contents = await compileSvelteModule(options, { filename, code }, statsCollection);
139
+ return { contents };
140
+ } catch (e) {
141
+ return { errors: [toESBuildError(e, options)] };
142
+ }
143
+ });
144
+ build.onEnd(() => {
145
+ statsCollection?.finish();
146
+ });
147
+ }
148
+ };
149
+ }
150
+
151
+ /**
152
+ * @param {import('../types/options.d.ts').ResolvedOptions} options
153
+ * @param {{ filename: string; code: string }} input
154
+ * @param {import('../types/vite-plugin-svelte-stats.d.ts').StatCollection} [statsCollection]
155
+ * @returns {Promise<string>}
156
+ */
157
+ async function compileSvelteModule(options, { filename, code }, statsCollection) {
158
+ const endStat = statsCollection?.start(filename);
159
+ const compiled = svelte.compileModule(code, {
160
+ dev: options.compilerOptions?.dev ?? true, // default to dev: true because prebundling is only used in dev
161
+ filename,
162
+ generate: 'client'
163
+ });
164
+ if (endStat) {
165
+ endStat();
166
+ }
167
+ return compiled.js.map
168
+ ? compiled.js.code + '//# sourceMappingURL=' + compiled.js.map.toUrl()
169
+ : compiled.js.code;
170
+ }
package/src/utils/id.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import { createFilter, normalizePath } from 'vite';
2
2
  import * as fs from 'node:fs';
3
3
  import { log } from './log.js';
4
+ import { DEFAULT_SVELTE_MODULE_EXT, DEFAULT_SVELTE_MODULE_INFIX } from './constants.js';
4
5
 
5
6
  const VITE_FS_PREFIX = '/@fs/';
6
7
  const IS_WINDOWS = process.platform === 'win32';
@@ -169,6 +170,21 @@ function buildFilter(include, exclude, extensions) {
169
170
  return (filename) => rollupFilter(filename) && extensions.some((ext) => filename.endsWith(ext));
170
171
  }
171
172
 
173
+ /**
174
+ * @param {import('../public.d.ts').Options['include'] | undefined} include
175
+ * @param {import('../public.d.ts').Options['exclude'] | undefined} exclude
176
+ * @param {string[]} infixes
177
+ * @param {string[]} extensions
178
+ * @returns {(filename: string) => boolean}
179
+ */
180
+ function buildModuleFilter(include, exclude, infixes, extensions) {
181
+ const rollupFilter = createFilter(include, exclude);
182
+ return (filename) =>
183
+ rollupFilter(filename) &&
184
+ infixes.some((infix) => filename.includes(infix)) &&
185
+ extensions.some((ext) => filename.endsWith(ext));
186
+ }
187
+
172
188
  /**
173
189
  * @param {import('../types/options.d.ts').ResolvedOptions} options
174
190
  * @returns {import('../types/id.d.ts').IdParser}
@@ -190,10 +206,15 @@ export function buildIdParser(options) {
190
206
  * @returns {import('../types/id.d.ts').ModuleIdParser}
191
207
  */
192
208
  export function buildModuleIdParser(options) {
193
- const { include, exclude, extensions } = options?.experimental?.compileModule ?? {};
209
+ const {
210
+ include,
211
+ exclude,
212
+ infixes = DEFAULT_SVELTE_MODULE_INFIX,
213
+ extensions = DEFAULT_SVELTE_MODULE_EXT
214
+ } = options?.experimental?.compileModule ?? {};
194
215
  const root = options.root;
195
216
  const normalizedRoot = normalizePath(root);
196
- const filter = buildFilter(include, exclude, extensions ?? ['.svelte.js', '.svelte.ts']);
217
+ const filter = buildModuleFilter(include, exclude, infixes, extensions);
197
218
  return (id, ssr, timestamp = Date.now()) => {
198
219
  const { filename, rawQuery } = splitId(id);
199
220
  if (filter(filename)) {
@@ -3,6 +3,7 @@ import { normalizePath } from 'vite';
3
3
  import { isDebugNamespaceEnabled, log } from './log.js';
4
4
  import { loadSvelteConfig } from './load-svelte-config.js';
5
5
  import {
6
+ DEFAULT_SVELTE_EXT,
6
7
  FAQ_LINK_MISSING_EXPORTS_CONDITION,
7
8
  SVELTE_EXPORT_CONDITIONS,
8
9
  SVELTE_IMPORTS,
@@ -11,7 +12,12 @@ import {
11
12
  } from './constants.js';
12
13
 
13
14
  import path from 'node:path';
14
- import { esbuildSveltePlugin, facadeEsbuildSveltePluginName } from './esbuild.js';
15
+ import {
16
+ esbuildSvelteModulePlugin,
17
+ esbuildSveltePlugin,
18
+ facadeEsbuildSvelteModulePluginName,
19
+ facadeEsbuildSveltePluginName
20
+ } from './esbuild.js';
15
21
  import { addExtraPreprocessors } from './preprocess.js';
16
22
  import deepmerge from 'deepmerge';
17
23
  import {
@@ -137,7 +143,7 @@ export async function preResolveOptions(inlineOptions, viteUserConfig, viteEnv)
137
143
  const isBuild = viteEnv.command === 'build';
138
144
  /** @type {Partial<import('../types/options.d.ts').PreResolvedOptions>} */
139
145
  const defaultOptions = {
140
- extensions: ['.svelte'],
146
+ extensions: DEFAULT_SVELTE_EXT,
141
147
  emitCss: true,
142
148
  prebundleSvelteLibraries: !isBuild
143
149
  };
@@ -383,7 +389,10 @@ export async function buildExtraViteConfig(options, config) {
383
389
  // Currently a placeholder as more information is needed after Vite config is resolved,
384
390
  // the real Svelte plugin is added in `patchResolvedViteConfig()`
385
391
  esbuildOptions: {
386
- plugins: [{ name: facadeEsbuildSveltePluginName, setup: () => {} }]
392
+ plugins: [
393
+ { name: facadeEsbuildSveltePluginName, setup: () => {} },
394
+ { name: facadeEsbuildSvelteModulePluginName, setup: () => {} }
395
+ ]
387
396
  }
388
397
  };
389
398
  }
@@ -583,6 +592,12 @@ export function patchResolvedViteConfig(viteConfig, options) {
583
592
  if (facadeEsbuildSveltePlugin) {
584
593
  Object.assign(facadeEsbuildSveltePlugin, esbuildSveltePlugin(options));
585
594
  }
595
+ const facadeEsbuildSvelteModulePlugin = viteConfig.optimizeDeps.esbuildOptions?.plugins?.find(
596
+ (plugin) => plugin.name === facadeEsbuildSvelteModulePluginName
597
+ );
598
+ if (facadeEsbuildSvelteModulePlugin) {
599
+ Object.assign(facadeEsbuildSvelteModulePlugin, esbuildSvelteModulePlugin(options));
600
+ }
586
601
  }
587
602
 
588
603
  /**
package/types/index.d.ts CHANGED
@@ -173,6 +173,15 @@ declare module '@sveltejs/vite-plugin-svelte' {
173
173
  }
174
174
 
175
175
  interface CompileModuleOptions {
176
+ /**
177
+ * infix that must be present in filename
178
+ * @default ['.svelte.']
179
+ */
180
+ infixes?: string[];
181
+ /**
182
+ * module extensions
183
+ * @default ['.ts','.js']
184
+ */
176
185
  extensions?: string[];
177
186
  include?: Arrayable<string>;
178
187
  exclude?: Arrayable<string>;
@@ -21,5 +21,5 @@
21
21
  null,
22
22
  null
23
23
  ],
24
- "mappings": ";;;;aAMYA,OAAOA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBA6GFC,YAAYA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAqEZC,qBAAqBA;;;;;;;;;;;;;iBChKtBC,MAAMA;iBCTNC,cAAcA;iBCgBRC,gBAAgBA"
24
+ "mappings": ";;;;aAMYA,OAAOA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBA6GFC,YAAYA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBA8EZC,qBAAqBA;;;;;;;;;;;;;iBCzKtBC,MAAMA;iBCTNC,cAAcA;iBCgBRC,gBAAgBA"
25
25
  }