@sveltejs/vite-plugin-svelte 2.3.0 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +7 -12
- package/src/{handle-hot-update.ts → handle-hot-update.js} +35 -20
- package/src/index.d.ts +215 -0
- package/src/{index.ts → index.js} +39 -67
- package/src/{preprocess.ts → preprocess.js} +37 -28
- package/src/types/compile.d.ts +48 -0
- package/src/types/id.d.ts +31 -0
- package/src/types/log.d.ts +24 -0
- package/src/types/options.d.ts +20 -0
- package/src/types/plugin-api.d.ts +11 -0
- package/src/types/vite-plugin-svelte-stats.d.ts +30 -0
- package/src/utils/{compile.ts → compile.js} +32 -63
- package/src/utils/{dependencies.ts → dependencies.js} +14 -11
- package/src/utils/{error.ts → error.js} +21 -14
- package/src/utils/{esbuild.ts → esbuild.js} +23 -17
- package/src/utils/{hash.ts → hash.js} +14 -3
- package/src/utils/{id.ts → id.js} +59 -60
- package/src/utils/{load-raw.ts → load-raw.js} +16 -16
- package/src/utils/{load-svelte-config.ts → load-svelte-config.js} +12 -10
- package/src/utils/{log.ts → log.js} +81 -48
- package/src/utils/{optimizer.ts → optimizer.js} +15 -7
- package/src/utils/{options.ts → options.js} +146 -296
- package/src/utils/{preprocess.ts → preprocess.js} +28 -12
- package/src/utils/{resolve.ts → resolve.js} +18 -9
- package/src/utils/{sourcemaps.ts → sourcemaps.js} +22 -14
- package/src/utils/{svelte-version.ts → svelte-version.js} +15 -7
- package/src/utils/vite-plugin-svelte-cache.js +253 -0
- package/src/utils/{vite-plugin-svelte-stats.ts → vite-plugin-svelte-stats.js} +66 -62
- package/src/utils/{watch.ts → watch.js} +30 -22
- package/dist/index.d.ts +0 -193
- package/dist/index.js +0 -2272
- package/dist/index.js.map +0 -1
- package/src/__tests__/fixtures/preprocess/foo.scss +0 -3
- package/src/__tests__/preprocess.spec.ts +0 -51
- package/src/utils/__tests__/compile.spec.ts +0 -49
- package/src/utils/__tests__/sourcemaps.spec.ts +0 -79
- package/src/utils/__tests__/svelte-version.spec.ts +0 -102
- package/src/utils/vite-plugin-svelte-cache.ts +0 -182
- /package/src/utils/{constants.ts → constants.js} +0 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { CompileOptions } from 'svelte/types/compiler/interfaces';
|
|
2
|
+
|
|
3
|
+
export type SvelteQueryTypes = 'style' | 'script' | 'preprocessed' | 'all';
|
|
4
|
+
|
|
5
|
+
export interface RequestQuery {
|
|
6
|
+
// our own
|
|
7
|
+
svelte?: boolean;
|
|
8
|
+
type?: SvelteQueryTypes;
|
|
9
|
+
sourcemap?: boolean;
|
|
10
|
+
compilerOptions?: Pick<
|
|
11
|
+
CompileOptions,
|
|
12
|
+
'generate' | 'dev' | 'css' | 'hydratable' | 'customElement' | 'immutable' | 'enableSourcemap'
|
|
13
|
+
>;
|
|
14
|
+
// vite specific
|
|
15
|
+
url?: boolean;
|
|
16
|
+
raw?: boolean;
|
|
17
|
+
direct?: boolean;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface SvelteRequest {
|
|
21
|
+
id: string;
|
|
22
|
+
cssId: string;
|
|
23
|
+
filename: string;
|
|
24
|
+
normalizedFilename: string;
|
|
25
|
+
query: RequestQuery;
|
|
26
|
+
timestamp: number;
|
|
27
|
+
ssr: boolean;
|
|
28
|
+
raw: boolean;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export type IdParser = (id: string, ssr: boolean, timestamp?: number) => SvelteRequest | undefined;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { Warning } from '../index.d.ts';
|
|
2
|
+
|
|
3
|
+
export interface LogFn extends SimpleLogFn {
|
|
4
|
+
(message: string, payload?: any, namespace?: string): void;
|
|
5
|
+
|
|
6
|
+
enabled: boolean;
|
|
7
|
+
once: SimpleLogFn;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface SimpleLogFn {
|
|
11
|
+
(message: string, payload?: any, namespace?: string): void;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export type SvelteWarningsMessage = {
|
|
15
|
+
id: string;
|
|
16
|
+
filename: string;
|
|
17
|
+
normalizedFilename: string;
|
|
18
|
+
timestamp: number;
|
|
19
|
+
warnings: Warning[]; // allWarnings filtered by warnings where onwarn did not call the default handler
|
|
20
|
+
allWarnings: Warning[]; // includes warnings filtered by onwarn and our extra vite plugin svelte warnings
|
|
21
|
+
rawWarnings: Warning[]; // raw compiler output
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export type LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'silent';
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { CompileOptions } from 'svelte/types/compiler/interfaces';
|
|
2
|
+
import type { ViteDevServer } from 'vite';
|
|
3
|
+
import { VitePluginSvelteStats } from '../utils/vite-plugin-svelte-stats.js';
|
|
4
|
+
import type { Options } from '../index.d.ts';
|
|
5
|
+
|
|
6
|
+
export interface PreResolvedOptions extends Options {
|
|
7
|
+
// these options are non-nullable after resolve
|
|
8
|
+
compilerOptions: CompileOptions;
|
|
9
|
+
// extra options
|
|
10
|
+
root: string;
|
|
11
|
+
isBuild: boolean;
|
|
12
|
+
isServe: boolean;
|
|
13
|
+
isDebug: boolean;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface ResolvedOptions extends PreResolvedOptions {
|
|
17
|
+
isProduction: boolean;
|
|
18
|
+
server?: ViteDevServer;
|
|
19
|
+
stats?: VitePluginSvelteStats;
|
|
20
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ResolvedOptions } from './options.d.ts';
|
|
2
|
+
|
|
3
|
+
export interface PluginAPI {
|
|
4
|
+
/**
|
|
5
|
+
* must not be modified, should not be used outside of vite-plugin-svelte repo
|
|
6
|
+
* @internal
|
|
7
|
+
* @experimental
|
|
8
|
+
*/
|
|
9
|
+
options?: ResolvedOptions;
|
|
10
|
+
// TODO expose compile cache here so other utility plugins can use it
|
|
11
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export interface Stat {
|
|
2
|
+
file: string;
|
|
3
|
+
pkg?: string;
|
|
4
|
+
start: number;
|
|
5
|
+
end: number;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface StatCollection {
|
|
9
|
+
name: string;
|
|
10
|
+
options: CollectionOptions;
|
|
11
|
+
|
|
12
|
+
start: (file: string) => () => void;
|
|
13
|
+
stats: Stat[];
|
|
14
|
+
packageStats?: PackageStats[];
|
|
15
|
+
collectionStart: number;
|
|
16
|
+
duration?: number;
|
|
17
|
+
finish: () => Promise<void> | void;
|
|
18
|
+
finished: boolean;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface PackageStats {
|
|
22
|
+
pkg: string;
|
|
23
|
+
files: number;
|
|
24
|
+
duration: number;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface CollectionOptions {
|
|
28
|
+
logInProgress: (collection: StatCollection, now: number) => boolean;
|
|
29
|
+
logResult: (collection: StatCollection) => boolean;
|
|
30
|
+
}
|
|
@@ -1,28 +1,24 @@
|
|
|
1
|
-
import { CompileOptions, ResolvedOptions } from './options';
|
|
2
1
|
import { compile, preprocess, walk } from 'svelte/compiler';
|
|
3
2
|
// @ts-ignore
|
|
4
3
|
import { createMakeHot } from 'svelte-hmr';
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import { log } from './log';
|
|
8
|
-
import { StatCollection } from './vite-plugin-svelte-stats';
|
|
9
|
-
//eslint-disable-next-line node/no-missing-import
|
|
10
|
-
import type { Processed } from 'svelte/types/compiler/preprocess';
|
|
11
|
-
import { createInjectScopeEverythingRulePreprocessorGroup } from './preprocess';
|
|
12
|
-
import { mapToRelative } from './sourcemaps';
|
|
4
|
+
import { safeBase64Hash } from './hash.js';
|
|
5
|
+
import { log } from './log.js';
|
|
13
6
|
|
|
14
|
-
|
|
7
|
+
import { createInjectScopeEverythingRulePreprocessorGroup } from './preprocess.js';
|
|
8
|
+
import { mapToRelative } from './sourcemaps.js';
|
|
15
9
|
|
|
16
|
-
|
|
10
|
+
const scriptLangRE = /<script [^>]*lang=["']?([^"' >]+)["']?[^>]*>/;
|
|
17
11
|
|
|
18
|
-
|
|
19
|
-
|
|
12
|
+
/**
|
|
13
|
+
* @param {Function} [makeHot]
|
|
14
|
+
* @returns {import('../types/compile.d.ts').CompileSvelte}
|
|
15
|
+
*/
|
|
16
|
+
export const _createCompileSvelte = (makeHot) => {
|
|
17
|
+
/** @type {import('../types/vite-plugin-svelte-stats.d.ts').StatCollection | undefined} */
|
|
18
|
+
let stats;
|
|
20
19
|
const devStylePreprocessor = createInjectScopeEverythingRulePreprocessorGroup();
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
code: string,
|
|
24
|
-
options: Partial<ResolvedOptions>
|
|
25
|
-
): Promise<CompileData> {
|
|
20
|
+
/** @type {import('../types/compile.d.ts').CompileSvelte} */
|
|
21
|
+
return async function compileSvelte(svelteRequest, code, options) {
|
|
26
22
|
const { filename, normalizedFilename, cssId, ssr, raw } = svelteRequest;
|
|
27
23
|
const { emitCss = true } = options;
|
|
28
24
|
const dependencies = [];
|
|
@@ -51,8 +47,8 @@ const _createCompileSvelte = (makeHot: Function) => {
|
|
|
51
47
|
// also they for hmr updates too
|
|
52
48
|
}
|
|
53
49
|
}
|
|
54
|
-
|
|
55
|
-
const compileOptions
|
|
50
|
+
/** @type {import('../index.d.ts').CompileOptions} */
|
|
51
|
+
const compileOptions = {
|
|
56
52
|
...options.compilerOptions,
|
|
57
53
|
filename: normalizedFilename, // use normalized here to avoid bleeding absolute fs path
|
|
58
54
|
generate: ssr ? 'ssr' : 'dom',
|
|
@@ -98,8 +94,10 @@ const _createCompileSvelte = (makeHot: Function) => {
|
|
|
98
94
|
mapToRelative(preprocessed?.map, filename);
|
|
99
95
|
}
|
|
100
96
|
if (raw && svelteRequest.query.type === 'preprocessed') {
|
|
101
|
-
// shortcut
|
|
102
|
-
return
|
|
97
|
+
// @ts-expect-error shortcut
|
|
98
|
+
return /** @type {import('../types/compile.d.ts').CompileData} */ {
|
|
99
|
+
preprocessed: preprocessed ?? { code }
|
|
100
|
+
};
|
|
103
101
|
}
|
|
104
102
|
const finalCode = preprocessed ? preprocessed.code : code;
|
|
105
103
|
const dynamicCompileOptions = await options.experimental?.dynamicCompileOptions?.({
|
|
@@ -169,7 +167,12 @@ const _createCompileSvelte = (makeHot: Function) => {
|
|
|
169
167
|
};
|
|
170
168
|
};
|
|
171
169
|
};
|
|
172
|
-
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* @param {import('../types/options.d.ts').ResolvedOptions} options
|
|
173
|
+
* @returns {Function | undefined}
|
|
174
|
+
*/
|
|
175
|
+
function buildMakeHot(options) {
|
|
173
176
|
const needsMakeHot = options.hot !== false && options.isServe && !options.isProduction;
|
|
174
177
|
if (needsMakeHot) {
|
|
175
178
|
// @ts-ignore
|
|
@@ -180,50 +183,16 @@ function buildMakeHot(options: ResolvedOptions) {
|
|
|
180
183
|
walk,
|
|
181
184
|
hotApi,
|
|
182
185
|
adapter,
|
|
183
|
-
hotOptions: { noOverlay: true,
|
|
186
|
+
hotOptions: { noOverlay: true, .../** @type {object} */ (options.hot) }
|
|
184
187
|
});
|
|
185
188
|
}
|
|
186
189
|
}
|
|
187
190
|
|
|
188
|
-
|
|
191
|
+
/**
|
|
192
|
+
* @param {import('../types/options.d.ts').ResolvedOptions} options
|
|
193
|
+
* @returns {import('../types/compile.d.ts').CompileSvelte}
|
|
194
|
+
*/
|
|
195
|
+
export function createCompileSvelte(options) {
|
|
189
196
|
const makeHot = buildMakeHot(options);
|
|
190
197
|
return _createCompileSvelte(makeHot);
|
|
191
198
|
}
|
|
192
|
-
|
|
193
|
-
export interface Code {
|
|
194
|
-
code: string;
|
|
195
|
-
map?: any;
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
export interface Compiled {
|
|
199
|
-
js: Code;
|
|
200
|
-
css: Code;
|
|
201
|
-
ast: any; // TODO type
|
|
202
|
-
warnings: any[]; // TODO type
|
|
203
|
-
vars: {
|
|
204
|
-
name: string;
|
|
205
|
-
export_name: string;
|
|
206
|
-
injected: boolean;
|
|
207
|
-
module: boolean;
|
|
208
|
-
mutated: boolean;
|
|
209
|
-
reassigned: boolean;
|
|
210
|
-
referenced: boolean;
|
|
211
|
-
writable: boolean;
|
|
212
|
-
referenced_from_script: boolean;
|
|
213
|
-
}[];
|
|
214
|
-
stats: {
|
|
215
|
-
timings: {
|
|
216
|
-
total: number;
|
|
217
|
-
};
|
|
218
|
-
};
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
export interface CompileData {
|
|
222
|
-
filename: string;
|
|
223
|
-
normalizedFilename: string;
|
|
224
|
-
lang: string;
|
|
225
|
-
compiled: Compiled;
|
|
226
|
-
ssr: boolean | undefined;
|
|
227
|
-
dependencies: string[];
|
|
228
|
-
preprocessed: Processed;
|
|
229
|
-
}
|
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
import path from 'path';
|
|
2
2
|
import fs from 'fs/promises';
|
|
3
|
-
// eslint-disable-next-line node/no-missing-import
|
|
4
3
|
import { findDepPkgJsonPath } from 'vitefu';
|
|
5
4
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
/**
|
|
6
|
+
* @typedef {{
|
|
7
|
+
* dir: string;
|
|
8
|
+
* pkg: Record<string, any>;
|
|
9
|
+
* }} DependencyData
|
|
10
|
+
*/
|
|
10
11
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
/**
|
|
13
|
+
* @param {string} dep
|
|
14
|
+
* @param {string} parent
|
|
15
|
+
* @returns {Promise<DependencyData | undefined>}
|
|
16
|
+
*/
|
|
17
|
+
export async function resolveDependencyData(dep, parent) {
|
|
15
18
|
const depDataPath = await findDepPkgJsonPath(dep, parent);
|
|
16
19
|
if (!depDataPath) return undefined;
|
|
17
20
|
try {
|
|
@@ -69,10 +72,10 @@ const COMMON_PREFIXES_WITHOUT_SVELTE_FIELD = [
|
|
|
69
72
|
*
|
|
70
73
|
* This speeds up the find process as we don't have to try and require the package.json for all of them
|
|
71
74
|
*
|
|
72
|
-
* @param
|
|
75
|
+
* @param {string} dependency
|
|
73
76
|
* @returns {boolean} true if it is a dependency without a svelte field
|
|
74
77
|
*/
|
|
75
|
-
export function isCommonDepWithoutSvelteField(dependency
|
|
78
|
+
export function isCommonDepWithoutSvelteField(dependency) {
|
|
76
79
|
return (
|
|
77
80
|
COMMON_DEPENDENCIES_WITHOUT_SVELTE_FIELD.includes(dependency) ||
|
|
78
81
|
COMMON_PREFIXES_WITHOUT_SVELTE_FIELD.some(
|
|
@@ -1,16 +1,15 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { ResolvedOptions, Warning } from './options';
|
|
3
|
-
import { buildExtendedLogMessage } from './log';
|
|
4
|
-
import { PartialMessage } from 'esbuild';
|
|
1
|
+
import { buildExtendedLogMessage } from './log.js';
|
|
5
2
|
|
|
6
3
|
/**
|
|
7
4
|
* convert an error thrown by svelte.compile to a RollupError so that vite displays it in a user friendly way
|
|
8
|
-
* @param error a svelte compiler error, which is a mix of Warning and an error
|
|
9
|
-
* @
|
|
5
|
+
* @param {import('svelte/types/compiler/interfaces').Warning & Error} error a svelte compiler error, which is a mix of Warning and an error
|
|
6
|
+
* @param {import('../types/options.d.ts').ResolvedOptions} options
|
|
7
|
+
* @returns {import('vite').Rollup.RollupError} the converted error
|
|
10
8
|
*/
|
|
11
|
-
export function toRollupError(error
|
|
9
|
+
export function toRollupError(error, options) {
|
|
12
10
|
const { filename, frame, start, code, name, stack } = error;
|
|
13
|
-
|
|
11
|
+
/** @type {import('vite').Rollup.RollupError} */
|
|
12
|
+
const rollupError = {
|
|
14
13
|
name, // needed otherwise sveltekit coalesce_to_error turns it into a string
|
|
15
14
|
id: filename,
|
|
16
15
|
message: buildExtendedLogMessage(error), // include filename:line:column so that it's clickable
|
|
@@ -30,12 +29,14 @@ export function toRollupError(error: Warning & Error, options: ResolvedOptions):
|
|
|
30
29
|
|
|
31
30
|
/**
|
|
32
31
|
* convert an error thrown by svelte.compile to an esbuild PartialMessage
|
|
33
|
-
* @param error a svelte compiler error, which is a mix of Warning and an error
|
|
34
|
-
* @
|
|
32
|
+
* @param {import('svelte/types/compiler/interfaces').Warning & Error} error a svelte compiler error, which is a mix of Warning and an error
|
|
33
|
+
* @param {import('../types/options.d.ts').ResolvedOptions} options
|
|
34
|
+
* @returns {import('esbuild').PartialMessage} the converted error
|
|
35
35
|
*/
|
|
36
|
-
export function toESBuildError(error
|
|
36
|
+
export function toESBuildError(error, options) {
|
|
37
37
|
const { filename, frame, start, stack } = error;
|
|
38
|
-
|
|
38
|
+
/** @type {import('esbuild').PartialMessage} */
|
|
39
|
+
const partialMessage = {
|
|
39
40
|
text: buildExtendedLogMessage(error)
|
|
40
41
|
};
|
|
41
42
|
if (start) {
|
|
@@ -54,8 +55,12 @@ export function toESBuildError(error: Warning & Error, options: ResolvedOptions)
|
|
|
54
55
|
|
|
55
56
|
/**
|
|
56
57
|
* extract line with number from codeframe
|
|
58
|
+
*
|
|
59
|
+
* @param {number} lineNo
|
|
60
|
+
* @param {string} [frame]
|
|
61
|
+
* @returns {string}
|
|
57
62
|
*/
|
|
58
|
-
function lineFromFrame(lineNo
|
|
63
|
+
function lineFromFrame(lineNo, frame) {
|
|
59
64
|
if (!frame) {
|
|
60
65
|
return '';
|
|
61
66
|
}
|
|
@@ -83,8 +88,10 @@ function lineFromFrame(lineNo: number, frame?: string): string {
|
|
|
83
88
|
* 3 | baz
|
|
84
89
|
* ```
|
|
85
90
|
* @see https://github.com/vitejs/vite/blob/96591bf9989529de839ba89958755eafe4c445ae/packages/vite/src/client/overlay.ts#L116
|
|
91
|
+
* @param {string} [frame]
|
|
92
|
+
* @returns {string}
|
|
86
93
|
*/
|
|
87
|
-
function formatFrameForVite(frame
|
|
94
|
+
function formatFrameForVite(frame) {
|
|
88
95
|
if (!frame) {
|
|
89
96
|
return '';
|
|
90
97
|
}
|
|
@@ -1,18 +1,20 @@
|
|
|
1
1
|
import { readFileSync } from 'fs';
|
|
2
2
|
import { compile, preprocess } from 'svelte/compiler';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { log } from './log';
|
|
6
|
-
import { CompileOptions, ResolvedOptions } from './options';
|
|
7
|
-
import { toESBuildError } from './error';
|
|
8
|
-
import { StatCollection } from './vite-plugin-svelte-stats';
|
|
3
|
+
import { log } from './log.js';
|
|
4
|
+
import { toESBuildError } from './error.js';
|
|
9
5
|
|
|
10
|
-
|
|
11
|
-
|
|
6
|
+
/**
|
|
7
|
+
* @typedef {NonNullable<import('vite').DepOptimizationOptions['esbuildOptions']>} EsbuildOptions
|
|
8
|
+
* @typedef {NonNullable<EsbuildOptions['plugins']>[number]} EsbuildPlugin
|
|
9
|
+
*/
|
|
12
10
|
|
|
13
11
|
export const facadeEsbuildSveltePluginName = 'vite-plugin-svelte:facade';
|
|
14
12
|
|
|
15
|
-
|
|
13
|
+
/**
|
|
14
|
+
* @param {import('../types/options.d.ts').ResolvedOptions} options
|
|
15
|
+
* @returns {EsbuildPlugin}
|
|
16
|
+
*/
|
|
17
|
+
export function esbuildSveltePlugin(options) {
|
|
16
18
|
return {
|
|
17
19
|
name: 'vite-plugin-svelte:optimize-svelte',
|
|
18
20
|
setup(build) {
|
|
@@ -22,7 +24,8 @@ export function esbuildSveltePlugin(options: ResolvedOptions): EsbuildPlugin {
|
|
|
22
24
|
|
|
23
25
|
const svelteExtensions = (options.extensions ?? ['.svelte']).map((ext) => ext.slice(1));
|
|
24
26
|
const svelteFilter = new RegExp(`\\.(` + svelteExtensions.join('|') + `)(\\?.*)?$`);
|
|
25
|
-
|
|
27
|
+
/** @type {import('../types/vite-plugin-svelte-stats.d.ts').StatCollection | undefined} */
|
|
28
|
+
let statsCollection;
|
|
26
29
|
build.onStart(() => {
|
|
27
30
|
statsCollection = options.stats?.startCollection('prebundle libraries', {
|
|
28
31
|
logResult: (c) => c.stats.length > 1
|
|
@@ -44,17 +47,20 @@ export function esbuildSveltePlugin(options: ResolvedOptions): EsbuildPlugin {
|
|
|
44
47
|
};
|
|
45
48
|
}
|
|
46
49
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
50
|
+
/**
|
|
51
|
+
* @param {import('../types/options.d.ts').ResolvedOptions} options
|
|
52
|
+
* @param {{ filename: string; code: string }} input
|
|
53
|
+
* @param {import('../types/vite-plugin-svelte-stats.d.ts').StatCollection} [statsCollection]
|
|
54
|
+
* @returns {Promise<string>}
|
|
55
|
+
*/
|
|
56
|
+
async function compileSvelte(options, { filename, code }, statsCollection) {
|
|
52
57
|
let css = options.compilerOptions.css;
|
|
53
58
|
if (css !== 'none') {
|
|
54
59
|
// TODO ideally we'd be able to externalize prebundled styles too, but for now always put them in the js
|
|
55
60
|
css = 'injected';
|
|
56
61
|
}
|
|
57
|
-
|
|
62
|
+
/** @type {import('../index.d.ts').CompileOptions} */
|
|
63
|
+
const compileOptions = {
|
|
58
64
|
...options.compilerOptions,
|
|
59
65
|
css,
|
|
60
66
|
filename,
|
|
@@ -93,7 +99,7 @@ async function compileSvelte(
|
|
|
93
99
|
}
|
|
94
100
|
: compileOptions;
|
|
95
101
|
const endStat = statsCollection?.start(filename);
|
|
96
|
-
const compiled = compile(finalCode, finalCompileOptions)
|
|
102
|
+
const compiled = compile(finalCode, finalCompileOptions);
|
|
97
103
|
if (endStat) {
|
|
98
104
|
endStat();
|
|
99
105
|
}
|
|
@@ -5,7 +5,13 @@ const hashes = Object.create(null);
|
|
|
5
5
|
//TODO shorter?
|
|
6
6
|
const hash_length = 12;
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
/**
|
|
9
|
+
* replaces +/= in base64 output so they don't interfere
|
|
10
|
+
*
|
|
11
|
+
* @param {string} input
|
|
12
|
+
* @returns {string} base64 hash safe to use in any context
|
|
13
|
+
*/
|
|
14
|
+
export function safeBase64Hash(input) {
|
|
9
15
|
if (hashes[input]) {
|
|
10
16
|
return hashes[input];
|
|
11
17
|
}
|
|
@@ -19,7 +25,8 @@ export function safeBase64Hash(input: string) {
|
|
|
19
25
|
return hash;
|
|
20
26
|
}
|
|
21
27
|
|
|
22
|
-
|
|
28
|
+
/** @type {Record<string, string>} */
|
|
29
|
+
const replacements = {
|
|
23
30
|
'+': '-',
|
|
24
31
|
'/': '_',
|
|
25
32
|
'=': ''
|
|
@@ -27,6 +34,10 @@ const replacements: { [key: string]: string } = {
|
|
|
27
34
|
|
|
28
35
|
const replaceRE = new RegExp(`[${Object.keys(replacements).join('')}]`, 'g');
|
|
29
36
|
|
|
30
|
-
|
|
37
|
+
/**
|
|
38
|
+
* @param {string} base64
|
|
39
|
+
* @returns {string}
|
|
40
|
+
*/
|
|
41
|
+
function toSafe(base64) {
|
|
31
42
|
return base64.replace(replaceRE, (x) => replacements[x]);
|
|
32
43
|
}
|
|
@@ -1,11 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
import { createFilter } from 'vite';
|
|
3
|
-
import { Arrayable, ResolvedOptions } from './options';
|
|
4
|
-
import { normalizePath } from 'vite';
|
|
1
|
+
import { createFilter, normalizePath } from 'vite';
|
|
5
2
|
import * as fs from 'fs';
|
|
6
|
-
|
|
7
|
-
import { CompileOptions } from 'svelte/types/compiler/interfaces';
|
|
8
|
-
import { log } from './log';
|
|
3
|
+
import { log } from './log.js';
|
|
9
4
|
|
|
10
5
|
const VITE_FS_PREFIX = '/@fs/';
|
|
11
6
|
const IS_WINDOWS = process.platform === 'win32';
|
|
@@ -21,49 +16,27 @@ const SUPPORTED_COMPILER_OPTIONS = [
|
|
|
21
16
|
];
|
|
22
17
|
const TYPES_WITH_COMPILER_OPTIONS = ['style', 'script', 'all'];
|
|
23
18
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
type?: SvelteQueryTypes;
|
|
30
|
-
sourcemap?: boolean;
|
|
31
|
-
compilerOptions?: Pick<
|
|
32
|
-
CompileOptions,
|
|
33
|
-
'generate' | 'dev' | 'css' | 'hydratable' | 'customElement' | 'immutable' | 'enableSourcemap'
|
|
34
|
-
>;
|
|
35
|
-
// vite specific
|
|
36
|
-
url?: boolean;
|
|
37
|
-
raw?: boolean;
|
|
38
|
-
direct?: boolean;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
export interface SvelteRequest {
|
|
42
|
-
id: string;
|
|
43
|
-
cssId: string;
|
|
44
|
-
filename: string;
|
|
45
|
-
normalizedFilename: string;
|
|
46
|
-
query: RequestQuery;
|
|
47
|
-
timestamp: number;
|
|
48
|
-
ssr: boolean;
|
|
49
|
-
raw: boolean;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
function splitId(id: string) {
|
|
19
|
+
/**
|
|
20
|
+
* @param {string} id
|
|
21
|
+
* @returns {{ filename: string, rawQuery: string }}
|
|
22
|
+
*/
|
|
23
|
+
function splitId(id) {
|
|
53
24
|
const parts = id.split(`?`, 2);
|
|
54
25
|
const filename = parts[0];
|
|
55
26
|
const rawQuery = parts[1];
|
|
56
27
|
return { filename, rawQuery };
|
|
57
28
|
}
|
|
58
29
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
)
|
|
30
|
+
/**
|
|
31
|
+
* @param {string} id
|
|
32
|
+
* @param {string} filename
|
|
33
|
+
* @param {string} rawQuery
|
|
34
|
+
* @param {string} root
|
|
35
|
+
* @param {number} timestamp
|
|
36
|
+
* @param {boolean} ssr
|
|
37
|
+
* @returns {import('../types/id.d.ts').SvelteRequest | undefined}
|
|
38
|
+
*/
|
|
39
|
+
function parseToSvelteRequest(id, filename, rawQuery, root, timestamp, ssr) {
|
|
67
40
|
const query = parseRequestQuery(rawQuery);
|
|
68
41
|
const rawOrDirect = !!(query.raw || query.direct);
|
|
69
42
|
if (query.url || (!query.svelte && rawOrDirect)) {
|
|
@@ -86,7 +59,13 @@ function parseToSvelteRequest(
|
|
|
86
59
|
};
|
|
87
60
|
}
|
|
88
61
|
|
|
89
|
-
|
|
62
|
+
/**
|
|
63
|
+
* @param {string} filename
|
|
64
|
+
* @param {string} root
|
|
65
|
+
* @param {import('../types/id.d.ts').SvelteQueryTypes} type
|
|
66
|
+
* @returns {string}
|
|
67
|
+
*/
|
|
68
|
+
function createVirtualImportId(filename, root, type) {
|
|
90
69
|
const parts = ['svelte', `type=${type}`];
|
|
91
70
|
if (type === 'style') {
|
|
92
71
|
parts.push('lang.css');
|
|
@@ -102,7 +81,11 @@ function createVirtualImportId(filename: string, root: string, type: SvelteQuery
|
|
|
102
81
|
return `${filename}?${parts.join('&')}`;
|
|
103
82
|
}
|
|
104
83
|
|
|
105
|
-
|
|
84
|
+
/**
|
|
85
|
+
* @param {string} rawQuery
|
|
86
|
+
* @returns {import('../types/id.d.ts').RequestQuery}
|
|
87
|
+
*/
|
|
88
|
+
function parseRequestQuery(rawQuery) {
|
|
106
89
|
const query = Object.fromEntries(new URLSearchParams(rawQuery));
|
|
107
90
|
for (const key in query) {
|
|
108
91
|
if (query[key] === '') {
|
|
@@ -138,46 +121,62 @@ function parseRequestQuery(rawQuery: string): RequestQuery {
|
|
|
138
121
|
}
|
|
139
122
|
}
|
|
140
123
|
|
|
141
|
-
return
|
|
124
|
+
return /** @type {import('../types/id.d.ts').RequestQuery}*/ query;
|
|
142
125
|
}
|
|
143
126
|
|
|
144
127
|
/**
|
|
145
128
|
* posixify and remove root at start
|
|
146
129
|
*
|
|
147
|
-
* @param filename
|
|
148
|
-
* @param normalizedRoot
|
|
130
|
+
* @param {string} filename
|
|
131
|
+
* @param {string} normalizedRoot
|
|
132
|
+
* @returns {string}
|
|
149
133
|
*/
|
|
150
|
-
function normalize(filename
|
|
134
|
+
function normalize(filename, normalizedRoot) {
|
|
151
135
|
return stripRoot(normalizePath(filename), normalizedRoot);
|
|
152
136
|
}
|
|
153
137
|
|
|
154
|
-
|
|
138
|
+
/**
|
|
139
|
+
* @param {string} filename
|
|
140
|
+
* @param {string} root
|
|
141
|
+
* @returns {boolean}
|
|
142
|
+
*/
|
|
143
|
+
function existsInRoot(filename, root) {
|
|
155
144
|
if (filename.startsWith(VITE_FS_PREFIX)) {
|
|
156
145
|
return false; // vite already tagged it as out of root
|
|
157
146
|
}
|
|
158
147
|
return fs.existsSync(root + filename);
|
|
159
148
|
}
|
|
160
149
|
|
|
161
|
-
|
|
150
|
+
/**
|
|
151
|
+
* @param {string} normalizedFilename
|
|
152
|
+
* @param {string} normalizedRoot
|
|
153
|
+
* @returns {string}
|
|
154
|
+
*/
|
|
155
|
+
function stripRoot(normalizedFilename, normalizedRoot) {
|
|
162
156
|
return normalizedFilename.startsWith(normalizedRoot + '/')
|
|
163
157
|
? normalizedFilename.slice(normalizedRoot.length)
|
|
164
158
|
: normalizedFilename;
|
|
165
159
|
}
|
|
166
160
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
161
|
+
/**
|
|
162
|
+
* @param {import('../index.d.ts').Arrayable<string> | undefined} include
|
|
163
|
+
* @param {import('../index.d.ts').Arrayable<string> | undefined} exclude
|
|
164
|
+
* @param {string[]} extensions
|
|
165
|
+
* @returns {(filename: string) => boolean}
|
|
166
|
+
*/
|
|
167
|
+
function buildFilter(include, exclude, extensions) {
|
|
172
168
|
const rollupFilter = createFilter(include, exclude);
|
|
173
169
|
return (filename) => rollupFilter(filename) && extensions.some((ext) => filename.endsWith(ext));
|
|
174
170
|
}
|
|
175
171
|
|
|
176
|
-
|
|
177
|
-
|
|
172
|
+
/**
|
|
173
|
+
* @param {import('../types/options.d.ts').ResolvedOptions} options
|
|
174
|
+
* @returns {import('../types/id.d.ts').IdParser}
|
|
175
|
+
*/
|
|
176
|
+
export function buildIdParser(options) {
|
|
178
177
|
const { include, exclude, extensions, root } = options;
|
|
179
178
|
const normalizedRoot = normalizePath(root);
|
|
180
|
-
const filter = buildFilter(include, exclude, extensions
|
|
179
|
+
const filter = buildFilter(include, exclude, extensions ?? []);
|
|
181
180
|
return (id, ssr, timestamp = Date.now()) => {
|
|
182
181
|
const { filename, rawQuery } = splitId(id);
|
|
183
182
|
if (filter(filename)) {
|