@vigla/vite-plugin 0.0.0-stage → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api.d.ts +12 -0
- package/dist/api.d.ts.map +1 -0
- package/dist/api.js +1 -0
- package/dist/api.js.map +1 -0
- package/dist/compile.d.ts +16 -0
- package/dist/compile.d.ts.map +1 -0
- package/dist/compile.js +48 -0
- package/dist/compile.js.map +1 -0
- package/dist/compiler.d.ts +115 -0
- package/dist/compiler.d.ts.map +1 -0
- package/dist/compiler.js +1 -0
- package/dist/compiler.js.map +1 -0
- package/dist/config-file.d.ts +10 -0
- package/dist/config-file.d.ts.map +1 -0
- package/dist/config-file.js +63 -0
- package/dist/config-file.js.map +1 -0
- package/dist/dependencies.d.ts +3 -0
- package/dist/dependencies.d.ts.map +1 -0
- package/dist/dependencies.js +40 -0
- package/dist/dependencies.js.map +1 -0
- package/dist/error.d.ts +7 -0
- package/dist/error.d.ts.map +1 -0
- package/dist/error.js +49 -0
- package/dist/error.js.map +1 -0
- package/dist/front-end.d.ts +24 -0
- package/dist/front-end.d.ts.map +1 -0
- package/dist/front-end.js +120 -0
- package/dist/front-end.js.map +1 -0
- package/dist/id.d.ts +40 -0
- package/dist/id.d.ts.map +1 -0
- package/dist/id.js +144 -0
- package/dist/id.js.map +1 -0
- package/dist/identity.d.ts +41 -0
- package/dist/identity.d.ts.map +1 -0
- package/dist/identity.js +31 -0
- package/dist/identity.js.map +1 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +37 -0
- package/dist/index.js.map +1 -0
- package/dist/log.d.ts +17 -0
- package/dist/log.d.ts.map +1 -0
- package/dist/log.js +92 -0
- package/dist/log.js.map +1 -0
- package/dist/maps.d.ts +8 -0
- package/dist/maps.d.ts.map +1 -0
- package/dist/maps.js +37 -0
- package/dist/maps.js.map +1 -0
- package/dist/messages.d.ts +17 -0
- package/dist/messages.d.ts.map +1 -0
- package/dist/messages.js +16 -0
- package/dist/messages.js.map +1 -0
- package/dist/options.d.ts +26 -0
- package/dist/options.d.ts.map +1 -0
- package/dist/options.js +187 -0
- package/dist/options.js.map +1 -0
- package/dist/plugins/compile-module.d.ts +5 -0
- package/dist/plugins/compile-module.d.ts.map +1 -0
- package/dist/plugins/compile-module.js +50 -0
- package/dist/plugins/compile-module.js.map +1 -0
- package/dist/plugins/compile.d.ts +5 -0
- package/dist/plugins/compile.d.ts.map +1 -0
- package/dist/plugins/compile.js +40 -0
- package/dist/plugins/compile.js.map +1 -0
- package/dist/plugins/configure.d.ts +6 -0
- package/dist/plugins/configure.d.ts.map +1 -0
- package/dist/plugins/configure.js +54 -0
- package/dist/plugins/configure.js.map +1 -0
- package/dist/plugins/hot-update.d.ts +5 -0
- package/dist/plugins/hot-update.d.ts.map +1 -0
- package/dist/plugins/hot-update.js +137 -0
- package/dist/plugins/hot-update.js.map +1 -0
- package/dist/plugins/load.d.ts +6 -0
- package/dist/plugins/load.d.ts.map +1 -0
- package/dist/plugins/load.js +79 -0
- package/dist/plugins/load.js.map +1 -0
- package/dist/plugins/optimizer.d.ts +5 -0
- package/dist/plugins/optimizer.d.ts.map +1 -0
- package/dist/plugins/optimizer.js +174 -0
- package/dist/plugins/optimizer.js.map +1 -0
- package/dist/plugins/preprocess.d.ts +11 -0
- package/dist/plugins/preprocess.d.ts.map +1 -0
- package/dist/plugins/preprocess.js +142 -0
- package/dist/plugins/preprocess.js.map +1 -0
- package/dist/plugins/runtime-scan.d.ts +4 -0
- package/dist/plugins/runtime-scan.d.ts.map +1 -0
- package/dist/plugins/runtime-scan.js +56 -0
- package/dist/plugins/runtime-scan.js.map +1 -0
- package/dist/plugins/scan.d.ts +5 -0
- package/dist/plugins/scan.d.ts.map +1 -0
- package/dist/plugins/scan.js +198 -0
- package/dist/plugins/scan.js.map +1 -0
- package/dist/preprocess.d.ts +6 -0
- package/dist/preprocess.d.ts.map +1 -0
- package/dist/preprocess.js +164 -0
- package/dist/preprocess.js.map +1 -0
- package/dist/public.d.ts +47 -0
- package/dist/public.d.ts.map +1 -0
- package/dist/public.js +1 -0
- package/dist/public.js.map +1 -0
- package/dist/vite-config.d.ts +14 -0
- package/dist/vite-config.d.ts.map +1 -0
- package/dist/vite-config.js +167 -0
- package/dist/vite-config.js.map +1 -0
- package/dist/warnings.d.ts +6 -0
- package/dist/warnings.d.ts.map +1 -0
- package/dist/warnings.js +57 -0
- package/dist/warnings.js.map +1 -0
- package/package.json +24 -5
- package/src/api.ts +12 -0
- package/src/compile.ts +96 -0
- package/src/compiler.ts +129 -0
- package/src/config-file.ts +75 -0
- package/src/dependencies.ts +47 -0
- package/src/error.ts +64 -0
- package/src/front-end.ts +146 -0
- package/src/id.ts +225 -0
- package/src/identity.ts +74 -0
- package/src/index.ts +61 -0
- package/src/log.ts +105 -0
- package/src/maps.ts +36 -0
- package/src/messages.ts +40 -0
- package/src/options.ts +257 -0
- package/src/plugins/compile-module.ts +65 -0
- package/src/plugins/compile.ts +49 -0
- package/src/plugins/configure.ts +63 -0
- package/src/plugins/hot-update.ts +159 -0
- package/src/plugins/load.ts +91 -0
- package/src/plugins/optimizer.ts +262 -0
- package/src/plugins/preprocess.ts +163 -0
- package/src/plugins/runtime-scan.ts +75 -0
- package/src/plugins/scan.ts +206 -0
- package/src/preprocess.ts +190 -0
- package/src/public.ts +56 -0
- package/src/vite-config.ts +252 -0
- package/src/warnings.ts +66 -0
- package/README.md +0 -3
package/src/id.ts
ADDED
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import process from 'node:process';
|
|
3
|
+
import { normalizePath } from 'vite';
|
|
4
|
+
import type { CompileOptions } from './compiler.ts';
|
|
5
|
+
import type { FrontEnd } from './front-end.ts';
|
|
6
|
+
import { styleQuery, type Identity } from './identity.ts';
|
|
7
|
+
import { arraify, type ResolvedOptions } from './options.ts';
|
|
8
|
+
|
|
9
|
+
const fsPrefix = '/@fs/';
|
|
10
|
+
const windows = process.platform === 'win32';
|
|
11
|
+
const queryCompilerOptions = ['generate', 'dev', 'css', 'customElement', 'immutable'];
|
|
12
|
+
const typesWithCompilerOptions = ['style', 'script', 'all'];
|
|
13
|
+
|
|
14
|
+
export interface RequestQuery {
|
|
15
|
+
url?: boolean;
|
|
16
|
+
raw?: boolean;
|
|
17
|
+
direct?: boolean;
|
|
18
|
+
type?: string;
|
|
19
|
+
sourcemap?: boolean;
|
|
20
|
+
compilerOptions?: Partial<CompileOptions>;
|
|
21
|
+
[name: string]: unknown;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface ModuleRequest {
|
|
25
|
+
id: string;
|
|
26
|
+
filename: string;
|
|
27
|
+
normalizedFilename: string;
|
|
28
|
+
query: RequestQuery;
|
|
29
|
+
timestamp: number;
|
|
30
|
+
ssr: boolean;
|
|
31
|
+
frontEnd: FrontEnd;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface ComponentRequest extends ModuleRequest {
|
|
35
|
+
cssId: string;
|
|
36
|
+
raw: boolean;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export interface IdFilter {
|
|
40
|
+
id: { include: (string | RegExp)[]; exclude: (string | RegExp)[] };
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export type IdParser = (
|
|
44
|
+
id: string,
|
|
45
|
+
ssr: boolean,
|
|
46
|
+
timestamp?: number
|
|
47
|
+
) => ComponentRequest | undefined;
|
|
48
|
+
export type ModuleIdParser = (
|
|
49
|
+
id: string,
|
|
50
|
+
ssr: boolean,
|
|
51
|
+
timestamp?: number
|
|
52
|
+
) => ModuleRequest | undefined;
|
|
53
|
+
|
|
54
|
+
function split(id: string): { filename: string; rawQuery: string } {
|
|
55
|
+
const [filename = '', rawQuery = ''] = id.split('?', 2);
|
|
56
|
+
return { filename, rawQuery };
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function parseQuery(rawQuery: string, { names, log }: Identity): RequestQuery {
|
|
60
|
+
const query: Record<string, unknown> = Object.fromEntries(new URLSearchParams(rawQuery));
|
|
61
|
+
for (const key in query) if (query[key] === '') query[key] = true;
|
|
62
|
+
const given = query.compilerOptions;
|
|
63
|
+
if (typeof given === 'string') {
|
|
64
|
+
if (!((query.raw || query.direct) && typesWithCompilerOptions.includes(String(query.type)))) {
|
|
65
|
+
throw new Error(
|
|
66
|
+
`Invalid compilerOptions in query ${rawQuery}. CompilerOptions are only supported for raw or direct queries with type in "${typesWithCompilerOptions.join(', ')}" e.g. '?${names.styleFlag}&raw&type=script&compilerOptions={"generate":"server","dev":false}`
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
try {
|
|
70
|
+
const parsed = JSON.parse(given) as Record<string, unknown>;
|
|
71
|
+
const invalid = Object.keys(parsed).filter((key) => !queryCompilerOptions.includes(key));
|
|
72
|
+
if (invalid.length > 0) {
|
|
73
|
+
throw new Error(
|
|
74
|
+
`Invalid compilerOptions in query ${rawQuery}: ${invalid.join(', ')}. Supported: ${queryCompilerOptions.join(', ')}`
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
query.compilerOptions = parsed;
|
|
78
|
+
} catch (error) {
|
|
79
|
+
log.error('failed to parse request query compilerOptions', error);
|
|
80
|
+
throw error;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return query as RequestQuery;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export function normalize(filename: string, root: string): string {
|
|
87
|
+
const normalized = normalizePath(filename);
|
|
88
|
+
return normalized.startsWith(`${root}/`) ? normalized.slice(root.length) : normalized;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function existsInRoot(filename: string, root: string): boolean {
|
|
92
|
+
return !filename.startsWith(fsPrefix) && fs.existsSync(root + filename);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function styleId(filename: string, root: string, identity: Identity): string {
|
|
96
|
+
let path = filename;
|
|
97
|
+
if (existsInRoot(filename, root)) path = root + filename;
|
|
98
|
+
else if (filename.startsWith(fsPrefix)) {
|
|
99
|
+
path = windows ? filename.slice(fsPrefix.length) : filename.slice(fsPrefix.length - 1);
|
|
100
|
+
}
|
|
101
|
+
return `${path}${styleQuery(identity.names)}`;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function escape(text: string): string {
|
|
105
|
+
return text.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function bare(extension: string): string {
|
|
109
|
+
return escape(extension.startsWith('.') ? extension.slice(1) : extension);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function componentPattern(extensions: readonly string[]): RegExp {
|
|
113
|
+
return new RegExp(`^[^?#]+\\.(?:${extensions.map(bare).join('|')})(?:[?#]|$)`);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function modulePattern(infixes: readonly string[], extensions: readonly string[]): RegExp {
|
|
117
|
+
return new RegExp(
|
|
118
|
+
`^[^?#]+(?:${infixes.map(escape).join('|')})(?:[^.\\\\/]+\\.)*(?:${extensions.map(bare).join('|')})(?:[?#]|$)`
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function claims(patterns: readonly RegExp[], frontEnds: readonly FrontEnd[]) {
|
|
123
|
+
return (filename: string): FrontEnd =>
|
|
124
|
+
frontEnds[patterns.findIndex((pattern) => pattern.test(filename))] ??
|
|
125
|
+
(frontEnds[0] as FrontEnd);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function componentPatterns(options: ResolvedOptions, frontEnds: readonly FrontEnd[]): RegExp[] {
|
|
129
|
+
return frontEnds.map((frontEnd) =>
|
|
130
|
+
componentPattern(frontEnds.length === 1 ? options.extensions : frontEnd.components)
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export function buildIdFilter(
|
|
135
|
+
options: ResolvedOptions,
|
|
136
|
+
frontEnds: readonly FrontEnd[],
|
|
137
|
+
{ virtualStyle }: Identity
|
|
138
|
+
): IdFilter {
|
|
139
|
+
return {
|
|
140
|
+
id: {
|
|
141
|
+
include:
|
|
142
|
+
frontEnds.length === 0
|
|
143
|
+
? [/$./]
|
|
144
|
+
: [...componentPatterns(options, frontEnds), ...arraify(options.include)],
|
|
145
|
+
exclude: ['\0', virtualStyle, ...arraify(options.exclude)]
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
export function buildIdParser(
|
|
151
|
+
options: ResolvedOptions,
|
|
152
|
+
frontEnds: readonly FrontEnd[],
|
|
153
|
+
identity: Identity
|
|
154
|
+
): IdParser {
|
|
155
|
+
if (frontEnds.length === 0) return () => undefined;
|
|
156
|
+
const root = normalizePath(options.root);
|
|
157
|
+
const claim = claims(componentPatterns(options, frontEnds), frontEnds);
|
|
158
|
+
return (id, ssr, timestamp = Date.now()) => {
|
|
159
|
+
const { filename, rawQuery } = split(id);
|
|
160
|
+
const query = parseQuery(rawQuery, identity);
|
|
161
|
+
const rawOrDirect = !!(query.raw || query.direct);
|
|
162
|
+
if (query.url || (!query[identity.names.styleFlag] && rawOrDirect)) return undefined;
|
|
163
|
+
return {
|
|
164
|
+
id,
|
|
165
|
+
filename,
|
|
166
|
+
normalizedFilename: normalize(filename, root),
|
|
167
|
+
cssId: styleId(filename, root, identity),
|
|
168
|
+
query,
|
|
169
|
+
timestamp,
|
|
170
|
+
ssr,
|
|
171
|
+
raw: rawOrDirect,
|
|
172
|
+
frontEnd: claim(filename)
|
|
173
|
+
};
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
function modulePatterns(options: ResolvedOptions, frontEnds: readonly FrontEnd[]): RegExp[] {
|
|
178
|
+
const given = frontEnds.length === 1 ? (options.experimental?.compileModule ?? {}) : {};
|
|
179
|
+
return frontEnds.map((frontEnd) =>
|
|
180
|
+
modulePattern(
|
|
181
|
+
given.infixes ?? frontEnd.modules.infixes,
|
|
182
|
+
given.extensions ?? frontEnd.modules.extensions
|
|
183
|
+
)
|
|
184
|
+
);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
export function buildModuleIdFilter(
|
|
188
|
+
options: ResolvedOptions,
|
|
189
|
+
frontEnds: readonly FrontEnd[]
|
|
190
|
+
): IdFilter {
|
|
191
|
+
const given = options.experimental?.compileModule ?? {};
|
|
192
|
+
return {
|
|
193
|
+
id: {
|
|
194
|
+
include:
|
|
195
|
+
frontEnds.length === 0
|
|
196
|
+
? [/$./]
|
|
197
|
+
: [...modulePatterns(options, frontEnds), ...arraify(given.include)],
|
|
198
|
+
exclude: ['\0', ...arraify(given.exclude)]
|
|
199
|
+
}
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
export function buildModuleIdParser(
|
|
204
|
+
options: ResolvedOptions,
|
|
205
|
+
frontEnds: readonly FrontEnd[],
|
|
206
|
+
identity: Identity
|
|
207
|
+
): ModuleIdParser {
|
|
208
|
+
if (frontEnds.length === 0) return () => undefined;
|
|
209
|
+
const root = normalizePath(options.root);
|
|
210
|
+
const claim = claims(modulePatterns(options, frontEnds), frontEnds);
|
|
211
|
+
return (id, ssr, timestamp = Date.now()) => {
|
|
212
|
+
const { filename, rawQuery } = split(id);
|
|
213
|
+
const query = parseQuery(rawQuery, identity);
|
|
214
|
+
if (query.url || query.raw || query.direct) return undefined;
|
|
215
|
+
return {
|
|
216
|
+
id,
|
|
217
|
+
filename,
|
|
218
|
+
normalizedFilename: normalize(filename, root),
|
|
219
|
+
query,
|
|
220
|
+
timestamp,
|
|
221
|
+
ssr,
|
|
222
|
+
frontEnd: claim(filename)
|
|
223
|
+
};
|
|
224
|
+
};
|
|
225
|
+
}
|
package/src/identity.ts
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import type { ResolvedConfig } from 'vite';
|
|
2
|
+
import { createLog, type Log } from './log.ts';
|
|
3
|
+
import { ownMessages, type Messages } from './messages.ts';
|
|
4
|
+
|
|
5
|
+
export interface Links {
|
|
6
|
+
readonly cssHash?: string;
|
|
7
|
+
readonly preprocess?: string;
|
|
8
|
+
readonly missingCondition?: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface Names {
|
|
12
|
+
readonly prebundle: string;
|
|
13
|
+
readonly resolveWarnings: string;
|
|
14
|
+
readonly warningsEvent: string;
|
|
15
|
+
readonly styleFlag: string;
|
|
16
|
+
readonly metaKey: string;
|
|
17
|
+
readonly metadataFile: string;
|
|
18
|
+
readonly withoutSources: readonly string[];
|
|
19
|
+
readonly withoutSourcesPrefixes: readonly string[];
|
|
20
|
+
readonly links: Links;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface History {
|
|
24
|
+
options?(options: Record<string, unknown>, log: Log): void;
|
|
25
|
+
config?(config: ResolvedConfig, log: Log): void;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface Naming {
|
|
29
|
+
readonly name: string;
|
|
30
|
+
readonly names?: Partial<Names>;
|
|
31
|
+
readonly messages?: Partial<Messages>;
|
|
32
|
+
readonly history?: History;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface Identity {
|
|
36
|
+
readonly name: string;
|
|
37
|
+
readonly log: Log;
|
|
38
|
+
readonly names: Names;
|
|
39
|
+
readonly messages: Messages;
|
|
40
|
+
readonly history: History;
|
|
41
|
+
readonly virtualStyle: RegExp;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export const ownNames: Names = {
|
|
45
|
+
prebundle: 'prebundleLibraries',
|
|
46
|
+
resolveWarnings: 'disableResolveWarnings',
|
|
47
|
+
warningsEvent: 'vigla:warnings',
|
|
48
|
+
styleFlag: 'vigla',
|
|
49
|
+
metaKey: 'vigla',
|
|
50
|
+
metadataFile: '_prebundle_metadata.json',
|
|
51
|
+
withoutSources: [],
|
|
52
|
+
withoutSourcesPrefixes: [],
|
|
53
|
+
links: {}
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
function escape(text: string): string {
|
|
57
|
+
return text.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export function styleQuery(names: Names): string {
|
|
61
|
+
return `?${names.styleFlag}&type=style&lang.css`;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export function createIdentity({ name, names, messages, history }: Naming): Identity {
|
|
65
|
+
const resolved: Names = { ...ownNames, ...names };
|
|
66
|
+
return {
|
|
67
|
+
name,
|
|
68
|
+
log: createLog(name),
|
|
69
|
+
names: resolved,
|
|
70
|
+
messages: { ...ownMessages, ...messages },
|
|
71
|
+
history: history ?? {},
|
|
72
|
+
virtualStyle: new RegExp(`[?&]${escape(resolved.styleFlag)}&type=style&lang.css$`)
|
|
73
|
+
};
|
|
74
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import process from 'node:process';
|
|
2
|
+
import type { Plugin, UserConfig } from 'vite';
|
|
3
|
+
import type { PluginAPI } from './api.ts';
|
|
4
|
+
import { loadConfig, type LoadedConfig } from './config-file.ts';
|
|
5
|
+
import { createIdentity, type Naming } from './identity.ts';
|
|
6
|
+
import { compile } from './plugins/compile.ts';
|
|
7
|
+
import { compileModule } from './plugins/compile-module.ts';
|
|
8
|
+
import { configure } from './plugins/configure.ts';
|
|
9
|
+
import { hotUpdate } from './plugins/hot-update.ts';
|
|
10
|
+
import { loadCompiledCss, loadCustom } from './plugins/load.ts';
|
|
11
|
+
import { setupOptimizer } from './plugins/optimizer.ts';
|
|
12
|
+
import { preprocess } from './plugins/preprocess.ts';
|
|
13
|
+
import type { RawOptions } from './options.ts';
|
|
14
|
+
import type { Options } from './public.ts';
|
|
15
|
+
|
|
16
|
+
export { vitePreprocess } from './preprocess.ts';
|
|
17
|
+
export type * from './public.ts';
|
|
18
|
+
export type { PluginAPI } from './api.ts';
|
|
19
|
+
export type { Compiler } from './compiler.ts';
|
|
20
|
+
export type { LoadedConfig } from './config-file.ts';
|
|
21
|
+
export type { FrontEnd } from './front-end.ts';
|
|
22
|
+
export type { History, Links, Names, Naming } from './identity.ts';
|
|
23
|
+
export type { Messages } from './messages.ts';
|
|
24
|
+
export type { Log } from './log.ts';
|
|
25
|
+
|
|
26
|
+
export interface PluginFactory<O extends object = Options> {
|
|
27
|
+
(inline?: Partial<O>): Plugin[];
|
|
28
|
+
readonly marker: string;
|
|
29
|
+
loadConfig(
|
|
30
|
+
viteConfig?: UserConfig,
|
|
31
|
+
inline?: Partial<O>,
|
|
32
|
+
stem?: string
|
|
33
|
+
): Promise<LoadedConfig | undefined>;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function createPlugin<O extends object = Options>(naming: Naming): PluginFactory<O> {
|
|
37
|
+
const identity = createIdentity(naming);
|
|
38
|
+
const { name } = identity;
|
|
39
|
+
const factory = (inline?: Partial<O>): Plugin[] => {
|
|
40
|
+
if (process.env.DEBUG != null) identity.log.setLevel('debug');
|
|
41
|
+
const api = {} as PluginAPI;
|
|
42
|
+
return [
|
|
43
|
+
{ name, api },
|
|
44
|
+
configure(api, identity, inline as RawOptions | undefined),
|
|
45
|
+
setupOptimizer(api, identity),
|
|
46
|
+
loadCompiledCss(api, identity),
|
|
47
|
+
loadCustom(api, identity),
|
|
48
|
+
preprocess(api, identity),
|
|
49
|
+
compile(api, identity),
|
|
50
|
+
compileModule(api, identity),
|
|
51
|
+
hotUpdate(api, identity)
|
|
52
|
+
];
|
|
53
|
+
};
|
|
54
|
+
return Object.assign(factory, {
|
|
55
|
+
marker: name,
|
|
56
|
+
loadConfig: (viteConfig?: UserConfig, inline?: Partial<O>, stem?: string) =>
|
|
57
|
+
loadConfig(identity, viteConfig, inline as RawOptions | undefined, stem)
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export const vigla: PluginFactory<Options> = createPlugin<Options>({ name: 'vigla' });
|
package/src/log.ts
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { styleText } from 'node:util';
|
|
2
|
+
import { createDebug, enabled } from 'obug';
|
|
3
|
+
import type { Warning } from './compiler.ts';
|
|
4
|
+
|
|
5
|
+
type Level = 'debug' | 'info' | 'warn' | 'error' | 'silent';
|
|
6
|
+
|
|
7
|
+
const levels: Level[] = ['debug', 'info', 'warn', 'error', 'silent'];
|
|
8
|
+
const on: Record<Level, boolean> = {
|
|
9
|
+
debug: false,
|
|
10
|
+
info: true,
|
|
11
|
+
warn: true,
|
|
12
|
+
error: true,
|
|
13
|
+
silent: false
|
|
14
|
+
};
|
|
15
|
+
const colors: Record<'info' | 'warn' | 'error', Parameters<typeof styleText>[0]> = {
|
|
16
|
+
info: 'cyan',
|
|
17
|
+
warn: 'yellow',
|
|
18
|
+
error: 'red'
|
|
19
|
+
};
|
|
20
|
+
const sinks = {
|
|
21
|
+
info: (text: unknown) => console.log(text),
|
|
22
|
+
warn: (text: unknown) => console.warn(text),
|
|
23
|
+
error: (text: unknown) => console.error(text)
|
|
24
|
+
};
|
|
25
|
+
let current: Level = 'info';
|
|
26
|
+
|
|
27
|
+
export interface LogFn {
|
|
28
|
+
(message: string, payload?: unknown, namespace?: string): void;
|
|
29
|
+
readonly enabled: boolean;
|
|
30
|
+
once(message: string, payload?: unknown, namespace?: string): void;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface Log {
|
|
34
|
+
readonly debug: LogFn;
|
|
35
|
+
readonly info: LogFn;
|
|
36
|
+
readonly warn: LogFn;
|
|
37
|
+
readonly error: LogFn;
|
|
38
|
+
debugs(namespace: string): boolean;
|
|
39
|
+
setLevel(level: string): void;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function createLog(prefix: string): Log {
|
|
43
|
+
const debugLog = createDebug(prefix);
|
|
44
|
+
const debugs = (namespace: string): boolean => enabled(`${prefix}:${namespace}`);
|
|
45
|
+
|
|
46
|
+
function write(level: Level, message: string, payload?: unknown, namespace?: string): void {
|
|
47
|
+
if (!on[level]) return;
|
|
48
|
+
if (level === 'debug') {
|
|
49
|
+
if (namespace !== undefined && !debugs(namespace)) return;
|
|
50
|
+
const debug = namespace === undefined ? debugLog : debugLog.extend(namespace);
|
|
51
|
+
if (payload !== undefined) debug(message, payload);
|
|
52
|
+
else debug(message);
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
if (level === 'silent') return;
|
|
56
|
+
const scope = namespace === undefined ? prefix : `${prefix}:${namespace}`;
|
|
57
|
+
const line = `${new Date().toLocaleTimeString()} [${scope}] ${message}`;
|
|
58
|
+
sinks[level](styleText(colors[level], line));
|
|
59
|
+
if (payload) sinks[level](payload);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function logger(level: Level): LogFn {
|
|
63
|
+
const logged = new Set<string>();
|
|
64
|
+
const fn = ((message: string, payload?: unknown, namespace?: string) =>
|
|
65
|
+
write(level, message, payload, namespace)) as LogFn;
|
|
66
|
+
Object.defineProperty(fn, 'enabled', { get: () => on[level] });
|
|
67
|
+
Object.defineProperty(fn, 'once', {
|
|
68
|
+
value: (message: string, payload?: unknown, namespace?: string) => {
|
|
69
|
+
if (!on[level] || logged.has(message)) return;
|
|
70
|
+
logged.add(message);
|
|
71
|
+
write(level, message, payload, namespace);
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
return fn;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return {
|
|
78
|
+
debug: logger('debug'),
|
|
79
|
+
info: logger('info'),
|
|
80
|
+
warn: logger('warn'),
|
|
81
|
+
error: logger('error'),
|
|
82
|
+
debugs,
|
|
83
|
+
setLevel(level) {
|
|
84
|
+
if (level === current) return;
|
|
85
|
+
const index = levels.indexOf(level as Level);
|
|
86
|
+
if (index < 0) {
|
|
87
|
+
write('error', `invalid log level: ${level} `);
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
current = level as Level;
|
|
91
|
+
levels.forEach((name, at) => (on[name] = at >= index));
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export function buildExtendedLogMessage(warning: Warning): string {
|
|
97
|
+
const parts: (string | number)[] = [];
|
|
98
|
+
if (warning.filename) parts.push(warning.filename);
|
|
99
|
+
if (warning.start) parts.push(':', warning.start.line, ':', warning.start.column);
|
|
100
|
+
if (warning.message) {
|
|
101
|
+
if (parts.length > 0) parts.push(' ');
|
|
102
|
+
parts.push(warning.message);
|
|
103
|
+
}
|
|
104
|
+
return parts.join('');
|
|
105
|
+
}
|
package/src/maps.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import process from 'node:process';
|
|
3
|
+
|
|
4
|
+
const windows = process.platform === 'win32';
|
|
5
|
+
|
|
6
|
+
export interface FileRefs {
|
|
7
|
+
file?: string;
|
|
8
|
+
sources?: (string | null)[];
|
|
9
|
+
sourceRoot?: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function mapToRelative(map: FileRefs | null | undefined, filename: string): void {
|
|
13
|
+
if (!map) return;
|
|
14
|
+
const root = map.sourceRoot;
|
|
15
|
+
const dirname = path.dirname(filename);
|
|
16
|
+
const relative = (source: string | null): string | null => {
|
|
17
|
+
if (!source) return source;
|
|
18
|
+
let full: string;
|
|
19
|
+
if (source.startsWith('file:///')) full = source.slice(windows ? 8 : 7);
|
|
20
|
+
else if (root)
|
|
21
|
+
full = `${root}${root.endsWith('/') || source.startsWith('/') ? '' : '/'}${source}`;
|
|
22
|
+
else full = source;
|
|
23
|
+
return path.isAbsolute(full) ? path.relative(dirname, full) : full;
|
|
24
|
+
};
|
|
25
|
+
if (map.file) map.file = path.basename(filename);
|
|
26
|
+
if (map.sources) map.sources = map.sources.map(relative);
|
|
27
|
+
if (map.sourceRoot) delete map.sourceRoot;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function removeLangSuffix(map: FileRefs | null | undefined, suffix: string): void {
|
|
31
|
+
if (!map) return;
|
|
32
|
+
const strip = (source: string | null) =>
|
|
33
|
+
source?.endsWith(suffix) ? source.slice(0, -suffix.length) : source;
|
|
34
|
+
if (map.file) map.file = strip(map.file) ?? undefined;
|
|
35
|
+
if (map.sources) map.sources = map.sources.map(strip);
|
|
36
|
+
}
|
package/src/messages.ts
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export interface Messages {
|
|
2
|
+
readonly configChangeDetected: string;
|
|
3
|
+
readonly configChanged: (file: string) => string;
|
|
4
|
+
readonly noClientEnvironment: string;
|
|
5
|
+
readonly configNotFound: (file: string) => string;
|
|
6
|
+
readonly configAbsent: (root: string) => string;
|
|
7
|
+
readonly configsMultiple: (file: string) => string;
|
|
8
|
+
readonly optionsMisplaced: (keys: string) => string;
|
|
9
|
+
readonly optionsAtRoot: (keys: string) => string;
|
|
10
|
+
readonly optionsDuplicate: (keys: string) => string;
|
|
11
|
+
readonly optionsUnknown: (keys: string) => string;
|
|
12
|
+
readonly cssHash: string;
|
|
13
|
+
readonly controlledOptions: (plugin: string, keys: string) => string;
|
|
14
|
+
readonly missingCondition: (conditions: readonly string[]) => string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export const ownMessages: Messages = {
|
|
18
|
+
configChangeDetected:
|
|
19
|
+
'Config file change detected, restart your dev process to apply the changes.',
|
|
20
|
+
configChanged: (file) => `config file changed: restarting vite server. - file: ${file}`,
|
|
21
|
+
noClientEnvironment:
|
|
22
|
+
'No client environment found, not adding watchers for config file and preprocessor dependencies',
|
|
23
|
+
configNotFound: (file) => `failed to find config file ${file}.`,
|
|
24
|
+
configAbsent: (root) => `no config file found at ${root} - using default configuration.`,
|
|
25
|
+
configsMultiple: (file) =>
|
|
26
|
+
`found more than one config file, using ${file}. you should only have one!`,
|
|
27
|
+
optionsMisplaced: (keys) =>
|
|
28
|
+
`Invalid options in config file. Move the following options into 'vitePlugin:{...}': ${keys}`,
|
|
29
|
+
optionsAtRoot: (keys) =>
|
|
30
|
+
`Invalid options in config file under vitePlugin:{...}', move them to the config root : ${keys}`,
|
|
31
|
+
optionsDuplicate: (keys) =>
|
|
32
|
+
`Invalid duplicate options in config file under vitePlugin:{...}', they are defined in root too and must only exist once: ${keys}`,
|
|
33
|
+
optionsUnknown: (keys) =>
|
|
34
|
+
`ignoring unknown plugin options in config file under vitePlugin:{...}: ${keys}`,
|
|
35
|
+
cssHash: 'The custom compilerOptions.cssHash in your config can degrade your DX.',
|
|
36
|
+
controlledOptions: (plugin, keys) =>
|
|
37
|
+
`The following compilerOptions are controlled by ${plugin} and essential to its functionality. User-specified values are ignored. Please remove them from your configuration: ${keys}`,
|
|
38
|
+
missingCondition: (conditions) =>
|
|
39
|
+
`The following packages have a ${conditions.join(' or ')} field in their package.json but no exports condition for it.`
|
|
40
|
+
};
|