@sveltejs/vite-plugin-svelte 1.1.0 → 1.2.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.
@@ -1,12 +1,5 @@
1
1
  /* eslint-disable no-unused-vars */
2
- import {
3
- ConfigEnv,
4
- DepOptimizationOptions,
5
- ResolvedConfig,
6
- UserConfig,
7
- ViteDevServer,
8
- normalizePath
9
- } from 'vite';
2
+ import { ConfigEnv, ResolvedConfig, UserConfig, ViteDevServer, normalizePath } from 'vite';
10
3
  import { log } from './log';
11
4
  import { loadSvelteConfig } from './load-svelte-config';
12
5
  import { SVELTE_HMR_IMPORTS, SVELTE_IMPORTS, SVELTE_RESOLVE_MAIN_FIELDS } from './constants';
@@ -21,11 +14,22 @@ import type {
21
14
  } from 'svelte/types/compiler/preprocess';
22
15
 
23
16
  import path from 'path';
24
- import { findRootSvelteDependencies, needsOptimization, SvelteDependency } from './dependencies';
25
- import { createRequire } from 'module';
26
17
  import { esbuildSveltePlugin, facadeEsbuildSveltePluginName } from './esbuild';
27
18
  import { addExtraPreprocessors } from './preprocess';
28
19
  import deepmerge from 'deepmerge';
20
+ import {
21
+ crawlFrameworkPkgs,
22
+ isDepExcluded,
23
+ isDepExternaled,
24
+ isDepIncluded,
25
+ isDepNoExternaled
26
+ // eslint-disable-next-line node/no-missing-import
27
+ } from 'vitefu';
28
+ import { atLeastSvelte } from './svelte-version';
29
+ import { isCommonDepWithoutSvelteField } from './dependencies';
30
+
31
+ // svelte 3.53.0 changed compilerOptions.css from boolean to string | boolen, use string when available
32
+ const cssAsString = atLeastSvelte('3.53.0');
29
33
 
30
34
  const allowedPluginOptions = new Set([
31
35
  'include',
@@ -170,15 +174,20 @@ export function resolveOptions(
170
174
  preResolveOptions: PreResolvedOptions,
171
175
  viteConfig: ResolvedConfig
172
176
  ): ResolvedOptions {
177
+ const css = cssAsString
178
+ ? preResolveOptions.emitCss
179
+ ? 'external'
180
+ : 'injected'
181
+ : !preResolveOptions.emitCss;
173
182
  const defaultOptions: Partial<Options> = {
174
183
  hot: viteConfig.isProduction
175
184
  ? false
176
185
  : {
177
- injectCss: !preResolveOptions.emitCss,
186
+ injectCss: css === true || css === 'injected',
178
187
  partialAccept: !!viteConfig.experimental?.hmrPartialAccept
179
188
  },
180
189
  compilerOptions: {
181
- css: !preResolveOptions.emitCss,
190
+ css,
182
191
  dev: !viteConfig.isProduction
183
192
  }
184
193
  };
@@ -208,11 +217,13 @@ function enforceOptionsForHmr(options: ResolvedOptions) {
208
217
  log.warn('hmr and emitCss are enabled but hot.injectCss is true, forcing it to false');
209
218
  options.hot.injectCss = false;
210
219
  }
211
- if (options.compilerOptions.css) {
220
+ const css = options.compilerOptions.css;
221
+ if (css === true || css === 'injected') {
222
+ const forcedCss = cssAsString ? 'external' : false;
212
223
  log.warn(
213
- 'hmr and emitCss are enabled but compilerOptions.css is true, forcing it to false'
224
+ `hmr and emitCss are enabled but compilerOptions.css is ${css}, forcing it to ${forcedCss}`
214
225
  );
215
- options.compilerOptions.css = false;
226
+ options.compilerOptions.css = forcedCss;
216
227
  }
217
228
  } else {
218
229
  if (options.hot === true || !options.hot.injectCss) {
@@ -225,11 +236,13 @@ function enforceOptionsForHmr(options: ResolvedOptions) {
225
236
  options.hot.injectCss = true;
226
237
  }
227
238
  }
228
- if (!options.compilerOptions.css) {
239
+ const css = options.compilerOptions.css;
240
+ if (!(css === true || css === 'injected')) {
241
+ const forcedCss = cssAsString ? 'injected' : true;
229
242
  log.warn(
230
- 'hmr with emitCss disabled requires compilerOptions.css to be enabled, forcing it to true'
243
+ `hmr with emitCss disabled requires compilerOptions.css to be enabled, forcing it to ${forcedCss}`
231
244
  );
232
- options.compilerOptions.css = true;
245
+ options.compilerOptions.css = forcedCss;
233
246
  }
234
247
  }
235
248
  }
@@ -273,20 +286,9 @@ function removeIgnoredOptions(options: ResolvedOptions) {
273
286
  // some SvelteKit options need compilerOptions to work, so set them here.
274
287
  function addSvelteKitOptions(options: ResolvedOptions) {
275
288
  // @ts-expect-error kit is not typed to avoid dependency on sveltekit
276
- if (options?.kit != null) {
277
- // @ts-expect-error kit is not typed to avoid dependency on sveltekit
278
- const kit_browser_hydrate = options.kit.browser?.hydrate;
279
- const hydratable = kit_browser_hydrate !== false;
280
- if (
281
- options.compilerOptions.hydratable != null &&
282
- options.compilerOptions.hydratable !== hydratable
283
- ) {
284
- log.warn(
285
- `Conflicting values "compilerOptions.hydratable: ${options.compilerOptions.hydratable}" and "kit.browser.hydrate: ${kit_browser_hydrate}" in your svelte config. You should remove "compilerOptions.hydratable".`
286
- );
287
- }
288
- log.debug(`Setting compilerOptions.hydratable: ${hydratable} for SvelteKit`);
289
- options.compilerOptions.hydratable = hydratable;
289
+ if (options?.kit != null && options.compilerOptions.hydratable == null) {
290
+ log.debug(`Setting compilerOptions.hydratable = true for SvelteKit`);
291
+ options.compilerOptions.hydratable = true;
290
292
  }
291
293
  }
292
294
 
@@ -306,12 +308,10 @@ function resolveViteRoot(viteConfig: UserConfig): string | undefined {
306
308
  return normalizePath(viteConfig.root ? path.resolve(viteConfig.root) : process.cwd());
307
309
  }
308
310
 
309
- export function buildExtraViteConfig(
311
+ export async function buildExtraViteConfig(
310
312
  options: PreResolvedOptions,
311
313
  config: UserConfig
312
- ): Partial<UserConfig> {
313
- // extra handling for svelte dependencies in the project
314
- const svelteDeps = findRootSvelteDependencies(options.root);
314
+ ): Promise<Partial<UserConfig>> {
315
315
  const extraViteConfig: Partial<UserConfig> = {
316
316
  resolve: {
317
317
  mainFields: [...SVELTE_RESOLVE_MAIN_FIELDS],
@@ -323,30 +323,50 @@ export function buildExtraViteConfig(
323
323
  // knownJsSrcExtensions: options.extensions
324
324
  };
325
325
 
326
- extraViteConfig.optimizeDeps = buildOptimizeDepsForSvelte(
327
- svelteDeps,
328
- options,
329
- config.optimizeDeps
330
- );
326
+ const extraSvelteConfig = buildExtraConfigForSvelte(config);
327
+ const extraDepsConfig = await buildExtraConfigForDependencies(options, config);
328
+ // merge extra svelte and deps config, but make sure dep values are not contradicting svelte
329
+ extraViteConfig.optimizeDeps = {
330
+ include: [
331
+ ...extraSvelteConfig.optimizeDeps.include,
332
+ ...extraDepsConfig.optimizeDeps.include.filter(
333
+ (dep) => !isDepExcluded(dep, extraSvelteConfig.optimizeDeps.exclude)
334
+ )
335
+ ],
336
+ exclude: [
337
+ ...extraSvelteConfig.optimizeDeps.exclude,
338
+ ...extraDepsConfig.optimizeDeps.exclude.filter(
339
+ (dep) => !isDepIncluded(dep, extraSvelteConfig.optimizeDeps.include)
340
+ )
341
+ ]
342
+ };
331
343
 
344
+ extraViteConfig.ssr = {
345
+ external: [
346
+ ...extraSvelteConfig.ssr.external,
347
+ ...extraDepsConfig.ssr.external.filter(
348
+ (dep) => !isDepNoExternaled(dep, extraSvelteConfig.ssr.noExternal)
349
+ )
350
+ ],
351
+ noExternal: [
352
+ ...extraSvelteConfig.ssr.noExternal,
353
+ ...extraDepsConfig.ssr.noExternal.filter(
354
+ (dep) => !isDepExternaled(dep, extraSvelteConfig.ssr.external)
355
+ )
356
+ ]
357
+ };
358
+
359
+ // handle prebundling for svelte files
332
360
  if (options.prebundleSvelteLibraries) {
333
- extraViteConfig.optimizeDeps = {
334
- ...extraViteConfig.optimizeDeps,
335
- // Experimental Vite API to allow these extensions to be scanned and prebundled
336
- // @ts-ignore
337
- extensions: options.extensions ?? ['.svelte'],
338
- // Add esbuild plugin to prebundle Svelte files.
339
- // Currently a placeholder as more information is needed after Vite config is resolved,
340
- // the real Svelte plugin is added in `patchResolvedViteConfig()`
341
- esbuildOptions: {
342
- plugins: [{ name: facadeEsbuildSveltePluginName, setup: () => {} }]
343
- }
361
+ extraViteConfig.optimizeDeps.extensions = options.extensions ?? ['.svelte'];
362
+ // Add esbuild plugin to prebundle Svelte files.
363
+ // Currently a placeholder as more information is needed after Vite config is resolved,
364
+ // the real Svelte plugin is added in `patchResolvedViteConfig()`
365
+ extraViteConfig.optimizeDeps.esbuildOptions = {
366
+ plugins: [{ name: facadeEsbuildSveltePluginName, setup: () => {} }]
344
367
  };
345
368
  }
346
369
 
347
- // @ts-ignore
348
- extraViteConfig.ssr = buildSSROptionsForSvelte(svelteDeps, options, config, extraViteConfig);
349
-
350
370
  // enable hmrPartialAccept if not explicitly disabled
351
371
  if (
352
372
  (options.hot == null ||
@@ -357,112 +377,91 @@ export function buildExtraViteConfig(
357
377
  log.debug('enabling "experimental.hmrPartialAccept" in vite config');
358
378
  extraViteConfig.experimental = { hmrPartialAccept: true };
359
379
  }
360
-
361
380
  return extraViteConfig;
362
381
  }
363
382
 
364
- function buildOptimizeDepsForSvelte(
365
- svelteDeps: SvelteDependency[],
366
- options: PreResolvedOptions,
367
- optimizeDeps?: DepOptimizationOptions
368
- ): DepOptimizationOptions {
383
+ async function buildExtraConfigForDependencies(options: PreResolvedOptions, config: UserConfig) {
384
+ // extra handling for svelte dependencies in the project
385
+ const depsConfig = await crawlFrameworkPkgs({
386
+ root: options.root,
387
+ isBuild: options.isBuild,
388
+ viteUserConfig: config,
389
+ isFrameworkPkgByJson(pkgJson) {
390
+ return !!pkgJson.svelte;
391
+ },
392
+ isSemiFrameworkPkgByJson(pkgJson) {
393
+ return !!pkgJson.dependencies?.svelte || !!pkgJson.peerDependencies?.svelte;
394
+ },
395
+ isFrameworkPkgByName(pkgName) {
396
+ const isNotSveltePackage = isCommonDepWithoutSvelteField(pkgName);
397
+ if (isNotSveltePackage) {
398
+ return false;
399
+ } else {
400
+ return undefined;
401
+ }
402
+ }
403
+ });
404
+
405
+ log.debug('extra config for dependencies generated by vitefu', depsConfig);
406
+
407
+ if (options.prebundleSvelteLibraries) {
408
+ // prebundling enabled, so we don't need extra dependency excludes
409
+ depsConfig.optimizeDeps.exclude = [];
410
+ // but keep dependency reinclusions of explicit user excludes
411
+ const userExclude = config.optimizeDeps?.exclude;
412
+ depsConfig.optimizeDeps.include = !userExclude
413
+ ? []
414
+ : depsConfig.optimizeDeps.include.filter((dep: string) => {
415
+ // reincludes look like this: foo > bar > baz
416
+ // in case foo or bar are excluded, we have to retain the reinclude even with prebundling
417
+ return (
418
+ dep.includes('>') &&
419
+ dep
420
+ .split('>')
421
+ .slice(0, -1)
422
+ .some((d) => isDepExcluded(d.trim(), userExclude))
423
+ );
424
+ });
425
+ }
426
+ if (options.disableDependencyReinclusion === true) {
427
+ depsConfig.optimizeDeps.include = depsConfig.optimizeDeps.include.filter(
428
+ (dep) => !dep.includes('>')
429
+ );
430
+ } else if (Array.isArray(options.disableDependencyReinclusion)) {
431
+ const disabledDeps = options.disableDependencyReinclusion;
432
+ depsConfig.optimizeDeps.include = depsConfig.optimizeDeps.include.filter((dep) => {
433
+ if (!dep.includes('>')) return true;
434
+ const trimDep = dep.replace(/\s+/g, '');
435
+ return disabledDeps.some((disabled) => trimDep.includes(`${disabled}>`));
436
+ });
437
+ }
438
+
439
+ log.debug('post-processed extra config for dependencies', depsConfig);
440
+
441
+ return depsConfig;
442
+ }
443
+
444
+ function buildExtraConfigForSvelte(config: UserConfig) {
369
445
  // include svelte imports for optimization unless explicitly excluded
370
446
  const include: string[] = [];
371
447
  const exclude: string[] = ['svelte-hmr'];
372
- const isIncluded = (dep: string) => include.includes(dep) || optimizeDeps?.include?.includes(dep);
373
- const isExcluded = (dep: string) => {
374
- return (
375
- exclude.includes(dep) ||
376
- // vite optimizeDeps.exclude works for subpackages too
377
- // see https://github.com/vitejs/vite/blob/c87763c1418d1ba876eae13d139eba83ac6f28b2/packages/vite/src/node/optimizer/scan.ts#L293
378
- optimizeDeps?.exclude?.some((id: string) => dep === id || id.startsWith(`${dep}/`))
379
- );
380
- };
381
- if (!isExcluded('svelte')) {
448
+ if (!isDepExcluded('svelte', config.optimizeDeps?.exclude ?? [])) {
382
449
  const svelteImportsToInclude = SVELTE_IMPORTS.filter((x) => x !== 'svelte/ssr'); // not used on clientside
383
450
  log.debug(
384
451
  `adding bare svelte packages to optimizeDeps.include: ${svelteImportsToInclude.join(', ')} `
385
452
  );
386
- include.push(...svelteImportsToInclude.filter((x) => !isIncluded(x)));
453
+ include.push(...svelteImportsToInclude);
387
454
  } else {
388
455
  log.debug('"svelte" is excluded in optimizeDeps.exclude, skipped adding it to include.');
389
456
  }
390
-
391
- // If we prebundle svelte libraries, we can skip the whole prebundling dance below
392
- if (options.prebundleSvelteLibraries) {
393
- return { include, exclude };
394
- }
395
-
396
- // only svelte component libraries needs to be processed for optimizeDeps, js libraries work fine
397
- svelteDeps = svelteDeps.filter((dep) => dep.type === 'component-library');
398
-
399
- const svelteDepsToExclude = Array.from(new Set(svelteDeps.map((dep) => dep.name))).filter(
400
- (dep) => !isIncluded(dep)
401
- );
402
- log.debug(`automatically excluding found svelte dependencies: ${svelteDepsToExclude.join(', ')}`);
403
- exclude.push(...svelteDepsToExclude.filter((x) => !isExcluded(x)));
404
-
405
- if (options.disableDependencyReinclusion !== true) {
406
- const disabledReinclusions = options.disableDependencyReinclusion || [];
407
- if (disabledReinclusions.length > 0) {
408
- log.debug(`not reincluding transitive dependencies of`, disabledReinclusions);
409
- }
410
- const transitiveDepsToInclude = svelteDeps
411
- .filter((dep) => !disabledReinclusions.includes(dep.name) && isExcluded(dep.name))
412
- .flatMap((dep) => {
413
- const localRequire = createRequire(`${dep.dir}/package.json`);
414
- return Object.keys(dep.pkg.dependencies || {})
415
- .filter((depOfDep) => !isExcluded(depOfDep) && needsOptimization(depOfDep, localRequire))
416
- .map((depOfDep) => dep.path.concat(dep.name, depOfDep).join(' > '));
417
- });
418
- log.debug(
419
- `reincluding transitive dependencies of excluded svelte dependencies`,
420
- transitiveDepsToInclude
421
- );
422
- include.push(...transitiveDepsToInclude);
423
- }
424
-
425
- return { include, exclude };
426
- }
427
-
428
- function buildSSROptionsForSvelte(
429
- svelteDeps: SvelteDependency[],
430
- options: ResolvedOptions,
431
- config: UserConfig
432
- ): any {
433
457
  const noExternal: (string | RegExp)[] = [];
434
-
458
+ const external: string[] = [];
435
459
  // add svelte to ssr.noExternal unless it is present in ssr.external
436
460
  // so we can resolve it with svelte/ssr
437
- if (!config.ssr?.external?.includes('svelte')) {
461
+ if (!isDepExternaled('svelte', config.ssr?.external ?? [])) {
438
462
  noExternal.push('svelte', /^svelte\//);
439
463
  }
440
-
441
- // add svelte dependencies to ssr.noExternal unless present in ssr.external
442
- noExternal.push(
443
- ...Array.from(new Set(svelteDeps.map((s) => s.name))).filter(
444
- (x) => !config.ssr?.external?.includes(x)
445
- )
446
- );
447
- const ssr = {
448
- noExternal,
449
- external: [] as string[]
450
- };
451
-
452
- if (options.isServe) {
453
- // during dev, we have to externalize transitive dependencies, see https://github.com/sveltejs/vite-plugin-svelte/issues/281
454
- ssr.external = Array.from(
455
- new Set(svelteDeps.flatMap((dep) => Object.keys(dep.pkg.dependencies || {})))
456
- ).filter(
457
- (dep) =>
458
- !ssr.noExternal.includes(dep) &&
459
- // TODO noExternal can be something different than a string array
460
- //!config.ssr?.noExternal?.includes(dep) &&
461
- !config.ssr?.external?.includes(dep)
462
- );
463
- }
464
-
465
- return ssr;
464
+ return { optimizeDeps: { include, exclude }, ssr: { noExternal, external } };
466
465
  }
467
466
 
468
467
  export function patchResolvedViteConfig(viteConfig: ResolvedConfig, options: ResolvedOptions) {
@@ -1,14 +1,8 @@
1
- import {
2
- transformWithEsbuild,
3
- ESBuildOptions,
4
- ResolvedConfig,
5
- TransformResult,
6
- Plugin
7
- } from 'vite';
1
+ import * as vite from 'vite';
2
+ import type { ESBuildOptions, ResolvedConfig, Plugin } from 'vite';
8
3
  import MagicString from 'magic-string';
9
4
  import { preprocess } from 'svelte/compiler';
10
5
  import { Preprocessor, PreprocessorGroup, Processed, ResolvedOptions } from './options';
11
- import { TransformPluginContext } from 'rollup';
12
6
  import { log } from './log';
13
7
  import { buildSourceMap } from './sourcemap';
14
8
  import path from 'path';
@@ -21,7 +15,7 @@ function createViteScriptPreprocessor(): Preprocessor {
21
15
  return async ({ attributes, content, filename = '' }) => {
22
16
  const lang = attributes.lang as string;
23
17
  if (!supportedScriptLangs.includes(lang)) return;
24
- const transformResult = await transformWithEsbuild(content, filename, {
18
+ const transformResult = await vite.transformWithEsbuild(content, filename, {
25
19
  loader: lang as ESBuildOptions['loader'],
26
20
  target: 'esnext',
27
21
  tsconfigRaw: {
@@ -40,34 +34,47 @@ function createViteScriptPreprocessor(): Preprocessor {
40
34
  }
41
35
 
42
36
  function createViteStylePreprocessor(config: ResolvedConfig): Preprocessor {
43
- const pluginName = 'vite:css';
44
- const plugin = config.plugins.find((p) => p.name === pluginName);
45
- if (!plugin) {
46
- throw new Error(`failed to find plugin ${pluginName}`);
47
- }
48
- if (!plugin.transform) {
49
- throw new Error(`plugin ${pluginName} has no transform`);
50
- }
51
- const pluginTransform = plugin.transform!.bind(null as unknown as TransformPluginContext);
37
+ const transform = getCssTransformFn(config);
52
38
  return async ({ attributes, content, filename = '' }) => {
53
39
  const lang = attributes.lang as string;
54
40
  if (!supportedStyleLangs.includes(lang)) return;
55
41
  const moduleId = `${filename}.${lang}`;
56
- const transformResult: TransformResult = (await pluginTransform(
57
- content,
58
- moduleId
59
- )) as TransformResult;
42
+ const result = await transform(content, moduleId);
60
43
  // patch sourcemap source to point back to original filename
61
- if (transformResult.map?.sources?.[0] === moduleId) {
62
- transformResult.map.sources[0] = path.basename(filename);
44
+ if (result.map?.sources?.[0] === moduleId) {
45
+ result.map.sources[0] = path.basename(filename);
63
46
  }
64
47
  return {
65
- code: transformResult.code,
66
- map: transformResult.map ?? undefined
48
+ code: result.code,
49
+ map: result.map ?? undefined
67
50
  };
68
51
  };
69
52
  }
70
53
 
54
+ // eslint-disable-next-line no-unused-vars
55
+ type CssTransform = (code: string, filename: string) => Promise<{ code: string; map?: any }>;
56
+
57
+ function getCssTransformFn(config: ResolvedConfig): CssTransform {
58
+ // API is only available in Vite 3.2 and above
59
+ // TODO: Remove Vite plugin hack when bump peer dep to Vite 3.2
60
+ if (vite.preprocessCSS) {
61
+ return async (code, filename) => {
62
+ return vite.preprocessCSS(code, filename, config);
63
+ };
64
+ } else {
65
+ const pluginName = 'vite:css';
66
+ const plugin = config.plugins.find((p) => p.name === pluginName);
67
+ if (!plugin) {
68
+ throw new Error(`failed to find plugin ${pluginName}`);
69
+ }
70
+ if (!plugin.transform) {
71
+ throw new Error(`plugin ${pluginName} has no transform`);
72
+ }
73
+ // @ts-expect-error
74
+ return plugin.transform.bind(null);
75
+ }
76
+ }
77
+
71
78
  function createVitePreprocessorGroup(config: ResolvedConfig): PreprocessorGroup {
72
79
  return {
73
80
  markup({ content, filename }) {
@@ -1,25 +1,24 @@
1
1
  import path from 'path';
2
- import { builtinModules, createRequire } from 'module';
3
- import { is_common_without_svelte_field, resolveDependencyData } from './dependencies';
2
+ import { builtinModules } from 'module';
3
+ import { resolveDependencyData, isCommonDepWithoutSvelteField } from './dependencies';
4
4
  import { VitePluginSvelteCache } from './vite-plugin-svelte-cache';
5
5
 
6
- export function resolveViaPackageJsonSvelte(
6
+ export async function resolveViaPackageJsonSvelte(
7
7
  importee: string,
8
8
  importer: string | undefined,
9
9
  cache: VitePluginSvelteCache
10
- ): string | void {
10
+ ): Promise<string | void> {
11
11
  if (
12
12
  importer &&
13
13
  isBareImport(importee) &&
14
14
  !isNodeInternal(importee) &&
15
- !is_common_without_svelte_field(importee)
15
+ !isCommonDepWithoutSvelteField(importee)
16
16
  ) {
17
17
  const cached = cache.getResolvedSvelteField(importee, importer);
18
18
  if (cached) {
19
19
  return cached;
20
20
  }
21
- const localRequire = createRequire(importer);
22
- const pkgData = resolveDependencyData(importee, localRequire);
21
+ const pkgData = await resolveDependencyData(importee, importer);
23
22
  if (pkgData) {
24
23
  const { pkg, dir } = pkgData;
25
24
  if (pkg.svelte) {
@@ -0,0 +1,37 @@
1
+ import { VERSION } from 'svelte/compiler';
2
+ const svelteVersion = parseVersion(VERSION);
3
+
4
+ export function parseVersion(version: string): number[] {
5
+ const segments = version.split('.', 3).map((s) => parseInt(s, 10));
6
+ while (segments.length < 3) {
7
+ segments.push(0);
8
+ }
9
+ return segments;
10
+ }
11
+
12
+ /**
13
+ * compare version with current svelte, only takes major.minor.patch into account.
14
+ * If you don't pass all three, values will be filled with 0, ie `3` is equal to `3.0.0`
15
+ * @param version
16
+ * @returns 1 if passed version is larger than current, 0 if it is equal and -1 if it is lower
17
+ */
18
+ export function compareToSvelte(version: string): 1 | 0 | -1 {
19
+ const parsedVersion = parseVersion(version);
20
+ for (let i = 0; i < svelteVersion.length; i++) {
21
+ const a = parsedVersion[i];
22
+ const b = svelteVersion[i];
23
+ if (a === b) {
24
+ continue;
25
+ } else if (a > b) {
26
+ return 1;
27
+ } else {
28
+ return -1;
29
+ }
30
+ }
31
+ return 0;
32
+ }
33
+
34
+ export function atLeastSvelte(version: string) {
35
+ const result = compareToSvelte(version) <= 0;
36
+ return result;
37
+ }
@@ -1,43 +0,0 @@
1
- import { describe, it, expect } from 'vitest';
2
- import { findRootSvelteDependencies, needsOptimization } from '../dependencies';
3
- import * as path from 'path';
4
- import { createRequire } from 'module';
5
- import { fileURLToPath } from 'url';
6
- const __dir = path.dirname(fileURLToPath(import.meta.url));
7
- const e2eTestRoot = path.resolve(__dir, '../../../../../packages/e2e-tests');
8
-
9
- describe('dependencies', () => {
10
- describe('findRootSvelteDependencies', () => {
11
- it('should find svelte dependencies in packages/e2e-test/hmr', () => {
12
- const deps = findRootSvelteDependencies(path.resolve('packages/e2e-tests/hmr'));
13
- expect(deps).toHaveLength(1);
14
- expect(deps[0].name).toBe('e2e-test-dep-svelte-simple');
15
- expect(deps[0].path).toEqual([]);
16
- });
17
- it('should find nested svelte dependencies in packages/e2e-test/package-json-svelte-field', () => {
18
- const deps = findRootSvelteDependencies(path.join(e2eTestRoot, 'package-json-svelte-field'));
19
- expect(deps).toHaveLength(3);
20
- const hybrid = deps.find((dep) => dep.name === 'e2e-test-dep-svelte-hybrid');
21
- expect(hybrid).toBeTruthy();
22
- expect(hybrid.path).toHaveLength(0);
23
- const nested = deps.find((dep) => dep.name === 'e2e-test-dep-svelte-nested');
24
- expect(nested).toBeTruthy();
25
- expect(nested.path).toHaveLength(0);
26
- const simple = deps.find((dep) => dep.name === 'e2e-test-dep-svelte-simple');
27
- expect(simple).toBeTruthy();
28
- expect(simple.path).toHaveLength(1);
29
- expect(simple.path[0]).toBe('e2e-test-dep-svelte-nested');
30
- });
31
- });
32
- describe('needsOptimization', () => {
33
- it('should optimize cjs deps only', () => {
34
- const testDepsPath = path.join(e2eTestRoot, 'dependencies/package.json');
35
- const localRequire = createRequire(testDepsPath);
36
- expect(needsOptimization('e2e-test-dep-cjs-and-esm', localRequire)).toBe(false);
37
- expect(needsOptimization('e2e-test-dep-cjs-only', localRequire)).toBe(true);
38
- expect(needsOptimization('e2e-test-dep-esm-only', localRequire)).toBe(false);
39
- expect(needsOptimization('e2e-test-dep-index-only', localRequire)).toBe(true);
40
- expect(needsOptimization('e2e-test-dep-types-only', localRequire)).toBe(false);
41
- });
42
- });
43
- });