@sveltejs/vite-plugin-svelte 1.0.0-next.32 → 1.0.0-next.36
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 +450 -358
- package/dist/index.cjs.map +1 -7
- package/dist/index.js +428 -345
- package/dist/index.js.map +1 -7
- package/package.json +10 -10
- package/src/index.ts +21 -20
- package/src/utils/compile.ts +7 -1
- package/src/utils/dependencies.ts +11 -3
- package/src/utils/error.ts +9 -6
- package/src/utils/esbuild.ts +10 -2
- package/src/utils/log.ts +4 -1
- package/src/utils/optimizer.ts +43 -0
- package/src/utils/options.ts +100 -91
- package/src/utils/preprocess.ts +5 -8
- package/src/utils/resolve.ts +24 -9
- package/src/utils/vite-plugin-svelte-cache.ts +20 -0
- package/src/utils/watch.ts +3 -3
package/src/index.ts
CHANGED
|
@@ -9,15 +9,17 @@ import {
|
|
|
9
9
|
validateInlineOptions,
|
|
10
10
|
Options,
|
|
11
11
|
ResolvedOptions,
|
|
12
|
-
resolveOptions
|
|
12
|
+
resolveOptions,
|
|
13
|
+
patchResolvedViteConfig,
|
|
14
|
+
preResolveOptions
|
|
13
15
|
} from './utils/options';
|
|
14
16
|
import { VitePluginSvelteCache } from './utils/vite-plugin-svelte-cache';
|
|
15
17
|
|
|
16
18
|
import { ensureWatchedFile, setupWatchers } from './utils/watch';
|
|
17
19
|
import { resolveViaPackageJsonSvelte } from './utils/resolve';
|
|
18
|
-
import { addExtraPreprocessors } from './utils/preprocess';
|
|
19
20
|
import { PartialResolvedId } from 'rollup';
|
|
20
21
|
import { toRollupError } from './utils/error';
|
|
22
|
+
import { handleOptimizeDeps } from './utils/optimizer';
|
|
21
23
|
|
|
22
24
|
export function svelte(inlineOptions?: Partial<Options>): Plugin {
|
|
23
25
|
if (process.env.DEBUG != null) {
|
|
@@ -25,7 +27,7 @@ export function svelte(inlineOptions?: Partial<Options>): Plugin {
|
|
|
25
27
|
}
|
|
26
28
|
validateInlineOptions(inlineOptions);
|
|
27
29
|
const cache = new VitePluginSvelteCache();
|
|
28
|
-
const
|
|
30
|
+
const pkg_resolve_errors = new Set();
|
|
29
31
|
// updated in configResolved hook
|
|
30
32
|
let requestParser: IdParser;
|
|
31
33
|
let options: ResolvedOptions;
|
|
@@ -51,21 +53,27 @@ export function svelte(inlineOptions?: Partial<Options>): Plugin {
|
|
|
51
53
|
} else if (config.logLevel) {
|
|
52
54
|
log.setLevel(config.logLevel);
|
|
53
55
|
}
|
|
54
|
-
options
|
|
56
|
+
// @ts-expect-error temporarily lend the options variable until fixed in configResolved
|
|
57
|
+
options = await preResolveOptions(inlineOptions, config, configEnv);
|
|
55
58
|
// extra vite config
|
|
56
59
|
const extraViteConfig = buildExtraViteConfig(options, config, configEnv);
|
|
57
60
|
log.debug('additional vite config', extraViteConfig);
|
|
58
|
-
return extraViteConfig
|
|
61
|
+
return extraViteConfig;
|
|
59
62
|
},
|
|
60
63
|
|
|
61
64
|
async configResolved(config) {
|
|
62
|
-
|
|
65
|
+
options = resolveOptions(options, config);
|
|
66
|
+
patchResolvedViteConfig(config, options);
|
|
63
67
|
requestParser = buildIdParser(options);
|
|
64
68
|
compileSvelte = createCompileSvelte(options);
|
|
65
69
|
viteConfig = config;
|
|
66
70
|
log.debug('resolved options', options);
|
|
67
71
|
},
|
|
68
72
|
|
|
73
|
+
async buildStart() {
|
|
74
|
+
await handleOptimizeDeps(options, viteConfig);
|
|
75
|
+
},
|
|
76
|
+
|
|
69
77
|
configureServer(server) {
|
|
70
78
|
// eslint-disable-next-line no-unused-vars
|
|
71
79
|
options.server = server;
|
|
@@ -129,21 +137,13 @@ export function svelte(inlineOptions?: Partial<Options>): Plugin {
|
|
|
129
137
|
}
|
|
130
138
|
|
|
131
139
|
try {
|
|
132
|
-
const resolved = resolveViaPackageJsonSvelte(importee, importer);
|
|
140
|
+
const resolved = resolveViaPackageJsonSvelte(importee, importer, cache);
|
|
133
141
|
if (resolved) {
|
|
134
142
|
log.debug(`resolveId resolved ${resolved} via package.json svelte field of ${importee}`);
|
|
135
143
|
return resolved;
|
|
136
144
|
}
|
|
137
145
|
} catch (err) {
|
|
138
|
-
|
|
139
|
-
case 'ERR_PACKAGE_PATH_NOT_EXPORTED':
|
|
140
|
-
pkg_export_errors.add(importee);
|
|
141
|
-
return null;
|
|
142
|
-
case 'MODULE_NOT_FOUND':
|
|
143
|
-
return null;
|
|
144
|
-
default:
|
|
145
|
-
throw err;
|
|
146
|
-
}
|
|
146
|
+
pkg_resolve_errors.add(importee);
|
|
147
147
|
}
|
|
148
148
|
},
|
|
149
149
|
|
|
@@ -170,7 +170,7 @@ export function svelte(inlineOptions?: Partial<Options>): Plugin {
|
|
|
170
170
|
try {
|
|
171
171
|
compileData = await compileSvelte(svelteRequest, code, options);
|
|
172
172
|
} catch (e) {
|
|
173
|
-
throw toRollupError(e);
|
|
173
|
+
throw toRollupError(e, options);
|
|
174
174
|
}
|
|
175
175
|
logCompilerWarnings(compileData.compiled.warnings, options);
|
|
176
176
|
cache.update(compileData);
|
|
@@ -198,10 +198,11 @@ export function svelte(inlineOptions?: Partial<Options>): Plugin {
|
|
|
198
198
|
*/
|
|
199
199
|
// TODO generateBundle isn't called by vite, is buildEnd enough or should it be logged once per violation in resolve
|
|
200
200
|
buildEnd() {
|
|
201
|
-
if (
|
|
201
|
+
if (pkg_resolve_errors.size > 0) {
|
|
202
202
|
log.warn(
|
|
203
|
-
`
|
|
204
|
-
|
|
203
|
+
`vite-plugin-svelte was unable to find package.json of the following packages and wasn't able to resolve via their "svelte" field.
|
|
204
|
+
If you had difficulties importing svelte components from a package, then please contact the author and ask them to export the package.json file.
|
|
205
|
+
${Array.from(pkg_resolve_errors, (s) => `- ${s}`).join('\n')}`.replace(/\t/g, '')
|
|
205
206
|
);
|
|
206
207
|
}
|
|
207
208
|
}
|
package/src/utils/compile.ts
CHANGED
|
@@ -37,7 +37,13 @@ const _createCompileSvelte = (makeHot: Function) =>
|
|
|
37
37
|
let preprocessed;
|
|
38
38
|
|
|
39
39
|
if (options.preprocess) {
|
|
40
|
-
|
|
40
|
+
try {
|
|
41
|
+
preprocessed = await preprocess(code, options.preprocess, { filename });
|
|
42
|
+
} catch (e) {
|
|
43
|
+
e.message = `Error while preprocessing ${filename}${e.message ? ` - ${e.message}` : ''}`;
|
|
44
|
+
throw e;
|
|
45
|
+
}
|
|
46
|
+
|
|
41
47
|
if (preprocessed.dependencies) dependencies.push(...preprocessed.dependencies);
|
|
42
48
|
if (preprocessed.map) compileOptions.sourcemap = preprocessed.map;
|
|
43
49
|
}
|
|
@@ -66,7 +66,10 @@ function getSvelteDependencies(
|
|
|
66
66
|
return result;
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
-
function resolveDependencyData(
|
|
69
|
+
export function resolveDependencyData(
|
|
70
|
+
dep: string,
|
|
71
|
+
localRequire: NodeRequire
|
|
72
|
+
): DependencyData | void {
|
|
70
73
|
try {
|
|
71
74
|
const pkgJson = `${dep}/package.json`;
|
|
72
75
|
const pkg = localRequire(pkgJson);
|
|
@@ -166,7 +169,7 @@ const COMMON_PREFIXES_WITHOUT_SVELTE_FIELD = [
|
|
|
166
169
|
* @param dependency {string}
|
|
167
170
|
* @returns {boolean} true if it is a dependency without a svelte field
|
|
168
171
|
*/
|
|
169
|
-
function is_common_without_svelte_field(dependency: string): boolean {
|
|
172
|
+
export function is_common_without_svelte_field(dependency: string): boolean {
|
|
170
173
|
return (
|
|
171
174
|
COMMON_DEPENDENCIES_WITHOUT_SVELTE_FIELD.includes(dependency) ||
|
|
172
175
|
COMMON_PREFIXES_WITHOUT_SVELTE_FIELD.some(
|
|
@@ -184,7 +187,12 @@ export function needsOptimization(dep: string, localRequire: NodeRequire): boole
|
|
|
184
187
|
const pkg = depData.pkg;
|
|
185
188
|
// only optimize if is cjs, using the below as heuristic
|
|
186
189
|
// see https://github.com/sveltejs/vite-plugin-svelte/issues/162
|
|
187
|
-
|
|
190
|
+
const isCjs = pkg.main && !pkg.module && !pkg.exports;
|
|
191
|
+
if (!isCjs) return false;
|
|
192
|
+
// ensure entry is js so vite can prebundle it
|
|
193
|
+
// see https://github.com/sveltejs/vite-plugin-svelte/issues/233
|
|
194
|
+
const entryExt = path.extname(pkg.main);
|
|
195
|
+
return !entryExt || entryExt === '.js' || entryExt === '.cjs';
|
|
188
196
|
}
|
|
189
197
|
|
|
190
198
|
interface DependencyData {
|
package/src/utils/error.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { RollupError } from 'rollup';
|
|
2
|
-
import { Warning } from './options';
|
|
2
|
+
import { ResolvedOptions, Warning } from './options';
|
|
3
3
|
import { buildExtendedLogMessage } from './log';
|
|
4
4
|
import { PartialMessage } from 'esbuild';
|
|
5
5
|
|
|
@@ -8,15 +8,15 @@ import { PartialMessage } from 'esbuild';
|
|
|
8
8
|
* @param error a svelte compiler error, which is a mix of Warning and an error
|
|
9
9
|
* @returns {RollupError} the converted error
|
|
10
10
|
*/
|
|
11
|
-
export function toRollupError(error: Warning & Error): RollupError {
|
|
12
|
-
const { filename, frame, start, code, name } = error;
|
|
11
|
+
export function toRollupError(error: Warning & Error, options: ResolvedOptions): RollupError {
|
|
12
|
+
const { filename, frame, start, code, name, stack } = error;
|
|
13
13
|
const rollupError: RollupError = {
|
|
14
14
|
name, // needed otherwise sveltekit coalesce_to_error turns it into a string
|
|
15
15
|
id: filename,
|
|
16
16
|
message: buildExtendedLogMessage(error), // include filename:line:column so that it's clickable
|
|
17
17
|
frame: formatFrameForVite(frame),
|
|
18
18
|
code,
|
|
19
|
-
stack: ''
|
|
19
|
+
stack: options.isBuild || options.isDebug || !frame ? stack : ''
|
|
20
20
|
};
|
|
21
21
|
if (start) {
|
|
22
22
|
rollupError.loc = {
|
|
@@ -33,8 +33,8 @@ export function toRollupError(error: Warning & Error): RollupError {
|
|
|
33
33
|
* @param error a svelte compiler error, which is a mix of Warning and an error
|
|
34
34
|
* @returns {PartialMessage} the converted error
|
|
35
35
|
*/
|
|
36
|
-
export function toESBuildError(error: Warning & Error): PartialMessage {
|
|
37
|
-
const { filename, frame, start } = error;
|
|
36
|
+
export function toESBuildError(error: Warning & Error, options: ResolvedOptions): PartialMessage {
|
|
37
|
+
const { filename, frame, start, stack } = error;
|
|
38
38
|
const partialMessage: PartialMessage = {
|
|
39
39
|
text: buildExtendedLogMessage(error)
|
|
40
40
|
};
|
|
@@ -46,6 +46,9 @@ export function toESBuildError(error: Warning & Error): PartialMessage {
|
|
|
46
46
|
lineText: lineFromFrame(start.line, frame) // needed to get a meaningful error message on cli
|
|
47
47
|
};
|
|
48
48
|
}
|
|
49
|
+
if (options.isBuild || options.isDebug || !frame) {
|
|
50
|
+
partialMessage.detail = stack;
|
|
51
|
+
}
|
|
49
52
|
return partialMessage;
|
|
50
53
|
}
|
|
51
54
|
|
package/src/utils/esbuild.ts
CHANGED
|
@@ -10,6 +10,8 @@ type EsbuildOptions = NonNullable<DepOptimizationOptions['esbuildOptions']>;
|
|
|
10
10
|
type EsbuildPlugin = NonNullable<EsbuildOptions['plugins']>[number];
|
|
11
11
|
type EsbuildPluginBuild = Parameters<EsbuildPlugin['setup']>[0];
|
|
12
12
|
|
|
13
|
+
export const facadeEsbuildSveltePluginName = 'vite-plugin-svelte:facade';
|
|
14
|
+
|
|
13
15
|
export function esbuildSveltePlugin(options: ResolvedOptions): EsbuildPlugin {
|
|
14
16
|
return {
|
|
15
17
|
name: 'vite-plugin-svelte:optimize-svelte',
|
|
@@ -25,7 +27,7 @@ export function esbuildSveltePlugin(options: ResolvedOptions): EsbuildPlugin {
|
|
|
25
27
|
const contents = await compileSvelte(options, { filename, code });
|
|
26
28
|
return { contents };
|
|
27
29
|
} catch (e) {
|
|
28
|
-
return { errors: [toESBuildError(e)] };
|
|
30
|
+
return { errors: [toESBuildError(e, options)] };
|
|
29
31
|
}
|
|
30
32
|
});
|
|
31
33
|
}
|
|
@@ -64,13 +66,19 @@ async function compileSvelte(
|
|
|
64
66
|
...options.compilerOptions,
|
|
65
67
|
css: true,
|
|
66
68
|
filename,
|
|
69
|
+
format: 'esm',
|
|
67
70
|
generate: 'dom'
|
|
68
71
|
};
|
|
69
72
|
|
|
70
73
|
let preprocessed;
|
|
71
74
|
|
|
72
75
|
if (options.preprocess) {
|
|
73
|
-
|
|
76
|
+
try {
|
|
77
|
+
preprocessed = await preprocess(code, options.preprocess, { filename });
|
|
78
|
+
} catch (e) {
|
|
79
|
+
e.message = `Error while preprocessing ${filename}${e.message ? ` - ${e.message}` : ''}`;
|
|
80
|
+
throw e;
|
|
81
|
+
}
|
|
74
82
|
if (preprocessed.map) compileOptions.sourcemap = preprocessed.map;
|
|
75
83
|
}
|
|
76
84
|
|
package/src/utils/log.ts
CHANGED
|
@@ -164,7 +164,10 @@ export function buildExtendedLogMessage(w: Warning) {
|
|
|
164
164
|
parts.push(':', w.start.line, ':', w.start.column);
|
|
165
165
|
}
|
|
166
166
|
if (w.message) {
|
|
167
|
-
parts.
|
|
167
|
+
if (parts.length > 0) {
|
|
168
|
+
parts.push(' ');
|
|
169
|
+
}
|
|
170
|
+
parts.push(w.message);
|
|
168
171
|
}
|
|
169
172
|
return parts.join('');
|
|
170
173
|
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { optimizeDeps, ResolvedConfig } from 'vite';
|
|
4
|
+
import { ResolvedOptions } from './options';
|
|
5
|
+
|
|
6
|
+
// List of options that changes the prebundling result
|
|
7
|
+
const PREBUNDLE_SENSITIVE_OPTIONS: (keyof ResolvedOptions)[] = [
|
|
8
|
+
'compilerOptions',
|
|
9
|
+
'configFile',
|
|
10
|
+
'experimental',
|
|
11
|
+
'extensions',
|
|
12
|
+
'ignorePluginPreprocessors',
|
|
13
|
+
'preprocess'
|
|
14
|
+
];
|
|
15
|
+
|
|
16
|
+
export async function handleOptimizeDeps(options: ResolvedOptions, viteConfig: ResolvedConfig) {
|
|
17
|
+
if (!options.experimental.prebundleSvelteLibraries || !viteConfig.cacheDir) return;
|
|
18
|
+
|
|
19
|
+
const viteMetadataPath = path.resolve(viteConfig.cacheDir, '_metadata.json');
|
|
20
|
+
|
|
21
|
+
if (!fs.existsSync(viteMetadataPath)) return;
|
|
22
|
+
|
|
23
|
+
const svelteMetadataPath = path.resolve(viteConfig.cacheDir, '_svelte_metadata.json');
|
|
24
|
+
const currentSvelteMetadata = JSON.stringify(generateSvelteMetadata(options), (_, value) => {
|
|
25
|
+
return typeof value === 'function' ? value.toString() : value;
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
if (fs.existsSync(svelteMetadataPath)) {
|
|
29
|
+
const existingSvelteMetadata = fs.readFileSync(svelteMetadataPath, 'utf8');
|
|
30
|
+
if (existingSvelteMetadata === currentSvelteMetadata) return;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
await optimizeDeps(viteConfig, true);
|
|
34
|
+
fs.writeFileSync(svelteMetadataPath, currentSvelteMetadata);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function generateSvelteMetadata(options: ResolvedOptions) {
|
|
38
|
+
const metadata: Record<string, any> = {};
|
|
39
|
+
for (const key of PREBUNDLE_SENSITIVE_OPTIONS) {
|
|
40
|
+
metadata[key] = options[key];
|
|
41
|
+
}
|
|
42
|
+
return metadata;
|
|
43
|
+
}
|
package/src/utils/options.ts
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
/* eslint-disable no-unused-vars */
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
ConfigEnv,
|
|
4
|
+
DepOptimizationOptions,
|
|
5
|
+
ResolvedConfig,
|
|
6
|
+
UserConfig,
|
|
7
|
+
ViteDevServer,
|
|
8
|
+
normalizePath
|
|
9
|
+
} from 'vite';
|
|
3
10
|
import { log } from './log';
|
|
4
11
|
import { loadSvelteConfig } from './load-svelte-config';
|
|
5
12
|
import { SVELTE_HMR_IMPORTS, SVELTE_IMPORTS, SVELTE_RESOLVE_MAIN_FIELDS } from './constants';
|
|
@@ -15,7 +22,8 @@ import {
|
|
|
15
22
|
import path from 'path';
|
|
16
23
|
import { findRootSvelteDependencies, needsOptimization, SvelteDependency } from './dependencies';
|
|
17
24
|
import { createRequire } from 'module';
|
|
18
|
-
import { esbuildSveltePlugin } from './esbuild';
|
|
25
|
+
import { esbuildSveltePlugin, facadeEsbuildSveltePluginName } from './esbuild';
|
|
26
|
+
import { addExtraPreprocessors } from './preprocess';
|
|
19
27
|
|
|
20
28
|
const knownOptions = new Set([
|
|
21
29
|
'configFile',
|
|
@@ -32,33 +40,86 @@ const knownOptions = new Set([
|
|
|
32
40
|
'experimental'
|
|
33
41
|
]);
|
|
34
42
|
|
|
35
|
-
function
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
+
export function validateInlineOptions(inlineOptions?: Partial<Options>) {
|
|
44
|
+
const invalidKeys = Object.keys(inlineOptions || {}).filter((key) => !knownOptions.has(key));
|
|
45
|
+
if (invalidKeys.length) {
|
|
46
|
+
log.warn(`invalid plugin options "${invalidKeys.join(', ')}" in config`, inlineOptions);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// used in config phase, merges the default options, svelte config, and inline options
|
|
51
|
+
export async function preResolveOptions(
|
|
52
|
+
inlineOptions: Partial<Options> = {},
|
|
53
|
+
viteUserConfig: UserConfig,
|
|
54
|
+
viteEnv: ConfigEnv
|
|
55
|
+
): Promise<PreResolvedOptions> {
|
|
56
|
+
const viteConfigWithResolvedRoot: UserConfig = {
|
|
57
|
+
...viteUserConfig,
|
|
58
|
+
root: resolveViteRoot(viteUserConfig)
|
|
59
|
+
};
|
|
43
60
|
const defaultOptions: Partial<Options> = {
|
|
44
61
|
extensions: ['.svelte'],
|
|
45
|
-
|
|
46
|
-
emitCss,
|
|
62
|
+
emitCss: true,
|
|
47
63
|
compilerOptions: {
|
|
48
|
-
format: 'esm'
|
|
49
|
-
css: !emitCss,
|
|
50
|
-
dev: !isProduction
|
|
64
|
+
format: 'esm'
|
|
51
65
|
}
|
|
52
66
|
};
|
|
53
|
-
|
|
54
|
-
|
|
67
|
+
const svelteConfig = await loadSvelteConfig(viteConfigWithResolvedRoot, inlineOptions);
|
|
68
|
+
const merged = {
|
|
69
|
+
...defaultOptions,
|
|
70
|
+
...svelteConfig,
|
|
71
|
+
...inlineOptions,
|
|
72
|
+
compilerOptions: {
|
|
73
|
+
...defaultOptions?.compilerOptions,
|
|
74
|
+
...svelteConfig?.compilerOptions,
|
|
75
|
+
...inlineOptions?.compilerOptions
|
|
76
|
+
},
|
|
77
|
+
experimental: {
|
|
78
|
+
...defaultOptions?.experimental,
|
|
79
|
+
...svelteConfig?.experimental,
|
|
80
|
+
...inlineOptions?.experimental
|
|
81
|
+
},
|
|
82
|
+
// extras
|
|
83
|
+
root: viteConfigWithResolvedRoot.root!,
|
|
84
|
+
isBuild: viteEnv.command === 'build',
|
|
85
|
+
isServe: viteEnv.command === 'serve',
|
|
86
|
+
isDebug: process.env.DEBUG != null
|
|
87
|
+
};
|
|
88
|
+
// configFile of svelteConfig contains the absolute path it was loaded from,
|
|
89
|
+
// prefer it over the possibly relative inline path
|
|
90
|
+
if (svelteConfig?.configFile) {
|
|
91
|
+
merged.configFile = svelteConfig.configFile;
|
|
92
|
+
}
|
|
93
|
+
return merged;
|
|
55
94
|
}
|
|
56
95
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
96
|
+
// used in configResolved phase, merges a contextual default config, pre-resolved options, and some preprocessors.
|
|
97
|
+
// also validates the final config.
|
|
98
|
+
export function resolveOptions(
|
|
99
|
+
preResolveOptions: PreResolvedOptions,
|
|
100
|
+
viteConfig: ResolvedConfig
|
|
101
|
+
): ResolvedOptions {
|
|
102
|
+
const defaultOptions: Partial<Options> = {
|
|
103
|
+
hot: viteConfig.isProduction ? false : { injectCss: !preResolveOptions.emitCss },
|
|
104
|
+
compilerOptions: {
|
|
105
|
+
css: !preResolveOptions.emitCss,
|
|
106
|
+
dev: !viteConfig.isProduction
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
const merged: ResolvedOptions = {
|
|
110
|
+
...defaultOptions,
|
|
111
|
+
...preResolveOptions,
|
|
112
|
+
compilerOptions: {
|
|
113
|
+
...defaultOptions.compilerOptions,
|
|
114
|
+
...preResolveOptions.compilerOptions
|
|
115
|
+
},
|
|
116
|
+
root: viteConfig.root,
|
|
117
|
+
isProduction: viteConfig.isProduction
|
|
118
|
+
};
|
|
119
|
+
addExtraPreprocessors(merged, viteConfig);
|
|
120
|
+
enforceOptionsForHmr(merged);
|
|
121
|
+
enforceOptionsForProduction(merged);
|
|
122
|
+
return merged;
|
|
62
123
|
}
|
|
63
124
|
|
|
64
125
|
function enforceOptionsForHmr(options: ResolvedOptions) {
|
|
@@ -114,69 +175,6 @@ function enforceOptionsForProduction(options: ResolvedOptions) {
|
|
|
114
175
|
}
|
|
115
176
|
}
|
|
116
177
|
|
|
117
|
-
function mergeOptions(
|
|
118
|
-
defaultOptions: Partial<Options>,
|
|
119
|
-
svelteConfig: Partial<Options>,
|
|
120
|
-
inlineOptions: Partial<Options>,
|
|
121
|
-
viteConfig: UserConfig,
|
|
122
|
-
viteEnv: ConfigEnv
|
|
123
|
-
): ResolvedOptions {
|
|
124
|
-
// @ts-ignore
|
|
125
|
-
const merged = {
|
|
126
|
-
...defaultOptions,
|
|
127
|
-
...svelteConfig,
|
|
128
|
-
...inlineOptions,
|
|
129
|
-
compilerOptions: {
|
|
130
|
-
...defaultOptions.compilerOptions,
|
|
131
|
-
...(svelteConfig?.compilerOptions || {}),
|
|
132
|
-
...(inlineOptions?.compilerOptions || {})
|
|
133
|
-
},
|
|
134
|
-
experimental: {
|
|
135
|
-
...(svelteConfig?.experimental || {}),
|
|
136
|
-
...(inlineOptions?.experimental || {})
|
|
137
|
-
},
|
|
138
|
-
root: viteConfig.root!,
|
|
139
|
-
isProduction: viteEnv.mode === 'production',
|
|
140
|
-
isBuild: viteEnv.command === 'build',
|
|
141
|
-
isServe: viteEnv.command === 'serve',
|
|
142
|
-
// @ts-expect-error we don't declare kit property of svelte config but read it once here to identify kit projects
|
|
143
|
-
isSvelteKit: !!svelteConfig?.kit
|
|
144
|
-
};
|
|
145
|
-
// configFile of svelteConfig contains the absolute path it was loaded from,
|
|
146
|
-
// prefer it over the possibly relative inline path
|
|
147
|
-
if (svelteConfig?.configFile) {
|
|
148
|
-
merged.configFile = svelteConfig.configFile;
|
|
149
|
-
}
|
|
150
|
-
return merged;
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
export async function resolveOptions(
|
|
154
|
-
inlineOptions: Partial<Options> = {},
|
|
155
|
-
viteConfig: UserConfig,
|
|
156
|
-
viteEnv: ConfigEnv
|
|
157
|
-
): Promise<ResolvedOptions> {
|
|
158
|
-
const viteConfigWithResolvedRoot = {
|
|
159
|
-
...viteConfig,
|
|
160
|
-
root: resolveViteRoot(viteConfig)
|
|
161
|
-
};
|
|
162
|
-
const svelteConfig = (await loadSvelteConfig(viteConfigWithResolvedRoot, inlineOptions)) || {};
|
|
163
|
-
const defaultOptions = buildDefaultOptions(
|
|
164
|
-
viteEnv.mode === 'production',
|
|
165
|
-
inlineOptions.emitCss ?? svelteConfig.emitCss
|
|
166
|
-
);
|
|
167
|
-
const resolvedOptions = mergeOptions(
|
|
168
|
-
defaultOptions,
|
|
169
|
-
svelteConfig,
|
|
170
|
-
inlineOptions,
|
|
171
|
-
viteConfigWithResolvedRoot,
|
|
172
|
-
viteEnv
|
|
173
|
-
);
|
|
174
|
-
|
|
175
|
-
enforceOptionsForProduction(resolvedOptions);
|
|
176
|
-
enforceOptionsForHmr(resolvedOptions);
|
|
177
|
-
return resolvedOptions;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
178
|
// vite passes unresolved `root`option to config hook but we need the resolved value, so do it here
|
|
181
179
|
// https://github.com/sveltejs/vite-plugin-svelte/issues/113
|
|
182
180
|
// https://github.com/vitejs/vite/blob/43c957de8a99bb326afd732c962f42127b0a4d1e/packages/vite/src/node/config.ts#L293
|
|
@@ -185,7 +183,7 @@ function resolveViteRoot(viteConfig: UserConfig): string | undefined {
|
|
|
185
183
|
}
|
|
186
184
|
|
|
187
185
|
export function buildExtraViteConfig(
|
|
188
|
-
options:
|
|
186
|
+
options: PreResolvedOptions,
|
|
189
187
|
config: UserConfig,
|
|
190
188
|
configEnv: ConfigEnv
|
|
191
189
|
): Partial<UserConfig> {
|
|
@@ -218,7 +216,7 @@ export function buildExtraViteConfig(
|
|
|
218
216
|
|
|
219
217
|
function buildOptimizeDepsForSvelte(
|
|
220
218
|
svelteDeps: SvelteDependency[],
|
|
221
|
-
options:
|
|
219
|
+
options: PreResolvedOptions,
|
|
222
220
|
optimizeDeps?: DepOptimizationOptions
|
|
223
221
|
): DepOptimizationOptions {
|
|
224
222
|
// include svelte imports for optimization unless explicitly excluded
|
|
@@ -249,7 +247,7 @@ function buildOptimizeDepsForSvelte(
|
|
|
249
247
|
include,
|
|
250
248
|
exclude,
|
|
251
249
|
esbuildOptions: {
|
|
252
|
-
plugins: [
|
|
250
|
+
plugins: [{ name: facadeEsbuildSveltePluginName, setup: () => {} }]
|
|
253
251
|
}
|
|
254
252
|
};
|
|
255
253
|
}
|
|
@@ -320,6 +318,14 @@ function buildSSROptionsForSvelte(
|
|
|
320
318
|
};
|
|
321
319
|
}
|
|
322
320
|
|
|
321
|
+
export function patchResolvedViteConfig(viteConfig: ResolvedConfig, options: ResolvedOptions) {
|
|
322
|
+
const facadeEsbuildSveltePlugin = viteConfig.optimizeDeps.esbuildOptions?.plugins?.find(
|
|
323
|
+
(plugin) => plugin.name === facadeEsbuildSveltePluginName
|
|
324
|
+
);
|
|
325
|
+
if (facadeEsbuildSveltePlugin) {
|
|
326
|
+
Object.assign(facadeEsbuildSveltePlugin, esbuildSveltePlugin(options));
|
|
327
|
+
}
|
|
328
|
+
}
|
|
323
329
|
export interface Options {
|
|
324
330
|
/**
|
|
325
331
|
* Path to a svelte config file, either absolute or relative to Vite root
|
|
@@ -478,17 +484,20 @@ export interface ExperimentalOptions {
|
|
|
478
484
|
}) => Promise<Partial<CompileOptions> | void> | Partial<CompileOptions> | void;
|
|
479
485
|
}
|
|
480
486
|
|
|
481
|
-
export interface
|
|
487
|
+
export interface PreResolvedOptions extends Options {
|
|
482
488
|
// these options are non-nullable after resolve
|
|
483
489
|
compilerOptions: CompileOptions;
|
|
484
490
|
experimental: ExperimentalOptions;
|
|
485
491
|
// extra options
|
|
486
492
|
root: string;
|
|
487
|
-
isProduction: boolean;
|
|
488
493
|
isBuild: boolean;
|
|
489
494
|
isServe: boolean;
|
|
495
|
+
isDebug: boolean;
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
export interface ResolvedOptions extends PreResolvedOptions {
|
|
499
|
+
isProduction: boolean;
|
|
490
500
|
server?: ViteDevServer;
|
|
491
|
-
isSvelteKit?: boolean;
|
|
492
501
|
}
|
|
493
502
|
|
|
494
503
|
export type {
|
package/src/utils/preprocess.ts
CHANGED
|
@@ -17,7 +17,6 @@ const supportedStyleLangs = ['css', 'less', 'sass', 'scss', 'styl', 'stylus', 'p
|
|
|
17
17
|
const supportedScriptLangs = ['ts'];
|
|
18
18
|
|
|
19
19
|
function createViteScriptPreprocessor(): Preprocessor {
|
|
20
|
-
// @ts-expect-error - allow return void
|
|
21
20
|
return async ({ attributes, content, filename = '' }) => {
|
|
22
21
|
const lang = attributes.lang as string;
|
|
23
22
|
if (!supportedScriptLangs.includes(lang)) return;
|
|
@@ -26,7 +25,8 @@ function createViteScriptPreprocessor(): Preprocessor {
|
|
|
26
25
|
tsconfigRaw: {
|
|
27
26
|
compilerOptions: {
|
|
28
27
|
// svelte typescript needs this flag to work with type imports
|
|
29
|
-
importsNotUsedAsValues: 'preserve'
|
|
28
|
+
importsNotUsedAsValues: 'preserve',
|
|
29
|
+
preserveValueImports: true
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
});
|
|
@@ -47,7 +47,6 @@ function createViteStylePreprocessor(config: ResolvedConfig): Preprocessor {
|
|
|
47
47
|
throw new Error(`plugin ${pluginName} has no transform`);
|
|
48
48
|
}
|
|
49
49
|
const pluginTransform = plugin.transform!.bind(null as unknown as TransformPluginContext);
|
|
50
|
-
// @ts-expect-error - allow return void
|
|
51
50
|
return async ({ attributes, content, filename = '' }) => {
|
|
52
51
|
const lang = attributes.lang as string;
|
|
53
52
|
if (!supportedStyleLangs.includes(lang)) return;
|
|
@@ -56,20 +55,18 @@ function createViteStylePreprocessor(config: ResolvedConfig): Preprocessor {
|
|
|
56
55
|
content,
|
|
57
56
|
moduleId
|
|
58
57
|
)) as TransformResult;
|
|
59
|
-
// vite returns empty mappings that would kill svelte compiler before 3.43.0
|
|
60
|
-
const hasMap = transformResult.map && transformResult.map.mappings !== '';
|
|
61
58
|
// patch sourcemap source to point back to original filename
|
|
62
|
-
if (
|
|
59
|
+
if (transformResult.map?.sources?.[0] === moduleId) {
|
|
63
60
|
transformResult.map.sources[0] = filename;
|
|
64
61
|
}
|
|
65
62
|
return {
|
|
66
63
|
code: transformResult.code,
|
|
67
|
-
map:
|
|
64
|
+
map: transformResult.map ?? undefined
|
|
68
65
|
};
|
|
69
66
|
};
|
|
70
67
|
}
|
|
71
68
|
|
|
72
|
-
|
|
69
|
+
function createVitePreprocessorGroup(config: ResolvedConfig): PreprocessorGroup {
|
|
73
70
|
return {
|
|
74
71
|
markup({ content, filename }) {
|
|
75
72
|
return preprocess(
|
package/src/utils/resolve.ts
CHANGED
|
@@ -1,14 +1,29 @@
|
|
|
1
1
|
import path from 'path';
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
import
|
|
2
|
+
import { createRequire } from 'module';
|
|
3
|
+
import { is_common_without_svelte_field, resolveDependencyData } from './dependencies';
|
|
4
|
+
import { VitePluginSvelteCache } from './vite-plugin-svelte-cache';
|
|
5
5
|
|
|
6
|
-
export function resolveViaPackageJsonSvelte(
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
6
|
+
export function resolveViaPackageJsonSvelte(
|
|
7
|
+
importee: string,
|
|
8
|
+
importer: string | undefined,
|
|
9
|
+
cache: VitePluginSvelteCache
|
|
10
|
+
): string | void {
|
|
11
|
+
if (importer && isBareImport(importee) && !is_common_without_svelte_field(importee)) {
|
|
12
|
+
const cached = cache.getResolvedSvelteField(importee, importer);
|
|
13
|
+
if (cached) {
|
|
14
|
+
return cached;
|
|
15
|
+
}
|
|
16
|
+
const localRequire = createRequire(importer);
|
|
17
|
+
const pkgData = resolveDependencyData(importee, localRequire);
|
|
18
|
+
if (pkgData) {
|
|
19
|
+
const { pkg, dir } = pkgData;
|
|
20
|
+
if (pkg.svelte) {
|
|
21
|
+
const result = path.resolve(dir, pkg.svelte);
|
|
22
|
+
cache.setResolvedSvelteField(importee, importer, result);
|
|
23
|
+
return result;
|
|
24
|
+
}
|
|
25
|
+
} else {
|
|
26
|
+
throw new Error(`failed to resolve package.json of ${importee} imported by ${importer}`);
|
|
12
27
|
}
|
|
13
28
|
}
|
|
14
29
|
}
|