@sveltejs/vite-plugin-svelte 1.0.0-next.33 → 1.0.0-next.37
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 +174 -92
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +137 -65
- package/dist/index.js.map +1 -1
- package/package.json +6 -7
- package/src/index.ts +13 -15
- package/src/utils/compile.ts +7 -1
- package/src/utils/dependencies.ts +5 -2
- package/src/utils/error.ts +9 -6
- package/src/utils/esbuild.ts +7 -2
- package/src/utils/log.ts +4 -1
- package/src/utils/optimizer.ts +43 -0
- package/src/utils/options.ts +4 -1
- package/src/utils/preprocess.ts +2 -1
- package/src/utils/resolve.ts +33 -9
- package/src/utils/vite-plugin-svelte-cache.ts +20 -0
- package/src/utils/watch.ts +1 -1
package/src/index.ts
CHANGED
|
@@ -19,6 +19,7 @@ import { ensureWatchedFile, setupWatchers } from './utils/watch';
|
|
|
19
19
|
import { resolveViaPackageJsonSvelte } from './utils/resolve';
|
|
20
20
|
import { PartialResolvedId } from 'rollup';
|
|
21
21
|
import { toRollupError } from './utils/error';
|
|
22
|
+
import { handleOptimizeDeps } from './utils/optimizer';
|
|
22
23
|
|
|
23
24
|
export function svelte(inlineOptions?: Partial<Options>): Plugin {
|
|
24
25
|
if (process.env.DEBUG != null) {
|
|
@@ -26,7 +27,7 @@ export function svelte(inlineOptions?: Partial<Options>): Plugin {
|
|
|
26
27
|
}
|
|
27
28
|
validateInlineOptions(inlineOptions);
|
|
28
29
|
const cache = new VitePluginSvelteCache();
|
|
29
|
-
const
|
|
30
|
+
const pkg_resolve_errors = new Set();
|
|
30
31
|
// updated in configResolved hook
|
|
31
32
|
let requestParser: IdParser;
|
|
32
33
|
let options: ResolvedOptions;
|
|
@@ -69,6 +70,10 @@ export function svelte(inlineOptions?: Partial<Options>): Plugin {
|
|
|
69
70
|
log.debug('resolved options', options);
|
|
70
71
|
},
|
|
71
72
|
|
|
73
|
+
async buildStart() {
|
|
74
|
+
await handleOptimizeDeps(options, viteConfig);
|
|
75
|
+
},
|
|
76
|
+
|
|
72
77
|
configureServer(server) {
|
|
73
78
|
// eslint-disable-next-line no-unused-vars
|
|
74
79
|
options.server = server;
|
|
@@ -132,21 +137,13 @@ export function svelte(inlineOptions?: Partial<Options>): Plugin {
|
|
|
132
137
|
}
|
|
133
138
|
|
|
134
139
|
try {
|
|
135
|
-
const resolved = resolveViaPackageJsonSvelte(importee, importer);
|
|
140
|
+
const resolved = resolveViaPackageJsonSvelte(importee, importer, cache);
|
|
136
141
|
if (resolved) {
|
|
137
142
|
log.debug(`resolveId resolved ${resolved} via package.json svelte field of ${importee}`);
|
|
138
143
|
return resolved;
|
|
139
144
|
}
|
|
140
145
|
} catch (err) {
|
|
141
|
-
|
|
142
|
-
case 'ERR_PACKAGE_PATH_NOT_EXPORTED':
|
|
143
|
-
pkg_export_errors.add(importee);
|
|
144
|
-
return null;
|
|
145
|
-
case 'MODULE_NOT_FOUND':
|
|
146
|
-
return null;
|
|
147
|
-
default:
|
|
148
|
-
throw err;
|
|
149
|
-
}
|
|
146
|
+
pkg_resolve_errors.add(importee);
|
|
150
147
|
}
|
|
151
148
|
},
|
|
152
149
|
|
|
@@ -173,7 +170,7 @@ export function svelte(inlineOptions?: Partial<Options>): Plugin {
|
|
|
173
170
|
try {
|
|
174
171
|
compileData = await compileSvelte(svelteRequest, code, options);
|
|
175
172
|
} catch (e) {
|
|
176
|
-
throw toRollupError(e);
|
|
173
|
+
throw toRollupError(e, options);
|
|
177
174
|
}
|
|
178
175
|
logCompilerWarnings(compileData.compiled.warnings, options);
|
|
179
176
|
cache.update(compileData);
|
|
@@ -201,10 +198,11 @@ export function svelte(inlineOptions?: Partial<Options>): Plugin {
|
|
|
201
198
|
*/
|
|
202
199
|
// TODO generateBundle isn't called by vite, is buildEnd enough or should it be logged once per violation in resolve
|
|
203
200
|
buildEnd() {
|
|
204
|
-
if (
|
|
201
|
+
if (pkg_resolve_errors.size > 0) {
|
|
205
202
|
log.warn(
|
|
206
|
-
`
|
|
207
|
-
|
|
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, '')
|
|
208
206
|
);
|
|
209
207
|
}
|
|
210
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(
|
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
|
@@ -27,7 +27,7 @@ export function esbuildSveltePlugin(options: ResolvedOptions): EsbuildPlugin {
|
|
|
27
27
|
const contents = await compileSvelte(options, { filename, code });
|
|
28
28
|
return { contents };
|
|
29
29
|
} catch (e) {
|
|
30
|
-
return { errors: [toESBuildError(e)] };
|
|
30
|
+
return { errors: [toESBuildError(e, options)] };
|
|
31
31
|
}
|
|
32
32
|
});
|
|
33
33
|
}
|
|
@@ -73,7 +73,12 @@ async function compileSvelte(
|
|
|
73
73
|
let preprocessed;
|
|
74
74
|
|
|
75
75
|
if (options.preprocess) {
|
|
76
|
-
|
|
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
|
+
}
|
|
77
82
|
if (preprocessed.map) compileOptions.sourcemap = preprocessed.map;
|
|
78
83
|
}
|
|
79
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
|
@@ -82,7 +82,8 @@ export async function preResolveOptions(
|
|
|
82
82
|
// extras
|
|
83
83
|
root: viteConfigWithResolvedRoot.root!,
|
|
84
84
|
isBuild: viteEnv.command === 'build',
|
|
85
|
-
isServe: viteEnv.command === 'serve'
|
|
85
|
+
isServe: viteEnv.command === 'serve',
|
|
86
|
+
isDebug: process.env.DEBUG != null
|
|
86
87
|
};
|
|
87
88
|
// configFile of svelteConfig contains the absolute path it was loaded from,
|
|
88
89
|
// prefer it over the possibly relative inline path
|
|
@@ -112,6 +113,7 @@ export function resolveOptions(
|
|
|
112
113
|
...defaultOptions.compilerOptions,
|
|
113
114
|
...preResolveOptions.compilerOptions
|
|
114
115
|
},
|
|
116
|
+
root: viteConfig.root,
|
|
115
117
|
isProduction: viteConfig.isProduction
|
|
116
118
|
};
|
|
117
119
|
addExtraPreprocessors(merged, viteConfig);
|
|
@@ -490,6 +492,7 @@ export interface PreResolvedOptions extends Options {
|
|
|
490
492
|
root: string;
|
|
491
493
|
isBuild: boolean;
|
|
492
494
|
isServe: boolean;
|
|
495
|
+
isDebug: boolean;
|
|
493
496
|
}
|
|
494
497
|
|
|
495
498
|
export interface ResolvedOptions extends PreResolvedOptions {
|
package/src/utils/preprocess.ts
CHANGED
|
@@ -25,7 +25,8 @@ function createViteScriptPreprocessor(): Preprocessor {
|
|
|
25
25
|
tsconfigRaw: {
|
|
26
26
|
compilerOptions: {
|
|
27
27
|
// svelte typescript needs this flag to work with type imports
|
|
28
|
-
importsNotUsedAsValues: 'preserve'
|
|
28
|
+
importsNotUsedAsValues: 'preserve',
|
|
29
|
+
preserveValueImports: true
|
|
29
30
|
}
|
|
30
31
|
}
|
|
31
32
|
});
|
package/src/utils/resolve.ts
CHANGED
|
@@ -1,18 +1,42 @@
|
|
|
1
1
|
import path from 'path';
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
import
|
|
2
|
+
import { builtinModules, 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 (
|
|
12
|
+
importer &&
|
|
13
|
+
isBareImport(importee) &&
|
|
14
|
+
!isNodeInternal(importee) &&
|
|
15
|
+
!is_common_without_svelte_field(importee)
|
|
16
|
+
) {
|
|
17
|
+
const cached = cache.getResolvedSvelteField(importee, importer);
|
|
18
|
+
if (cached) {
|
|
19
|
+
return cached;
|
|
20
|
+
}
|
|
21
|
+
const localRequire = createRequire(importer);
|
|
22
|
+
const pkgData = resolveDependencyData(importee, localRequire);
|
|
23
|
+
if (pkgData) {
|
|
24
|
+
const { pkg, dir } = pkgData;
|
|
25
|
+
if (pkg.svelte) {
|
|
26
|
+
const result = path.resolve(dir, pkg.svelte);
|
|
27
|
+
cache.setResolvedSvelteField(importee, importer, result);
|
|
28
|
+
return result;
|
|
29
|
+
}
|
|
30
|
+
} else {
|
|
31
|
+
throw new Error(`failed to resolve package.json of ${importee} imported by ${importer}`);
|
|
12
32
|
}
|
|
13
33
|
}
|
|
14
34
|
}
|
|
15
35
|
|
|
36
|
+
function isNodeInternal(importee: string) {
|
|
37
|
+
return importee.startsWith('node:') || builtinModules.includes(importee);
|
|
38
|
+
}
|
|
39
|
+
|
|
16
40
|
function isBareImport(importee: string): boolean {
|
|
17
41
|
if (
|
|
18
42
|
!importee ||
|
|
@@ -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