@sveltejs/vite-plugin-svelte 1.0.0-next.31 → 1.0.0-next.35
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 +432 -355
- package/dist/index.cjs.map +1 -7
- package/dist/index.js +416 -348
- package/dist/index.js.map +1 -7
- package/package.json +11 -11
- package/src/index.ts +25 -28
- package/src/utils/dependencies.ts +11 -3
- package/src/utils/esbuild.ts +3 -0
- package/src/utils/optimizer.ts +43 -0
- package/src/utils/options.ts +98 -87
- package/src/utils/preprocess.ts +5 -8
- package/src/utils/resolve.ts +31 -10
- package/src/utils/vite-plugin-svelte-cache.ts +20 -0
- package/src/utils/watch.ts +7 -7
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;
|
|
@@ -95,11 +103,9 @@ export function svelte(inlineOptions?: Partial<Options>): Plugin {
|
|
|
95
103
|
}
|
|
96
104
|
},
|
|
97
105
|
|
|
98
|
-
async resolveId(importee, importer, opts
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
const ssr: boolean = _ssr === true || opts.ssr;
|
|
102
|
-
const svelteRequest = requestParser(importee, !!ssr);
|
|
106
|
+
async resolveId(importee, importer, opts) {
|
|
107
|
+
const ssr = !!opts?.ssr;
|
|
108
|
+
const svelteRequest = requestParser(importee, ssr);
|
|
103
109
|
if (svelteRequest?.query.svelte) {
|
|
104
110
|
if (svelteRequest.query.type === 'style') {
|
|
105
111
|
// return cssId with root prefix so postcss pipeline of vite finds the directory correctly
|
|
@@ -131,29 +137,19 @@ export function svelte(inlineOptions?: Partial<Options>): Plugin {
|
|
|
131
137
|
}
|
|
132
138
|
|
|
133
139
|
try {
|
|
134
|
-
const resolved = resolveViaPackageJsonSvelte(importee, importer);
|
|
140
|
+
const resolved = resolveViaPackageJsonSvelte(importee, importer, cache);
|
|
135
141
|
if (resolved) {
|
|
136
142
|
log.debug(`resolveId resolved ${resolved} via package.json svelte field of ${importee}`);
|
|
137
143
|
return resolved;
|
|
138
144
|
}
|
|
139
145
|
} catch (err) {
|
|
140
|
-
|
|
141
|
-
case 'ERR_PACKAGE_PATH_NOT_EXPORTED':
|
|
142
|
-
pkg_export_errors.add(importee);
|
|
143
|
-
return null;
|
|
144
|
-
case 'MODULE_NOT_FOUND':
|
|
145
|
-
return null;
|
|
146
|
-
default:
|
|
147
|
-
throw err;
|
|
148
|
-
}
|
|
146
|
+
pkg_resolve_errors.add(importee);
|
|
149
147
|
}
|
|
150
148
|
},
|
|
151
149
|
|
|
152
150
|
async transform(code, id, opts) {
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
const ssr: boolean = opts === true || opts?.ssr;
|
|
156
|
-
const svelteRequest = requestParser(id, !!ssr);
|
|
151
|
+
const ssr = !!opts?.ssr;
|
|
152
|
+
const svelteRequest = requestParser(id, ssr);
|
|
157
153
|
if (!svelteRequest) {
|
|
158
154
|
return;
|
|
159
155
|
}
|
|
@@ -202,10 +198,11 @@ export function svelte(inlineOptions?: Partial<Options>): Plugin {
|
|
|
202
198
|
*/
|
|
203
199
|
// TODO generateBundle isn't called by vite, is buildEnd enough or should it be logged once per violation in resolve
|
|
204
200
|
buildEnd() {
|
|
205
|
-
if (
|
|
201
|
+
if (pkg_resolve_errors.size > 0) {
|
|
206
202
|
log.warn(
|
|
207
|
-
`
|
|
208
|
-
|
|
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, '')
|
|
209
206
|
);
|
|
210
207
|
}
|
|
211
208
|
}
|
|
@@ -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/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',
|
|
@@ -64,6 +66,7 @@ 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
|
|
|
@@ -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,85 @@ 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
|
+
};
|
|
87
|
+
// configFile of svelteConfig contains the absolute path it was loaded from,
|
|
88
|
+
// prefer it over the possibly relative inline path
|
|
89
|
+
if (svelteConfig?.configFile) {
|
|
90
|
+
merged.configFile = svelteConfig.configFile;
|
|
91
|
+
}
|
|
92
|
+
return merged;
|
|
55
93
|
}
|
|
56
94
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
95
|
+
// used in configResolved phase, merges a contextual default config, pre-resolved options, and some preprocessors.
|
|
96
|
+
// also validates the final config.
|
|
97
|
+
export function resolveOptions(
|
|
98
|
+
preResolveOptions: PreResolvedOptions,
|
|
99
|
+
viteConfig: ResolvedConfig
|
|
100
|
+
): ResolvedOptions {
|
|
101
|
+
const defaultOptions: Partial<Options> = {
|
|
102
|
+
hot: viteConfig.isProduction ? false : { injectCss: !preResolveOptions.emitCss },
|
|
103
|
+
compilerOptions: {
|
|
104
|
+
css: !preResolveOptions.emitCss,
|
|
105
|
+
dev: !viteConfig.isProduction
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
const merged: ResolvedOptions = {
|
|
109
|
+
...defaultOptions,
|
|
110
|
+
...preResolveOptions,
|
|
111
|
+
compilerOptions: {
|
|
112
|
+
...defaultOptions.compilerOptions,
|
|
113
|
+
...preResolveOptions.compilerOptions
|
|
114
|
+
},
|
|
115
|
+
root: viteConfig.root,
|
|
116
|
+
isProduction: viteConfig.isProduction
|
|
117
|
+
};
|
|
118
|
+
addExtraPreprocessors(merged, viteConfig);
|
|
119
|
+
enforceOptionsForHmr(merged);
|
|
120
|
+
enforceOptionsForProduction(merged);
|
|
121
|
+
return merged;
|
|
62
122
|
}
|
|
63
123
|
|
|
64
124
|
function enforceOptionsForHmr(options: ResolvedOptions) {
|
|
@@ -114,66 +174,6 @@ function enforceOptionsForProduction(options: ResolvedOptions) {
|
|
|
114
174
|
}
|
|
115
175
|
}
|
|
116
176
|
|
|
117
|
-
function mergeOptions(
|
|
118
|
-
defaultOptions: Partial<Options>,
|
|
119
|
-
svelteConfig: Partial<Options>,
|
|
120
|
-
inlineOptions: Partial<Options>,
|
|
121
|
-
viteConfig: UserConfig,
|
|
122
|
-
viteEnv: ConfigEnv
|
|
123
|
-
): ResolvedOptions {
|
|
124
|
-
const merged = {
|
|
125
|
-
...defaultOptions,
|
|
126
|
-
...svelteConfig,
|
|
127
|
-
...inlineOptions,
|
|
128
|
-
compilerOptions: {
|
|
129
|
-
...defaultOptions.compilerOptions,
|
|
130
|
-
...(svelteConfig?.compilerOptions || {}),
|
|
131
|
-
...(inlineOptions?.compilerOptions || {})
|
|
132
|
-
},
|
|
133
|
-
experimental: {
|
|
134
|
-
...(svelteConfig?.experimental || {}),
|
|
135
|
-
...(inlineOptions?.experimental || {})
|
|
136
|
-
},
|
|
137
|
-
root: viteConfig.root!,
|
|
138
|
-
isProduction: viteEnv.mode === 'production',
|
|
139
|
-
isBuild: viteEnv.command === 'build',
|
|
140
|
-
isServe: viteEnv.command === 'serve'
|
|
141
|
-
};
|
|
142
|
-
// configFile of svelteConfig contains the absolute path it was loaded from,
|
|
143
|
-
// prefer it over the possibly relative inline path
|
|
144
|
-
if (svelteConfig?.configFile) {
|
|
145
|
-
merged.configFile = svelteConfig.configFile;
|
|
146
|
-
}
|
|
147
|
-
return merged;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
export async function resolveOptions(
|
|
151
|
-
inlineOptions: Partial<Options> = {},
|
|
152
|
-
viteConfig: UserConfig,
|
|
153
|
-
viteEnv: ConfigEnv
|
|
154
|
-
): Promise<ResolvedOptions> {
|
|
155
|
-
const viteConfigWithResolvedRoot = {
|
|
156
|
-
...viteConfig,
|
|
157
|
-
root: resolveViteRoot(viteConfig)
|
|
158
|
-
};
|
|
159
|
-
const svelteConfig = (await loadSvelteConfig(viteConfigWithResolvedRoot, inlineOptions)) || {};
|
|
160
|
-
const defaultOptions = buildDefaultOptions(
|
|
161
|
-
viteEnv.mode === 'production',
|
|
162
|
-
inlineOptions.emitCss ?? svelteConfig.emitCss
|
|
163
|
-
);
|
|
164
|
-
const resolvedOptions = mergeOptions(
|
|
165
|
-
defaultOptions,
|
|
166
|
-
svelteConfig,
|
|
167
|
-
inlineOptions,
|
|
168
|
-
viteConfigWithResolvedRoot,
|
|
169
|
-
viteEnv
|
|
170
|
-
);
|
|
171
|
-
|
|
172
|
-
enforceOptionsForProduction(resolvedOptions);
|
|
173
|
-
enforceOptionsForHmr(resolvedOptions);
|
|
174
|
-
return resolvedOptions;
|
|
175
|
-
}
|
|
176
|
-
|
|
177
177
|
// vite passes unresolved `root`option to config hook but we need the resolved value, so do it here
|
|
178
178
|
// https://github.com/sveltejs/vite-plugin-svelte/issues/113
|
|
179
179
|
// https://github.com/vitejs/vite/blob/43c957de8a99bb326afd732c962f42127b0a4d1e/packages/vite/src/node/config.ts#L293
|
|
@@ -182,7 +182,7 @@ function resolveViteRoot(viteConfig: UserConfig): string | undefined {
|
|
|
182
182
|
}
|
|
183
183
|
|
|
184
184
|
export function buildExtraViteConfig(
|
|
185
|
-
options:
|
|
185
|
+
options: PreResolvedOptions,
|
|
186
186
|
config: UserConfig,
|
|
187
187
|
configEnv: ConfigEnv
|
|
188
188
|
): Partial<UserConfig> {
|
|
@@ -215,7 +215,7 @@ export function buildExtraViteConfig(
|
|
|
215
215
|
|
|
216
216
|
function buildOptimizeDepsForSvelte(
|
|
217
217
|
svelteDeps: SvelteDependency[],
|
|
218
|
-
options:
|
|
218
|
+
options: PreResolvedOptions,
|
|
219
219
|
optimizeDeps?: DepOptimizationOptions
|
|
220
220
|
): DepOptimizationOptions {
|
|
221
221
|
// include svelte imports for optimization unless explicitly excluded
|
|
@@ -246,7 +246,7 @@ function buildOptimizeDepsForSvelte(
|
|
|
246
246
|
include,
|
|
247
247
|
exclude,
|
|
248
248
|
esbuildOptions: {
|
|
249
|
-
plugins: [
|
|
249
|
+
plugins: [{ name: facadeEsbuildSveltePluginName, setup: () => {} }]
|
|
250
250
|
}
|
|
251
251
|
};
|
|
252
252
|
}
|
|
@@ -317,6 +317,14 @@ function buildSSROptionsForSvelte(
|
|
|
317
317
|
};
|
|
318
318
|
}
|
|
319
319
|
|
|
320
|
+
export function patchResolvedViteConfig(viteConfig: ResolvedConfig, options: ResolvedOptions) {
|
|
321
|
+
const facadeEsbuildSveltePlugin = viteConfig.optimizeDeps.esbuildOptions?.plugins?.find(
|
|
322
|
+
(plugin) => plugin.name === facadeEsbuildSveltePluginName
|
|
323
|
+
);
|
|
324
|
+
if (facadeEsbuildSveltePlugin) {
|
|
325
|
+
Object.assign(facadeEsbuildSveltePlugin, esbuildSveltePlugin(options));
|
|
326
|
+
}
|
|
327
|
+
}
|
|
320
328
|
export interface Options {
|
|
321
329
|
/**
|
|
322
330
|
* Path to a svelte config file, either absolute or relative to Vite root
|
|
@@ -475,15 +483,18 @@ export interface ExperimentalOptions {
|
|
|
475
483
|
}) => Promise<Partial<CompileOptions> | void> | Partial<CompileOptions> | void;
|
|
476
484
|
}
|
|
477
485
|
|
|
478
|
-
export interface
|
|
486
|
+
export interface PreResolvedOptions extends Options {
|
|
479
487
|
// these options are non-nullable after resolve
|
|
480
488
|
compilerOptions: CompileOptions;
|
|
481
489
|
experimental: ExperimentalOptions;
|
|
482
490
|
// extra options
|
|
483
491
|
root: string;
|
|
484
|
-
isProduction: boolean;
|
|
485
492
|
isBuild: boolean;
|
|
486
493
|
isServe: boolean;
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
export interface ResolvedOptions extends PreResolvedOptions {
|
|
497
|
+
isProduction: boolean;
|
|
487
498
|
server?: ViteDevServer;
|
|
488
499
|
}
|
|
489
500
|
|
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,20 +1,41 @@
|
|
|
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
|
}
|
|
15
30
|
|
|
16
31
|
function isBareImport(importee: string): boolean {
|
|
17
|
-
if (
|
|
32
|
+
if (
|
|
33
|
+
!importee ||
|
|
34
|
+
importee[0] === '.' ||
|
|
35
|
+
importee[0] === '\0' ||
|
|
36
|
+
importee.includes(':') ||
|
|
37
|
+
path.isAbsolute(importee)
|
|
38
|
+
) {
|
|
18
39
|
return false;
|
|
19
40
|
}
|
|
20
41
|
const parts = importee.split('/');
|
|
@@ -6,6 +6,7 @@ export class VitePluginSvelteCache {
|
|
|
6
6
|
private _js = new Map<string, Code>();
|
|
7
7
|
private _dependencies = new Map<string, string[]>();
|
|
8
8
|
private _dependants = new Map<string, Set<string>>();
|
|
9
|
+
private _resolvedSvelteFields = new Map<string, string>();
|
|
9
10
|
|
|
10
11
|
public update(compileData: CompileData) {
|
|
11
12
|
this.updateCSS(compileData);
|
|
@@ -80,4 +81,23 @@ export class VitePluginSvelteCache {
|
|
|
80
81
|
const dependants = this._dependants.get(path);
|
|
81
82
|
return dependants ? [...dependants] : [];
|
|
82
83
|
}
|
|
84
|
+
|
|
85
|
+
public getResolvedSvelteField(name: string, importer?: string): string | void {
|
|
86
|
+
return this._resolvedSvelteFields.get(this._getResolvedSvelteFieldKey(name, importer));
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
public setResolvedSvelteField(
|
|
90
|
+
importee: string,
|
|
91
|
+
importer: string | undefined = undefined,
|
|
92
|
+
resolvedSvelte: string
|
|
93
|
+
) {
|
|
94
|
+
this._resolvedSvelteFields.set(
|
|
95
|
+
this._getResolvedSvelteFieldKey(importee, importer),
|
|
96
|
+
resolvedSvelte
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
private _getResolvedSvelteFieldKey(importee: string, importer?: string): string {
|
|
101
|
+
return importer ? `${importer} > ${importee}` : importee;
|
|
102
|
+
}
|
|
83
103
|
}
|
package/src/utils/watch.ts
CHANGED
|
@@ -17,7 +17,7 @@ export function setupWatchers(
|
|
|
17
17
|
return;
|
|
18
18
|
}
|
|
19
19
|
const { watcher, ws } = server;
|
|
20
|
-
const {
|
|
20
|
+
const { root, server: serverConfig } = server.config;
|
|
21
21
|
|
|
22
22
|
const emitChangeEventOnDependants = (filename: string) => {
|
|
23
23
|
const dependants = cache.getDependants(filename);
|
|
@@ -42,12 +42,9 @@ export function setupWatchers(
|
|
|
42
42
|
};
|
|
43
43
|
|
|
44
44
|
const triggerViteRestart = (filename: string) => {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
log.info(`svelte config changed: restarting vite server. - file: ${filename}`);
|
|
49
|
-
watcher.emit('change', viteConfigFile);
|
|
50
|
-
} else {
|
|
45
|
+
if (serverConfig.middlewareMode) {
|
|
46
|
+
// in middlewareMode we can't restart the server automatically
|
|
47
|
+
// show the user an overlay instead
|
|
51
48
|
const message =
|
|
52
49
|
'Svelte config change detected, restart your dev process to apply the changes.';
|
|
53
50
|
log.info(message, filename);
|
|
@@ -55,6 +52,9 @@ export function setupWatchers(
|
|
|
55
52
|
type: 'error',
|
|
56
53
|
err: { message, stack: '', plugin: 'vite-plugin-svelte', id: filename }
|
|
57
54
|
});
|
|
55
|
+
} else {
|
|
56
|
+
log.info(`svelte config changed: restarting vite server. - file: ${filename}`);
|
|
57
|
+
server.restart();
|
|
58
58
|
}
|
|
59
59
|
};
|
|
60
60
|
|