@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.
- package/dist/index.cjs +318 -394
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +302 -376
- package/dist/index.js.map +1 -1
- package/package.json +8 -6
- package/src/index.ts +27 -14
- package/src/utils/__tests__/svelte-version.spec.ts +102 -0
- package/src/utils/compile.ts +4 -3
- package/src/utils/dependencies.ts +17 -173
- package/src/utils/esbuild.ts +7 -1
- package/src/utils/options.ts +142 -143
- package/src/utils/preprocess.ts +33 -26
- package/src/utils/resolve.ts +6 -7
- package/src/utils/svelte-version.ts +37 -0
- package/src/utils/__tests__/dependencies.spec.ts +0 -43
package/src/utils/options.ts
CHANGED
|
@@ -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:
|
|
186
|
+
injectCss: css === true || css === 'injected',
|
|
178
187
|
partialAccept: !!viteConfig.experimental?.hmrPartialAccept
|
|
179
188
|
},
|
|
180
189
|
compilerOptions: {
|
|
181
|
-
css
|
|
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
|
-
|
|
220
|
+
const css = options.compilerOptions.css;
|
|
221
|
+
if (css === true || css === 'injected') {
|
|
222
|
+
const forcedCss = cssAsString ? 'external' : false;
|
|
212
223
|
log.warn(
|
|
213
|
-
|
|
224
|
+
`hmr and emitCss are enabled but compilerOptions.css is ${css}, forcing it to ${forcedCss}`
|
|
214
225
|
);
|
|
215
|
-
options.compilerOptions.css =
|
|
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
|
-
|
|
239
|
+
const css = options.compilerOptions.css;
|
|
240
|
+
if (!(css === true || css === 'injected')) {
|
|
241
|
+
const forcedCss = cssAsString ? 'injected' : true;
|
|
229
242
|
log.warn(
|
|
230
|
-
|
|
243
|
+
`hmr with emitCss disabled requires compilerOptions.css to be enabled, forcing it to ${forcedCss}`
|
|
231
244
|
);
|
|
232
|
-
options.compilerOptions.css =
|
|
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
|
-
|
|
278
|
-
|
|
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
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
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
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
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
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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) {
|
package/src/utils/preprocess.ts
CHANGED
|
@@ -1,14 +1,8 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
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
|
|
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
|
|
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 (
|
|
62
|
-
|
|
44
|
+
if (result.map?.sources?.[0] === moduleId) {
|
|
45
|
+
result.map.sources[0] = path.basename(filename);
|
|
63
46
|
}
|
|
64
47
|
return {
|
|
65
|
-
code:
|
|
66
|
-
map:
|
|
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 }) {
|
package/src/utils/resolve.ts
CHANGED
|
@@ -1,25 +1,24 @@
|
|
|
1
1
|
import path from 'path';
|
|
2
|
-
import { builtinModules
|
|
3
|
-
import {
|
|
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
|
-
!
|
|
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
|
|
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
|
-
});
|