@sveltejs/vite-plugin-svelte 2.4.6 → 3.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 +11 -11
- package/src/handle-hot-update.js +15 -5
- package/src/index.d.ts +15 -13
- package/src/index.js +16 -102
- package/src/preprocess.js +6 -7
- package/src/utils/compile.js +37 -21
- package/src/utils/constants.js +3 -8
- package/src/utils/error.js +76 -0
- package/src/utils/esbuild.js +7 -7
- package/src/utils/load-raw.js +2 -2
- package/src/utils/load-svelte-config.js +3 -2
- package/src/utils/log.js +9 -3
- package/src/utils/options.js +31 -9
- package/src/utils/preprocess.js +57 -2
- package/src/utils/vite-plugin-svelte-cache.js +0 -41
- package/src/utils/watch.js +4 -2
- package/src/utils/resolve.js +0 -66
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sveltejs/vite-plugin-svelte",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0-next.1",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"author": "dominikg",
|
|
6
6
|
"files": [
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"./package.json": "./package.json"
|
|
17
17
|
},
|
|
18
18
|
"engines": {
|
|
19
|
-
"node": "^
|
|
19
|
+
"node": "^18.0.0 || >=20"
|
|
20
20
|
},
|
|
21
21
|
"repository": {
|
|
22
22
|
"type": "git",
|
|
@@ -34,23 +34,23 @@
|
|
|
34
34
|
},
|
|
35
35
|
"homepage": "https://github.com/sveltejs/vite-plugin-svelte#readme",
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@sveltejs/vite-plugin-svelte-inspector": "^
|
|
37
|
+
"@sveltejs/vite-plugin-svelte-inspector": "^2.0.0-next.0 || ^2.0.0",
|
|
38
38
|
"debug": "^4.3.4",
|
|
39
39
|
"deepmerge": "^4.3.1",
|
|
40
40
|
"kleur": "^4.1.5",
|
|
41
|
-
"magic-string": "^0.30.
|
|
41
|
+
"magic-string": "^0.30.5",
|
|
42
42
|
"svelte-hmr": "^0.15.3",
|
|
43
|
-
"vitefu": "^0.2.
|
|
43
|
+
"vitefu": "^0.2.5"
|
|
44
44
|
},
|
|
45
45
|
"peerDependencies": {
|
|
46
|
-
"svelte": "^
|
|
47
|
-
"vite": "^
|
|
46
|
+
"svelte": "^4.0.0",
|
|
47
|
+
"vite": "^5.0.0-beta.1 || ^5.0.0"
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
|
50
|
-
"@types/debug": "^4.1.
|
|
51
|
-
"esbuild": "^0.19.
|
|
52
|
-
"svelte": "^4.2.
|
|
53
|
-
"vite": "^
|
|
50
|
+
"@types/debug": "^4.1.9",
|
|
51
|
+
"esbuild": "^0.19.4",
|
|
52
|
+
"svelte": "^4.2.1",
|
|
53
|
+
"vite": "^5.0.0-beta.7"
|
|
54
54
|
},
|
|
55
55
|
"scripts": {
|
|
56
56
|
"check:publint": "publint --strict",
|
package/src/handle-hot-update.js
CHANGED
|
@@ -14,7 +14,11 @@ import { toRollupError } from './utils/error.js';
|
|
|
14
14
|
export async function handleHotUpdate(compileSvelte, ctx, svelteRequest, cache, options) {
|
|
15
15
|
if (!cache.has(svelteRequest)) {
|
|
16
16
|
// file hasn't been requested yet (e.g. async component)
|
|
17
|
-
log.debug(
|
|
17
|
+
log.debug(
|
|
18
|
+
`handleHotUpdate called before initial transform for ${svelteRequest.id}`,
|
|
19
|
+
undefined,
|
|
20
|
+
'hmr'
|
|
21
|
+
);
|
|
18
22
|
return;
|
|
19
23
|
}
|
|
20
24
|
const { read, server, modules } = ctx;
|
|
@@ -39,7 +43,7 @@ export async function handleHotUpdate(compileSvelte, ctx, svelteRequest, cache,
|
|
|
39
43
|
if (cssIdx > -1) {
|
|
40
44
|
const cssUpdated = cssChanged(cachedCss, compileData.compiled.css);
|
|
41
45
|
if (!cssUpdated) {
|
|
42
|
-
log.debug(`skipping unchanged css for ${svelteRequest.cssId}
|
|
46
|
+
log.debug(`skipping unchanged css for ${svelteRequest.cssId}`, undefined, 'hmr');
|
|
43
47
|
affectedModules.splice(cssIdx, 1);
|
|
44
48
|
}
|
|
45
49
|
}
|
|
@@ -47,7 +51,7 @@ export async function handleHotUpdate(compileSvelte, ctx, svelteRequest, cache,
|
|
|
47
51
|
if (jsIdx > -1) {
|
|
48
52
|
const jsUpdated = jsChanged(cachedJS, compileData.compiled.js, svelteRequest.filename);
|
|
49
53
|
if (!jsUpdated) {
|
|
50
|
-
log.debug(`skipping unchanged js for ${svelteRequest.id}
|
|
54
|
+
log.debug(`skipping unchanged js for ${svelteRequest.id}`, undefined, 'hmr');
|
|
51
55
|
affectedModules.splice(jsIdx, 1);
|
|
52
56
|
// transform won't be called, log warnings here
|
|
53
57
|
logCompilerWarnings(svelteRequest, compileData.compiled.warnings, options);
|
|
@@ -57,14 +61,20 @@ export async function handleHotUpdate(compileSvelte, ctx, svelteRequest, cache,
|
|
|
57
61
|
// TODO is this enough? see also: https://github.com/vitejs/vite/issues/2274
|
|
58
62
|
const ssrModulesToInvalidate = affectedModules.filter((m) => !!m.ssrTransformResult);
|
|
59
63
|
if (ssrModulesToInvalidate.length > 0) {
|
|
60
|
-
log.debug(
|
|
64
|
+
log.debug(
|
|
65
|
+
`invalidating modules ${ssrModulesToInvalidate.map((m) => m.id).join(', ')}`,
|
|
66
|
+
undefined,
|
|
67
|
+
'hmr'
|
|
68
|
+
);
|
|
61
69
|
ssrModulesToInvalidate.forEach((moduleNode) => server.moduleGraph.invalidateModule(moduleNode));
|
|
62
70
|
}
|
|
63
71
|
if (affectedModules.length > 0) {
|
|
64
72
|
log.debug(
|
|
65
73
|
`handleHotUpdate for ${svelteRequest.id} result: ${affectedModules
|
|
66
74
|
.map((m) => m.id)
|
|
67
|
-
.join(', ')}
|
|
75
|
+
.join(', ')}`,
|
|
76
|
+
undefined,
|
|
77
|
+
'hmr'
|
|
68
78
|
);
|
|
69
79
|
}
|
|
70
80
|
return affectedModules;
|
package/src/index.d.ts
CHANGED
|
@@ -121,20 +121,7 @@ interface SvelteOptions {
|
|
|
121
121
|
* @see https://svelte.dev/docs#svelte_compile
|
|
122
122
|
*/
|
|
123
123
|
compilerOptions?: Omit<CompileOptions, 'filename' | 'format' | 'generate'>;
|
|
124
|
-
/**
|
|
125
|
-
* Handles warning emitted from the Svelte compiler
|
|
126
|
-
*/
|
|
127
|
-
onwarn?: (warning: Warning, defaultHandler?: (warning: Warning) => void) => void;
|
|
128
|
-
/**
|
|
129
|
-
* Options for vite-plugin-svelte
|
|
130
|
-
*/
|
|
131
|
-
vitePlugin?: PluginOptions;
|
|
132
|
-
}
|
|
133
124
|
|
|
134
|
-
/**
|
|
135
|
-
* These options are considered experimental and breaking changes to them can occur in any release
|
|
136
|
-
*/
|
|
137
|
-
interface ExperimentalOptions {
|
|
138
125
|
/**
|
|
139
126
|
* A function to update `compilerOptions` before compilation
|
|
140
127
|
*
|
|
@@ -159,6 +146,21 @@ interface ExperimentalOptions {
|
|
|
159
146
|
code: string;
|
|
160
147
|
compileOptions: Partial<CompileOptions>;
|
|
161
148
|
}) => Promise<Partial<CompileOptions> | void> | Partial<CompileOptions> | void;
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Handles warning emitted from the Svelte compiler
|
|
152
|
+
*/
|
|
153
|
+
onwarn?: (warning: Warning, defaultHandler?: (warning: Warning) => void) => void;
|
|
154
|
+
/**
|
|
155
|
+
* Options for vite-plugin-svelte
|
|
156
|
+
*/
|
|
157
|
+
vitePlugin?: PluginOptions;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* These options are considered experimental and breaking changes to them can occur in any release
|
|
162
|
+
*/
|
|
163
|
+
interface ExperimentalOptions {
|
|
162
164
|
/**
|
|
163
165
|
* send a websocket message with svelte compiler warnings during dev
|
|
164
166
|
*
|
package/src/index.js
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
|
-
import { version as viteVersion } from 'vite';
|
|
3
2
|
|
|
4
3
|
import { svelteInspector } from '@sveltejs/vite-plugin-svelte-inspector';
|
|
5
4
|
|
|
6
|
-
import { isDepExcluded } from 'vitefu';
|
|
7
5
|
import { handleHotUpdate } from './handle-hot-update.js';
|
|
8
6
|
import { log, logCompilerWarnings } from './utils/log.js';
|
|
9
7
|
import { createCompileSvelte } from './utils/compile.js';
|
|
@@ -17,16 +15,10 @@ import {
|
|
|
17
15
|
} from './utils/options.js';
|
|
18
16
|
|
|
19
17
|
import { ensureWatchedFile, setupWatchers } from './utils/watch.js';
|
|
20
|
-
import { resolveViaPackageJsonSvelte } from './utils/resolve.js';
|
|
21
|
-
|
|
22
18
|
import { toRollupError } from './utils/error.js';
|
|
23
19
|
import { saveSvelteMetadata } from './utils/optimizer.js';
|
|
24
20
|
import { VitePluginSvelteCache } from './utils/vite-plugin-svelte-cache.js';
|
|
25
21
|
import { loadRaw } from './utils/load-raw.js';
|
|
26
|
-
import { FAQ_LINK_CONFLICTS_IN_SVELTE_RESOLVE } from './utils/constants.js';
|
|
27
|
-
import { isSvelte3 } from './utils/svelte-version.js';
|
|
28
|
-
|
|
29
|
-
const isVite4_0 = viteVersion.startsWith('4.0');
|
|
30
22
|
|
|
31
23
|
/** @type {import('./index.d.ts').svelte} */
|
|
32
24
|
export function svelte(inlineOptions) {
|
|
@@ -42,15 +34,9 @@ export function svelte(inlineOptions) {
|
|
|
42
34
|
let options;
|
|
43
35
|
/** @type {import('vite').ResolvedConfig} */
|
|
44
36
|
let viteConfig;
|
|
45
|
-
|
|
46
37
|
/** @type {import('./types/compile.d.ts').CompileSvelte} */
|
|
47
38
|
let compileSvelte;
|
|
48
39
|
/* eslint-enable no-unused-vars */
|
|
49
|
-
|
|
50
|
-
/** @type {Promise<import('vite').Rollup.PartialResolvedId | null>} */
|
|
51
|
-
let resolvedSvelteSSR;
|
|
52
|
-
/** @type {Set<string>} */
|
|
53
|
-
let packagesWithResolveWarnings;
|
|
54
40
|
/** @type {import('./types/plugin-api.d.ts').PluginAPI} */
|
|
55
41
|
const api = {};
|
|
56
42
|
/** @type {import('vite').Plugin[]} */
|
|
@@ -71,7 +57,7 @@ export function svelte(inlineOptions) {
|
|
|
71
57
|
options = await preResolveOptions(inlineOptions, config, configEnv);
|
|
72
58
|
// extra vite config
|
|
73
59
|
const extraViteConfig = await buildExtraViteConfig(options, config);
|
|
74
|
-
log.debug('additional vite config', extraViteConfig);
|
|
60
|
+
log.debug('additional vite config', extraViteConfig, 'config');
|
|
75
61
|
return extraViteConfig;
|
|
76
62
|
},
|
|
77
63
|
|
|
@@ -83,11 +69,10 @@ export function svelte(inlineOptions) {
|
|
|
83
69
|
viteConfig = config;
|
|
84
70
|
// TODO deep clone to avoid mutability from outside?
|
|
85
71
|
api.options = options;
|
|
86
|
-
log.debug('resolved options', options);
|
|
72
|
+
log.debug('resolved options', options, 'config');
|
|
87
73
|
},
|
|
88
74
|
|
|
89
75
|
async buildStart() {
|
|
90
|
-
packagesWithResolveWarnings = new Set();
|
|
91
76
|
if (!options.prebundleSvelteLibraries) return;
|
|
92
77
|
const isSvelteMetadataChanged = await saveSvelteMetadata(viteConfig.cacheDir, options);
|
|
93
78
|
if (isSvelteMetadataChanged) {
|
|
@@ -108,18 +93,24 @@ export function svelte(inlineOptions) {
|
|
|
108
93
|
if (svelteRequest) {
|
|
109
94
|
const { filename, query, raw } = svelteRequest;
|
|
110
95
|
if (raw) {
|
|
111
|
-
|
|
96
|
+
const code = await loadRaw(svelteRequest, compileSvelte, options);
|
|
97
|
+
// prevent vite from injecting sourcemaps in the results.
|
|
98
|
+
return {
|
|
99
|
+
code,
|
|
100
|
+
map: {
|
|
101
|
+
mappings: ''
|
|
102
|
+
}
|
|
103
|
+
};
|
|
112
104
|
} else {
|
|
113
105
|
if (query.svelte && query.type === 'style') {
|
|
114
106
|
const css = cache.getCSS(svelteRequest);
|
|
115
107
|
if (css) {
|
|
116
|
-
log.debug(`load returns css for ${filename}`);
|
|
117
108
|
return css;
|
|
118
109
|
}
|
|
119
110
|
}
|
|
120
111
|
// prevent vite asset plugin from loading files as url that should be compiled in transform
|
|
121
112
|
if (viteConfig.assetsInclude(filename)) {
|
|
122
|
-
log.debug(`load returns raw content for ${filename}
|
|
113
|
+
log.debug(`load returns raw content for ${filename}`, undefined, 'load');
|
|
123
114
|
return fs.readFileSync(filename, 'utf-8');
|
|
124
115
|
}
|
|
125
116
|
}
|
|
@@ -133,78 +124,12 @@ export function svelte(inlineOptions) {
|
|
|
133
124
|
if (svelteRequest.query.type === 'style' && !svelteRequest.raw) {
|
|
134
125
|
// return cssId with root prefix so postcss pipeline of vite finds the directory correctly
|
|
135
126
|
// see https://github.com/sveltejs/vite-plugin-svelte/issues/14
|
|
136
|
-
log.debug(
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
// TODO: remove this after bumping peerDep on Vite to 4.1+ or Svelte to 4.0+
|
|
142
|
-
if (isVite4_0 && isSvelte3 && ssr && importee === 'svelte') {
|
|
143
|
-
if (!resolvedSvelteSSR) {
|
|
144
|
-
resolvedSvelteSSR = this.resolve('svelte/ssr', undefined, { skipSelf: true }).then(
|
|
145
|
-
(svelteSSR) => {
|
|
146
|
-
log.debug('resolved svelte to svelte/ssr');
|
|
147
|
-
return svelteSSR;
|
|
148
|
-
},
|
|
149
|
-
(err) => {
|
|
150
|
-
log.debug(
|
|
151
|
-
'failed to resolve svelte to svelte/ssr. Update svelte to a version that exports it',
|
|
152
|
-
err
|
|
153
|
-
);
|
|
154
|
-
return null; // returning null here leads to svelte getting resolved regularly
|
|
155
|
-
}
|
|
127
|
+
log.debug(
|
|
128
|
+
`resolveId resolved virtual css module ${svelteRequest.cssId}`,
|
|
129
|
+
undefined,
|
|
130
|
+
'resolve'
|
|
156
131
|
);
|
|
157
|
-
|
|
158
|
-
return resolvedSvelteSSR;
|
|
159
|
-
}
|
|
160
|
-
//@ts-expect-error scan
|
|
161
|
-
const scan = !!opts?.scan; // scanner phase of optimizeDeps
|
|
162
|
-
const isPrebundled =
|
|
163
|
-
options.prebundleSvelteLibraries &&
|
|
164
|
-
viteConfig.optimizeDeps?.disabled !== true &&
|
|
165
|
-
viteConfig.optimizeDeps?.disabled !== (options.isBuild ? 'build' : 'dev') &&
|
|
166
|
-
!isDepExcluded(importee, viteConfig.optimizeDeps?.exclude ?? []);
|
|
167
|
-
// for prebundled libraries we let vite resolve the prebundling result
|
|
168
|
-
// for ssr, during scanning and non-prebundled, we do it
|
|
169
|
-
if (ssr || scan || !isPrebundled) {
|
|
170
|
-
try {
|
|
171
|
-
const isFirstResolve = !cache.hasResolvedSvelteField(importee, importer);
|
|
172
|
-
const resolved = await resolveViaPackageJsonSvelte(importee, importer, cache);
|
|
173
|
-
if (isFirstResolve && resolved) {
|
|
174
|
-
const packageInfo = await cache.getPackageInfo(resolved);
|
|
175
|
-
const packageVersion = `${packageInfo.name}@${packageInfo.version}`;
|
|
176
|
-
log.debug.once(
|
|
177
|
-
`resolveId resolved ${importee} to ${resolved} via package.json svelte field of ${packageVersion}`
|
|
178
|
-
);
|
|
179
|
-
|
|
180
|
-
try {
|
|
181
|
-
const viteResolved = (
|
|
182
|
-
await this.resolve(importee, importer, { ...opts, skipSelf: true })
|
|
183
|
-
)?.id;
|
|
184
|
-
if (resolved !== viteResolved) {
|
|
185
|
-
packagesWithResolveWarnings.add(packageVersion);
|
|
186
|
-
log.debug.enabled &&
|
|
187
|
-
log.debug.once(
|
|
188
|
-
`resolve difference for ${packageVersion} ${importee} - svelte: "${resolved}", vite: "${viteResolved}"`
|
|
189
|
-
);
|
|
190
|
-
}
|
|
191
|
-
} catch (e) {
|
|
192
|
-
packagesWithResolveWarnings.add(packageVersion);
|
|
193
|
-
log.debug.enabled &&
|
|
194
|
-
log.debug.once(
|
|
195
|
-
`resolve error for ${packageVersion} ${importee} - svelte: "${resolved}", vite: ERROR`,
|
|
196
|
-
e
|
|
197
|
-
);
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
return resolved;
|
|
201
|
-
} catch (e) {
|
|
202
|
-
log.debug.once(
|
|
203
|
-
`error trying to resolve ${importee} from ${importer} via package.json svelte field `,
|
|
204
|
-
e
|
|
205
|
-
);
|
|
206
|
-
// this error most likely happens due to non-svelte related importee/importers so swallow it here
|
|
207
|
-
// in case it really way a svelte library, users will notice anyway. (lib not working due to failed resolve)
|
|
132
|
+
return svelteRequest.cssId;
|
|
208
133
|
}
|
|
209
134
|
}
|
|
210
135
|
},
|
|
@@ -235,7 +160,6 @@ export function svelte(inlineOptions) {
|
|
|
235
160
|
}
|
|
236
161
|
}
|
|
237
162
|
}
|
|
238
|
-
log.debug(`transform returns compiled js for ${svelteRequest.filename}`);
|
|
239
163
|
return {
|
|
240
164
|
...compileData.compiled.js,
|
|
241
165
|
meta: {
|
|
@@ -257,16 +181,6 @@ export function svelte(inlineOptions) {
|
|
|
257
181
|
},
|
|
258
182
|
async buildEnd() {
|
|
259
183
|
await options.stats?.finishAll();
|
|
260
|
-
if (
|
|
261
|
-
!options.experimental?.disableSvelteResolveWarnings &&
|
|
262
|
-
packagesWithResolveWarnings?.size > 0
|
|
263
|
-
) {
|
|
264
|
-
log.warn(
|
|
265
|
-
`WARNING: The following packages use a svelte resolve configuration in package.json that has conflicting results and is going to cause problems future.\n\n${[
|
|
266
|
-
...packagesWithResolveWarnings
|
|
267
|
-
].join('\n')}\n\nPlease see ${FAQ_LINK_CONFLICTS_IN_SVELTE_RESOLVE} for details.`
|
|
268
|
-
);
|
|
269
|
-
}
|
|
270
184
|
}
|
|
271
185
|
},
|
|
272
186
|
svelteInspector()
|
package/src/preprocess.js
CHANGED
|
@@ -1,19 +1,18 @@
|
|
|
1
|
-
import { preprocessCSS, resolveConfig, transformWithEsbuild } from 'vite';
|
|
1
|
+
import { isCSSRequest, preprocessCSS, resolveConfig, transformWithEsbuild } from 'vite';
|
|
2
2
|
import { mapToRelative, removeLangSuffix } from './utils/sourcemaps.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* @typedef {(code: string, filename: string) => Promise<{ code: string; map?: any; deps?: Set<string> }>} CssTransform
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
const supportedStyleLangs = ['css', 'less', 'sass', 'scss', 'styl', 'stylus', 'postcss', 'sss'];
|
|
9
8
|
const supportedScriptLangs = ['ts'];
|
|
10
9
|
|
|
11
|
-
export const lang_sep = '.vite-preprocess
|
|
10
|
+
export const lang_sep = '.vite-preprocess';
|
|
12
11
|
|
|
13
12
|
/** @type {import('./index.d.ts').vitePreprocess} */
|
|
14
13
|
export function vitePreprocess(opts) {
|
|
15
14
|
/** @type {import('svelte/types/compiler/preprocess').PreprocessorGroup} */
|
|
16
|
-
const preprocessor = {};
|
|
15
|
+
const preprocessor = { name: 'vite-preprocess' };
|
|
17
16
|
if (opts?.script !== false) {
|
|
18
17
|
preprocessor.script = viteScript().script;
|
|
19
18
|
}
|
|
@@ -63,8 +62,8 @@ function viteStyle(config = {}) {
|
|
|
63
62
|
let transform;
|
|
64
63
|
/** @type {import('svelte/types/compiler/preprocess').Preprocessor} */
|
|
65
64
|
const style = async ({ attributes, content, filename = '' }) => {
|
|
66
|
-
const
|
|
67
|
-
if (!
|
|
65
|
+
const ext = attributes.lang ? `.${attributes.lang}` : '.css';
|
|
66
|
+
if (attributes.lang && !isCSSRequest(ext)) return;
|
|
68
67
|
if (!transform) {
|
|
69
68
|
/** @type {import('vite').ResolvedConfig} */
|
|
70
69
|
let resolvedConfig;
|
|
@@ -82,7 +81,7 @@ function viteStyle(config = {}) {
|
|
|
82
81
|
}
|
|
83
82
|
transform = getCssTransformFn(resolvedConfig);
|
|
84
83
|
}
|
|
85
|
-
const suffix = `${lang_sep}${
|
|
84
|
+
const suffix = `${lang_sep}${ext}`;
|
|
86
85
|
const moduleId = `${filename}${suffix}`;
|
|
87
86
|
const { code, map, deps } = await transform(content, moduleId);
|
|
88
87
|
removeLangSuffix(map, suffix);
|
package/src/utils/compile.js
CHANGED
|
@@ -4,13 +4,15 @@ import { createMakeHot } from 'svelte-hmr';
|
|
|
4
4
|
import { safeBase64Hash } from './hash.js';
|
|
5
5
|
import { log } from './log.js';
|
|
6
6
|
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
checkPreprocessDependencies,
|
|
9
|
+
createInjectScopeEverythingRulePreprocessorGroup
|
|
10
|
+
} from './preprocess.js';
|
|
8
11
|
import { mapToRelative } from './sourcemaps.js';
|
|
12
|
+
import { enhanceCompileError } from './error.js';
|
|
9
13
|
|
|
10
14
|
const scriptLangRE = /<script [^>]*lang=["']?([^"' >]+)["']?[^>]*>/;
|
|
11
15
|
|
|
12
|
-
import { isSvelte3 } from './svelte-version.js';
|
|
13
|
-
|
|
14
16
|
/**
|
|
15
17
|
* @param {Function} [makeHot]
|
|
16
18
|
* @returns {import('../types/compile.d.ts').CompileSvelte}
|
|
@@ -23,7 +25,10 @@ export const _createCompileSvelte = (makeHot) => {
|
|
|
23
25
|
return async function compileSvelte(svelteRequest, code, options) {
|
|
24
26
|
const { filename, normalizedFilename, cssId, ssr, raw } = svelteRequest;
|
|
25
27
|
const { emitCss = true } = options;
|
|
28
|
+
/** @type {string[]} */
|
|
26
29
|
const dependencies = [];
|
|
30
|
+
/** @type {import('svelte/types/compiler/interfaces').Warning[]} */
|
|
31
|
+
const warnings = [];
|
|
27
32
|
|
|
28
33
|
if (options.stats) {
|
|
29
34
|
if (options.isBuild) {
|
|
@@ -55,13 +60,9 @@ export const _createCompileSvelte = (makeHot) => {
|
|
|
55
60
|
filename,
|
|
56
61
|
generate: ssr ? 'ssr' : 'dom'
|
|
57
62
|
};
|
|
58
|
-
|
|
59
|
-
// @ts-ignore
|
|
60
|
-
compileOptions.format = 'esm';
|
|
61
|
-
}
|
|
63
|
+
|
|
62
64
|
if (options.hot && options.emitCss) {
|
|
63
65
|
const hash = `s-${safeBase64Hash(normalizedFilename)}`;
|
|
64
|
-
log.debug(`setting cssHash ${hash} for ${normalizedFilename}`);
|
|
65
66
|
compileOptions.cssHash = () => hash;
|
|
66
67
|
}
|
|
67
68
|
if (ssr && compileOptions.enableSourcemap !== false) {
|
|
@@ -92,7 +93,16 @@ export const _createCompileSvelte = (makeHot) => {
|
|
|
92
93
|
throw e;
|
|
93
94
|
}
|
|
94
95
|
|
|
95
|
-
if (preprocessed.dependencies)
|
|
96
|
+
if (preprocessed.dependencies?.length) {
|
|
97
|
+
const checked = checkPreprocessDependencies(filename, preprocessed.dependencies);
|
|
98
|
+
if (checked.warnings.length) {
|
|
99
|
+
warnings.push(...checked.warnings);
|
|
100
|
+
}
|
|
101
|
+
if (checked.dependencies.length) {
|
|
102
|
+
dependencies.push(...checked.dependencies);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
96
106
|
if (preprocessed.map) compileOptions.sourcemap = preprocessed.map;
|
|
97
107
|
}
|
|
98
108
|
if (typeof preprocessed?.map === 'object') {
|
|
@@ -105,14 +115,16 @@ export const _createCompileSvelte = (makeHot) => {
|
|
|
105
115
|
};
|
|
106
116
|
}
|
|
107
117
|
const finalCode = preprocessed ? preprocessed.code : code;
|
|
108
|
-
const dynamicCompileOptions = await options
|
|
118
|
+
const dynamicCompileOptions = await options?.dynamicCompileOptions?.({
|
|
109
119
|
filename,
|
|
110
120
|
code: finalCode,
|
|
111
121
|
compileOptions
|
|
112
122
|
});
|
|
113
123
|
if (dynamicCompileOptions && log.debug.enabled) {
|
|
114
124
|
log.debug(
|
|
115
|
-
`dynamic compile options for ${filename}: ${JSON.stringify(dynamicCompileOptions)}
|
|
125
|
+
`dynamic compile options for ${filename}: ${JSON.stringify(dynamicCompileOptions)}`,
|
|
126
|
+
undefined,
|
|
127
|
+
'compile'
|
|
116
128
|
);
|
|
117
129
|
}
|
|
118
130
|
const finalCompileOptions = dynamicCompileOptions
|
|
@@ -123,22 +135,26 @@ export const _createCompileSvelte = (makeHot) => {
|
|
|
123
135
|
: compileOptions;
|
|
124
136
|
|
|
125
137
|
const endStat = stats?.start(filename);
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
/\/\* [@#]__PURE__ \*\/(\s*)$/gm,
|
|
134
|
-
' $1'
|
|
135
|
-
);
|
|
138
|
+
/** @type {import('svelte/types/compiler/interfaces').CompileResult} */
|
|
139
|
+
let compiled;
|
|
140
|
+
try {
|
|
141
|
+
compiled = compile(finalCode, finalCompileOptions);
|
|
142
|
+
} catch (e) {
|
|
143
|
+
enhanceCompileError(e, code, preprocessors);
|
|
144
|
+
throw e;
|
|
136
145
|
}
|
|
146
|
+
|
|
137
147
|
if (endStat) {
|
|
138
148
|
endStat();
|
|
139
149
|
}
|
|
140
150
|
mapToRelative(compiled.js?.map, filename);
|
|
141
151
|
mapToRelative(compiled.css?.map, filename);
|
|
152
|
+
if (warnings.length) {
|
|
153
|
+
if (!compiled.warnings) {
|
|
154
|
+
compiled.warnings = [];
|
|
155
|
+
}
|
|
156
|
+
compiled.warnings.push(...warnings);
|
|
157
|
+
}
|
|
142
158
|
if (!raw) {
|
|
143
159
|
// wire css import and code for hmr
|
|
144
160
|
const hasCss = compiled.css?.code?.trim().length > 0;
|
package/src/utils/constants.js
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { isSvelte3 } from './svelte-version.js';
|
|
2
|
-
|
|
3
1
|
export const VITE_RESOLVE_MAIN_FIELDS = ['module', 'jsnext:main', 'jsnext'];
|
|
4
2
|
|
|
5
3
|
export const SVELTE_RESOLVE_MAIN_FIELDS = ['svelte'];
|
|
@@ -8,16 +6,13 @@ export const SVELTE_IMPORTS = [
|
|
|
8
6
|
'svelte/animate',
|
|
9
7
|
'svelte/easing',
|
|
10
8
|
'svelte/internal',
|
|
9
|
+
'svelte/internal/disclose-version',
|
|
11
10
|
'svelte/motion',
|
|
12
11
|
'svelte/ssr',
|
|
13
12
|
'svelte/store',
|
|
14
13
|
'svelte/transition',
|
|
15
14
|
'svelte'
|
|
16
15
|
];
|
|
17
|
-
// TODO add to global list after dropping svelte 3
|
|
18
|
-
if (!isSvelte3) {
|
|
19
|
-
SVELTE_IMPORTS.push('svelte/internal/disclose-version');
|
|
20
|
-
}
|
|
21
16
|
|
|
22
17
|
export const SVELTE_HMR_IMPORTS = [
|
|
23
18
|
'svelte-hmr/runtime/hot-api-esm.js',
|
|
@@ -27,5 +22,5 @@ export const SVELTE_HMR_IMPORTS = [
|
|
|
27
22
|
|
|
28
23
|
export const SVELTE_EXPORT_CONDITIONS = ['svelte'];
|
|
29
24
|
|
|
30
|
-
export const
|
|
31
|
-
'https://github.com/sveltejs/vite-plugin-svelte/blob/main/docs/faq.md#
|
|
25
|
+
export const FAQ_LINK_MISSING_EXPORTS_CONDITION =
|
|
26
|
+
'https://github.com/sveltejs/vite-plugin-svelte/blob/main/docs/faq.md#missing-exports-condition';
|
package/src/utils/error.js
CHANGED
|
@@ -100,3 +100,79 @@ function formatFrameForVite(frame) {
|
|
|
100
100
|
.map((line) => (line.match(/^\s+\^/) ? ' ' + line : ' ' + line.replace(':', ' | ')))
|
|
101
101
|
.join('\n');
|
|
102
102
|
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* @param {import('svelte/types/compiler/interfaces').Warning & Error} err a svelte compiler error, which is a mix of Warning and an error
|
|
106
|
+
* @param {string} originalCode
|
|
107
|
+
* @param {import('../index.js').Arrayable<import('svelte/types/compiler/preprocess').PreprocessorGroup>} [preprocessors]
|
|
108
|
+
*/
|
|
109
|
+
export function enhanceCompileError(err, originalCode, preprocessors) {
|
|
110
|
+
preprocessors = arraify(preprocessors ?? []);
|
|
111
|
+
|
|
112
|
+
/** @type {string[]} */
|
|
113
|
+
const additionalMessages = [];
|
|
114
|
+
|
|
115
|
+
// Handle incorrect TypeScript usage
|
|
116
|
+
if (err.code === 'parse-error') {
|
|
117
|
+
// Reference from Svelte: https://github.com/sveltejs/svelte/blob/800f6c076be5dd87dd4d2e9d66c59b973d54d84b/packages/svelte/src/compiler/preprocess/index.js#L262
|
|
118
|
+
const scriptRe = /<script(\s[^]*?)?(?:>([^]*?)<\/script>|\/>)/gi;
|
|
119
|
+
const errIndex = err.pos ?? -1;
|
|
120
|
+
|
|
121
|
+
let m;
|
|
122
|
+
while ((m = scriptRe.exec(originalCode))) {
|
|
123
|
+
const matchStart = m.index;
|
|
124
|
+
const matchEnd = matchStart + m[0].length;
|
|
125
|
+
const isErrorInScript = matchStart <= errIndex && errIndex <= matchEnd;
|
|
126
|
+
if (isErrorInScript) {
|
|
127
|
+
// Warn missing lang="ts"
|
|
128
|
+
const hasLangTs = m[1]?.includes('lang="ts"');
|
|
129
|
+
if (!hasLangTs) {
|
|
130
|
+
additionalMessages.push('Did you forget to add lang="ts" to your script tag?');
|
|
131
|
+
}
|
|
132
|
+
// Warn missing script preprocessor
|
|
133
|
+
if (preprocessors.every((p) => p.script == null)) {
|
|
134
|
+
const preprocessorType = hasLangTs ? 'TypeScript' : 'script';
|
|
135
|
+
additionalMessages.push(
|
|
136
|
+
`Did you forget to add a ${preprocessorType} preprocessor? See https://github.com/sveltejs/vite-plugin-svelte/blob/main/docs/preprocess.md for more information.`
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// Handle incorrect CSS preprocessor usage
|
|
144
|
+
if (err.code === 'css-syntax-error') {
|
|
145
|
+
const styleRe = /<style(\s[^]*?)?(?:>([^]*?)<\/style>|\/>)/gi;
|
|
146
|
+
|
|
147
|
+
let m;
|
|
148
|
+
while ((m = styleRe.exec(originalCode))) {
|
|
149
|
+
// Warn missing lang attribute
|
|
150
|
+
if (!m[1]?.includes('lang=')) {
|
|
151
|
+
additionalMessages.push('Did you forget to add a lang attribute to your style tag?');
|
|
152
|
+
}
|
|
153
|
+
// Warn missing style preprocessor
|
|
154
|
+
if (
|
|
155
|
+
preprocessors.every((p) => p.style == null || p.name === 'inject-scope-everything-rule')
|
|
156
|
+
) {
|
|
157
|
+
const preprocessorType = m[1]?.match(/lang="(.+?)"/)?.[1] ?? 'style';
|
|
158
|
+
additionalMessages.push(
|
|
159
|
+
`Did you forget to add a ${preprocessorType} preprocessor? See https://github.com/sveltejs/vite-plugin-svelte/blob/main/docs/preprocess.md for more information.`
|
|
160
|
+
);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
if (additionalMessages.length) {
|
|
166
|
+
err.message += '\n\n- ' + additionalMessages.join('\n- ');
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
return err;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* @param {T | T[]} value
|
|
174
|
+
* @template T
|
|
175
|
+
*/
|
|
176
|
+
function arraify(value) {
|
|
177
|
+
return Array.isArray(value) ? value : [value];
|
|
178
|
+
}
|
package/src/utils/esbuild.js
CHANGED
|
@@ -2,7 +2,6 @@ import { readFileSync } from 'node:fs';
|
|
|
2
2
|
import { compile, preprocess } from 'svelte/compiler';
|
|
3
3
|
import { log } from './log.js';
|
|
4
4
|
import { toESBuildError } from './error.js';
|
|
5
|
-
import { isSvelte3 } from './svelte-version.js';
|
|
6
5
|
|
|
7
6
|
/**
|
|
8
7
|
* @typedef {NonNullable<import('vite').DepOptimizationOptions['esbuildOptions']>} EsbuildOptions
|
|
@@ -67,10 +66,7 @@ async function compileSvelte(options, { filename, code }, statsCollection) {
|
|
|
67
66
|
filename,
|
|
68
67
|
generate: 'dom'
|
|
69
68
|
};
|
|
70
|
-
|
|
71
|
-
// @ts-ignore
|
|
72
|
-
compileOptions.format = 'esm';
|
|
73
|
-
}
|
|
69
|
+
|
|
74
70
|
let preprocessed;
|
|
75
71
|
|
|
76
72
|
if (options.preprocess) {
|
|
@@ -85,14 +81,18 @@ async function compileSvelte(options, { filename, code }, statsCollection) {
|
|
|
85
81
|
|
|
86
82
|
const finalCode = preprocessed ? preprocessed.code : code;
|
|
87
83
|
|
|
88
|
-
const dynamicCompileOptions = await options
|
|
84
|
+
const dynamicCompileOptions = await options?.dynamicCompileOptions?.({
|
|
89
85
|
filename,
|
|
90
86
|
code: finalCode,
|
|
91
87
|
compileOptions
|
|
92
88
|
});
|
|
93
89
|
|
|
94
90
|
if (dynamicCompileOptions && log.debug.enabled) {
|
|
95
|
-
log.debug(
|
|
91
|
+
log.debug(
|
|
92
|
+
`dynamic compile options for ${filename}: ${JSON.stringify(dynamicCompileOptions)}`,
|
|
93
|
+
undefined,
|
|
94
|
+
'compile'
|
|
95
|
+
);
|
|
96
96
|
}
|
|
97
97
|
|
|
98
98
|
const finalCompileOptions = dynamicCompileOptions
|
package/src/utils/load-raw.js
CHANGED
|
@@ -64,7 +64,7 @@ export async function loadRaw(svelteRequest, compileSvelte, options) {
|
|
|
64
64
|
}" combined with direct in ${id}. supported are: ${supportedDirectTypes.join(', ')}`
|
|
65
65
|
);
|
|
66
66
|
}
|
|
67
|
-
log.debug(`load returns direct result for ${id}
|
|
67
|
+
log.debug(`load returns direct result for ${id}`, undefined, 'load');
|
|
68
68
|
let directOutput = result.code;
|
|
69
69
|
if (query.sourcemap && result.map?.toUrl) {
|
|
70
70
|
const map = `sourceMappingURL=${result.map.toUrl()}`;
|
|
@@ -76,7 +76,7 @@ export async function loadRaw(svelteRequest, compileSvelte, options) {
|
|
|
76
76
|
}
|
|
77
77
|
return directOutput;
|
|
78
78
|
} else if (query.raw) {
|
|
79
|
-
log.debug(`load returns raw result for ${id}
|
|
79
|
+
log.debug(`load returns raw result for ${id}`, undefined, 'load');
|
|
80
80
|
return toRawExports(result);
|
|
81
81
|
} else {
|
|
82
82
|
throw new Error(`invalid raw mode in ${id}, supported are raw, direct`);
|
|
@@ -59,7 +59,8 @@ export async function loadSvelteConfig(viteConfig, inlineOptions) {
|
|
|
59
59
|
// identify which require function to use (esm and cjs mode)
|
|
60
60
|
const _require = import.meta.url
|
|
61
61
|
? esmRequire ?? (esmRequire = createRequire(import.meta.url))
|
|
62
|
-
:
|
|
62
|
+
: // eslint-disable-next-line no-undef
|
|
63
|
+
require;
|
|
63
64
|
|
|
64
65
|
// avoid loading cached version on reload
|
|
65
66
|
delete _require.cache[_require.resolve(configFile)];
|
|
@@ -104,7 +105,7 @@ function findConfigToLoad(viteConfig, inlineOptions) {
|
|
|
104
105
|
.map((candidate) => path.resolve(root, candidate))
|
|
105
106
|
.filter((file) => fs.existsSync(file));
|
|
106
107
|
if (existingKnownConfigFiles.length === 0) {
|
|
107
|
-
log.debug(`no svelte config found at ${root}
|
|
108
|
+
log.debug(`no svelte config found at ${root}`, undefined, 'config');
|
|
108
109
|
return;
|
|
109
110
|
} else if (existingKnownConfigFiles.length > 1) {
|
|
110
111
|
log.warn(
|
package/src/utils/log.js
CHANGED
|
@@ -8,7 +8,7 @@ const prefix = 'vite-plugin-svelte';
|
|
|
8
8
|
/** @type {Record<import('../types/log.d.ts').LogLevel, any>} */
|
|
9
9
|
const loggers = {
|
|
10
10
|
debug: {
|
|
11
|
-
log: debug(
|
|
11
|
+
log: debug(`${prefix}`),
|
|
12
12
|
enabled: false,
|
|
13
13
|
isDebug: true
|
|
14
14
|
},
|
|
@@ -65,7 +65,13 @@ function _log(logger, message, payload, namespace) {
|
|
|
65
65
|
return;
|
|
66
66
|
}
|
|
67
67
|
if (logger.isDebug) {
|
|
68
|
-
|
|
68
|
+
let log = logger.log;
|
|
69
|
+
if (namespace) {
|
|
70
|
+
if (!isDebugNamespaceEnabled(namespace)) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
log = logger.log.extend(namespace);
|
|
74
|
+
}
|
|
69
75
|
payload !== undefined ? log(message, payload) : log(message);
|
|
70
76
|
} else {
|
|
71
77
|
logger.log(
|
|
@@ -251,5 +257,5 @@ export function buildExtendedLogMessage(w) {
|
|
|
251
257
|
* @returns {boolean}
|
|
252
258
|
*/
|
|
253
259
|
export function isDebugNamespaceEnabled(namespace) {
|
|
254
|
-
return debug.enabled(
|
|
260
|
+
return debug.enabled(`${prefix}:${namespace}`);
|
|
255
261
|
}
|
package/src/utils/options.js
CHANGED
|
@@ -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
|
+
FAQ_LINK_MISSING_EXPORTS_CONDITION,
|
|
6
7
|
SVELTE_EXPORT_CONDITIONS,
|
|
7
8
|
SVELTE_HMR_IMPORTS,
|
|
8
9
|
SVELTE_IMPORTS,
|
|
@@ -35,6 +36,7 @@ const allowedPluginOptions = new Set([
|
|
|
35
36
|
'disableDependencyReinclusion',
|
|
36
37
|
'prebundleSvelteLibraries',
|
|
37
38
|
'inspector',
|
|
39
|
+
'dynamicCompileOptions',
|
|
38
40
|
'experimental'
|
|
39
41
|
]);
|
|
40
42
|
|
|
@@ -315,13 +317,13 @@ function removeIgnoredOptions(options) {
|
|
|
315
317
|
function handleDeprecatedOptions(options) {
|
|
316
318
|
const experimental = /** @type {Record<string, any>} */ (options.experimental);
|
|
317
319
|
if (experimental) {
|
|
318
|
-
for (const promoted of ['prebundleSvelteLibraries', 'inspector']) {
|
|
320
|
+
for (const promoted of ['prebundleSvelteLibraries', 'inspector', 'dynamicCompileOptions']) {
|
|
319
321
|
if (experimental[promoted]) {
|
|
320
322
|
//@ts-expect-error untyped assign
|
|
321
323
|
options[promoted] = experimental[promoted];
|
|
322
324
|
delete experimental[promoted];
|
|
323
325
|
log.warn(
|
|
324
|
-
`Option "
|
|
326
|
+
`Option "experimental.${promoted}" is no longer experimental and has moved to "${promoted}". Please update your Svelte or Vite config.`
|
|
325
327
|
);
|
|
326
328
|
}
|
|
327
329
|
}
|
|
@@ -428,7 +430,7 @@ export async function buildExtraViteConfig(options, config) {
|
|
|
428
430
|
(options.hot && options.hot.partialAccept !== false)) && // deviate from svelte-hmr, default to true
|
|
429
431
|
config.experimental?.hmrPartialAccept !== false
|
|
430
432
|
) {
|
|
431
|
-
log.debug('enabling "experimental.hmrPartialAccept" in vite config');
|
|
433
|
+
log.debug('enabling "experimental.hmrPartialAccept" in vite config', undefined, 'config');
|
|
432
434
|
extraViteConfig.experimental = { hmrPartialAccept: true };
|
|
433
435
|
}
|
|
434
436
|
validateViteConfig(extraViteConfig, config, options);
|
|
@@ -481,6 +483,7 @@ function validateViteConfig(extraViteConfig, config, options) {
|
|
|
481
483
|
*/
|
|
482
484
|
async function buildExtraConfigForDependencies(options, config) {
|
|
483
485
|
// extra handling for svelte dependencies in the project
|
|
486
|
+
const packagesWithoutSvelteExportsCondition = new Set();
|
|
484
487
|
const depsConfig = await crawlFrameworkPkgs({
|
|
485
488
|
root: options.root,
|
|
486
489
|
isBuild: options.isBuild,
|
|
@@ -496,7 +499,11 @@ async function buildExtraConfigForDependencies(options, config) {
|
|
|
496
499
|
return value;
|
|
497
500
|
});
|
|
498
501
|
}
|
|
499
|
-
|
|
502
|
+
const hasSvelteField = !!pkgJson.svelte;
|
|
503
|
+
if (hasSvelteField && !hasSvelteCondition) {
|
|
504
|
+
packagesWithoutSvelteExportsCondition.add(`${pkgJson.name}@${pkgJson.version}`);
|
|
505
|
+
}
|
|
506
|
+
return hasSvelteCondition || hasSvelteField;
|
|
500
507
|
},
|
|
501
508
|
isSemiFrameworkPkgByJson(pkgJson) {
|
|
502
509
|
return !!pkgJson.dependencies?.svelte || !!pkgJson.peerDependencies?.svelte;
|
|
@@ -510,8 +517,17 @@ async function buildExtraConfigForDependencies(options, config) {
|
|
|
510
517
|
}
|
|
511
518
|
}
|
|
512
519
|
});
|
|
513
|
-
|
|
514
|
-
|
|
520
|
+
if (
|
|
521
|
+
!options.experimental?.disableSvelteResolveWarnings &&
|
|
522
|
+
packagesWithoutSvelteExportsCondition?.size > 0
|
|
523
|
+
) {
|
|
524
|
+
log.warn(
|
|
525
|
+
`WARNING: The following packages have a svelte field in their package.json but no exports condition for svelte.\n\n${[
|
|
526
|
+
...packagesWithoutSvelteExportsCondition
|
|
527
|
+
].join('\n')}\n\nPlease see ${FAQ_LINK_MISSING_EXPORTS_CONDITION} for details.`
|
|
528
|
+
);
|
|
529
|
+
}
|
|
530
|
+
log.debug('extra config for dependencies generated by vitefu', depsConfig, 'config');
|
|
515
531
|
|
|
516
532
|
if (options.prebundleSvelteLibraries) {
|
|
517
533
|
// prebundling enabled, so we don't need extra dependency excludes
|
|
@@ -545,7 +561,7 @@ async function buildExtraConfigForDependencies(options, config) {
|
|
|
545
561
|
});
|
|
546
562
|
}
|
|
547
563
|
|
|
548
|
-
log.debug('post-processed extra config for dependencies', depsConfig);
|
|
564
|
+
log.debug('post-processed extra config for dependencies', depsConfig, 'config');
|
|
549
565
|
|
|
550
566
|
return depsConfig;
|
|
551
567
|
}
|
|
@@ -562,11 +578,17 @@ function buildExtraConfigForSvelte(config) {
|
|
|
562
578
|
if (!isDepExcluded('svelte', config.optimizeDeps?.exclude ?? [])) {
|
|
563
579
|
const svelteImportsToInclude = SVELTE_IMPORTS.filter((x) => x !== 'svelte/ssr'); // not used on clientside
|
|
564
580
|
log.debug(
|
|
565
|
-
`adding bare svelte packages to optimizeDeps.include: ${svelteImportsToInclude.join(', ')}
|
|
581
|
+
`adding bare svelte packages to optimizeDeps.include: ${svelteImportsToInclude.join(', ')} `,
|
|
582
|
+
undefined,
|
|
583
|
+
'config'
|
|
566
584
|
);
|
|
567
585
|
include.push(...svelteImportsToInclude);
|
|
568
586
|
} else {
|
|
569
|
-
log.debug(
|
|
587
|
+
log.debug(
|
|
588
|
+
'"svelte" is excluded in optimizeDeps.exclude, skipped adding it to include.',
|
|
589
|
+
undefined,
|
|
590
|
+
'config'
|
|
591
|
+
);
|
|
570
592
|
}
|
|
571
593
|
/** @type {(string | RegExp)[]} */
|
|
572
594
|
const noExternal = [];
|
package/src/utils/preprocess.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import MagicString from 'magic-string';
|
|
2
2
|
import { log } from './log.js';
|
|
3
3
|
import path from 'node:path';
|
|
4
|
+
import { normalizePath } from 'vite';
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* this appends a *{} rule to component styles to force the svelte compiler to add style classes to all nodes
|
|
@@ -12,6 +13,7 @@ import path from 'node:path';
|
|
|
12
13
|
*/
|
|
13
14
|
export function createInjectScopeEverythingRulePreprocessorGroup() {
|
|
14
15
|
return {
|
|
16
|
+
name: 'inject-scope-everything-rule',
|
|
15
17
|
style({ content, filename }) {
|
|
16
18
|
const s = new MagicString(content);
|
|
17
19
|
s.append(' *{}');
|
|
@@ -84,14 +86,18 @@ function buildExtraPreprocessors(options, config) {
|
|
|
84
86
|
log.debug(
|
|
85
87
|
`Ignoring svelte preprocessors defined by these vite plugins: ${ignored
|
|
86
88
|
.map((p) => p.name)
|
|
87
|
-
.join(', ')}
|
|
89
|
+
.join(', ')}`,
|
|
90
|
+
undefined,
|
|
91
|
+
'preprocess'
|
|
88
92
|
);
|
|
89
93
|
}
|
|
90
94
|
if (included.length > 0) {
|
|
91
95
|
log.debug(
|
|
92
96
|
`Adding svelte preprocessors defined by these vite plugins: ${included
|
|
93
97
|
.map((p) => p.name)
|
|
94
|
-
.join(', ')}
|
|
98
|
+
.join(', ')}`,
|
|
99
|
+
undefined,
|
|
100
|
+
'preprocess'
|
|
95
101
|
);
|
|
96
102
|
appendPreprocessors.push(...pluginsWithPreprocessors.map((p) => p.api.sveltePreprocess));
|
|
97
103
|
}
|
|
@@ -116,3 +122,52 @@ export function addExtraPreprocessors(options, config) {
|
|
|
116
122
|
}
|
|
117
123
|
}
|
|
118
124
|
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
*
|
|
128
|
+
* @param filename {string}
|
|
129
|
+
* @param dependencies {string[]}
|
|
130
|
+
* @returns {({dependencies: string[], warnings:import('svelte/types/compiler/interfaces').Warning[] })}
|
|
131
|
+
*/
|
|
132
|
+
export function checkPreprocessDependencies(filename, dependencies) {
|
|
133
|
+
/** @type {import('svelte/types/compiler/interfaces').Warning[]} */
|
|
134
|
+
const warnings = [];
|
|
135
|
+
|
|
136
|
+
// to find self, we have to compare normalized filenames, but must keep the original values in `dependencies`
|
|
137
|
+
// because otherwise file watching on windows doesn't work
|
|
138
|
+
// so we track idx and filter by that in the end
|
|
139
|
+
/** @type {number[]} */
|
|
140
|
+
const selfIdx = [];
|
|
141
|
+
const normalizedFullFilename = normalizePath(filename);
|
|
142
|
+
const normalizedDeps = dependencies.map(normalizePath);
|
|
143
|
+
for (let i = 0; i < normalizedDeps.length; i++) {
|
|
144
|
+
if (normalizedDeps[i] === normalizedFullFilename) {
|
|
145
|
+
selfIdx.push(i);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
const hasSelfDependency = selfIdx.length > 0;
|
|
149
|
+
if (hasSelfDependency) {
|
|
150
|
+
warnings.push({
|
|
151
|
+
code: 'vite-plugin-svelte-preprocess-depends-on-self',
|
|
152
|
+
message:
|
|
153
|
+
'svelte.preprocess returned this file as a dependency of itself. This can be caused by an invalid configuration or importing generated code that depends on .svelte files (eg. tailwind base css)',
|
|
154
|
+
filename
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
if (dependencies.length > 10) {
|
|
159
|
+
warnings.push({
|
|
160
|
+
code: 'vite-plugin-svelte-preprocess-many-dependencies',
|
|
161
|
+
message: `svelte.preprocess depends on more than 10 external files which can cause slow builds and poor DX, try to reduce them. Found: ${dependencies.join(
|
|
162
|
+
', '
|
|
163
|
+
)}`,
|
|
164
|
+
filename
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
return {
|
|
168
|
+
dependencies: hasSelfDependency
|
|
169
|
+
? dependencies.filter((_, i) => !selfIdx.includes(i)) // remove self dependency
|
|
170
|
+
: dependencies,
|
|
171
|
+
warnings
|
|
172
|
+
};
|
|
173
|
+
}
|
|
@@ -24,8 +24,6 @@ export class VitePluginSvelteCache {
|
|
|
24
24
|
#dependencies = new Map();
|
|
25
25
|
/** @type {Map<string, Set<string>>} */
|
|
26
26
|
#dependants = new Map();
|
|
27
|
-
/** @type {Map<string, string>} */
|
|
28
|
-
#resolvedSvelteFields = new Map();
|
|
29
27
|
/** @type {Map<string, any>} */
|
|
30
28
|
#errors = new Map();
|
|
31
29
|
/** @type {PackageInfo[]} */
|
|
@@ -168,45 +166,6 @@ export class VitePluginSvelteCache {
|
|
|
168
166
|
return dependants ? [...dependants] : [];
|
|
169
167
|
}
|
|
170
168
|
|
|
171
|
-
/**
|
|
172
|
-
* @param {string} name
|
|
173
|
-
* @param {string} [importer]
|
|
174
|
-
* @returns {string|void}
|
|
175
|
-
*/
|
|
176
|
-
getResolvedSvelteField(name, importer) {
|
|
177
|
-
return this.#resolvedSvelteFields.get(this.#getResolvedSvelteFieldKey(name, importer));
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
/**
|
|
181
|
-
* @param {string} name
|
|
182
|
-
* @param {string} [importer]
|
|
183
|
-
* @returns {boolean}
|
|
184
|
-
*/
|
|
185
|
-
hasResolvedSvelteField(name, importer) {
|
|
186
|
-
return this.#resolvedSvelteFields.has(this.#getResolvedSvelteFieldKey(name, importer));
|
|
187
|
-
}
|
|
188
|
-
/**
|
|
189
|
-
*
|
|
190
|
-
* @param {string} importee
|
|
191
|
-
* @param {string | undefined} importer
|
|
192
|
-
* @param {string} resolvedSvelte
|
|
193
|
-
*/
|
|
194
|
-
setResolvedSvelteField(importee, importer, resolvedSvelte) {
|
|
195
|
-
this.#resolvedSvelteFields.set(
|
|
196
|
-
this.#getResolvedSvelteFieldKey(importee, importer),
|
|
197
|
-
resolvedSvelte
|
|
198
|
-
);
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
/**
|
|
202
|
-
* @param {string} importee
|
|
203
|
-
* @param {string | undefined} importer
|
|
204
|
-
* @returns {string}
|
|
205
|
-
*/
|
|
206
|
-
#getResolvedSvelteFieldKey(importee, importer) {
|
|
207
|
-
return importer ? `${importer} > ${importee}` : importee;
|
|
208
|
-
}
|
|
209
|
-
|
|
210
169
|
/**
|
|
211
170
|
* @param {string} file
|
|
212
171
|
* @returns {Promise<PackageInfo>}
|
package/src/utils/watch.js
CHANGED
|
@@ -22,7 +22,9 @@ export function setupWatchers(options, cache, requestParser) {
|
|
|
22
22
|
dependants.forEach((dependant) => {
|
|
23
23
|
if (fs.existsSync(dependant)) {
|
|
24
24
|
log.debug(
|
|
25
|
-
`emitting virtual change event for "${dependant}" because depdendency "${filename}" changed
|
|
25
|
+
`emitting virtual change event for "${dependant}" because depdendency "${filename}" changed`,
|
|
26
|
+
undefined,
|
|
27
|
+
'hmr'
|
|
26
28
|
);
|
|
27
29
|
watcher.emit('change', dependant);
|
|
28
30
|
}
|
|
@@ -34,7 +36,7 @@ export function setupWatchers(options, cache, requestParser) {
|
|
|
34
36
|
if (svelteRequest) {
|
|
35
37
|
const removedFromCache = cache.remove(svelteRequest);
|
|
36
38
|
if (removedFromCache) {
|
|
37
|
-
log.debug(`cleared VitePluginSvelteCache for deleted file ${filename}
|
|
39
|
+
log.debug(`cleared VitePluginSvelteCache for deleted file ${filename}`, undefined, 'hmr');
|
|
38
40
|
}
|
|
39
41
|
}
|
|
40
42
|
};
|
package/src/utils/resolve.js
DELETED
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import path from 'node:path';
|
|
2
|
-
import { builtinModules } from 'node:module';
|
|
3
|
-
import { resolveDependencyData, isCommonDepWithoutSvelteField } from './dependencies.js';
|
|
4
|
-
import { normalizePath } from 'vite';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* @param {string} importee
|
|
8
|
-
* @param {string | undefined} importer
|
|
9
|
-
* @param {import('./vite-plugin-svelte-cache').VitePluginSvelteCache} cache
|
|
10
|
-
* @returns {Promise<string | void>}
|
|
11
|
-
*/
|
|
12
|
-
export async function resolveViaPackageJsonSvelte(importee, importer, cache) {
|
|
13
|
-
if (
|
|
14
|
-
importer &&
|
|
15
|
-
isBareImport(importee) &&
|
|
16
|
-
!isNodeInternal(importee) &&
|
|
17
|
-
!isCommonDepWithoutSvelteField(importee)
|
|
18
|
-
) {
|
|
19
|
-
const cached = cache.getResolvedSvelteField(importee, importer);
|
|
20
|
-
if (cached) {
|
|
21
|
-
return cached;
|
|
22
|
-
}
|
|
23
|
-
const pkgData = await resolveDependencyData(importee, importer);
|
|
24
|
-
if (pkgData) {
|
|
25
|
-
const { pkg, dir } = pkgData;
|
|
26
|
-
if (pkg.svelte) {
|
|
27
|
-
const result = normalizePath(path.resolve(dir, pkg.svelte));
|
|
28
|
-
cache.setResolvedSvelteField(importee, importer, result);
|
|
29
|
-
return result;
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* @param {string} importee
|
|
37
|
-
* @returns {boolean}
|
|
38
|
-
*/
|
|
39
|
-
function isNodeInternal(importee) {
|
|
40
|
-
return importee.startsWith('node:') || builtinModules.includes(importee);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* @param {string} importee
|
|
45
|
-
* @returns {boolean}
|
|
46
|
-
*/
|
|
47
|
-
function isBareImport(importee) {
|
|
48
|
-
if (
|
|
49
|
-
!importee ||
|
|
50
|
-
importee[0] === '.' ||
|
|
51
|
-
importee[0] === '\0' ||
|
|
52
|
-
importee.includes(':') ||
|
|
53
|
-
path.isAbsolute(importee)
|
|
54
|
-
) {
|
|
55
|
-
return false;
|
|
56
|
-
}
|
|
57
|
-
const parts = importee.split('/');
|
|
58
|
-
switch (parts.length) {
|
|
59
|
-
case 1:
|
|
60
|
-
return true;
|
|
61
|
-
case 2:
|
|
62
|
-
return parts[0].startsWith('@');
|
|
63
|
-
default:
|
|
64
|
-
return false;
|
|
65
|
-
}
|
|
66
|
-
}
|