@pit-frontend-framework/unplugin-vue-components 1.0.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/LICENSE +21 -0
- package/README.md +464 -0
- package/dist/esbuild.d.mts +6 -0
- package/dist/esbuild.mjs +5 -0
- package/dist/index.d.mts +11 -0
- package/dist/index.mjs +3 -0
- package/dist/nuxt.d.mts +7 -0
- package/dist/nuxt.mjs +9 -0
- package/dist/resolvers.d.mts +552 -0
- package/dist/resolvers.mjs +2007 -0
- package/dist/rolldown.d.mts +6 -0
- package/dist/rolldown.mjs +5 -0
- package/dist/rollup.d.mts +6 -0
- package/dist/rollup.mjs +5 -0
- package/dist/rspack.d.mts +6 -0
- package/dist/rspack.mjs +5 -0
- package/dist/src-S1kwY0Q8.mjs +656 -0
- package/dist/types-BbnOeCab.d.mts +217 -0
- package/dist/types.d.mts +2 -0
- package/dist/types.mjs +1 -0
- package/dist/utils-BfjsfvcK.mjs +229 -0
- package/dist/vite.d.mts +9 -0
- package/dist/vite.mjs +5 -0
- package/dist/webpack.d.mts +6 -0
- package/dist/webpack.mjs +5 -0
- package/package.json +95 -0
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { u as Options } from "./types-BbnOeCab.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/rolldown.d.ts
|
|
4
|
+
declare const rolldown: (options: Options) => import("rolldown").Plugin<any>[] | import("rolldown").Plugin<any>;
|
|
5
|
+
//#endregion
|
|
6
|
+
export { rolldown as default, rolldown as "module.exports" };
|
package/dist/rollup.mjs
ADDED
package/dist/rspack.mjs
ADDED
|
@@ -0,0 +1,656 @@
|
|
|
1
|
+
import { _ as notNullish, a as getTransformedPath, b as toArray, d as parseId, f as pascalCase, g as DISABLE_COMMENT, h as stringifyComponentImport, l as matchGlobs, m as shouldTransform, n as escapeSpecialChars, o as isExclude, p as resolveAlias, r as getNameFromFilePath, u as normalizeComponentInfo, v as slash, y as throttle } from "./utils-BfjsfvcK.mjs";
|
|
2
|
+
import { existsSync } from "node:fs";
|
|
3
|
+
import process from "node:process";
|
|
4
|
+
import chokidar from "chokidar";
|
|
5
|
+
import { glob, globSync } from "tinyglobby";
|
|
6
|
+
import { createUnplugin } from "unplugin";
|
|
7
|
+
import { createFilter } from "unplugin-utils";
|
|
8
|
+
import { dirname, isAbsolute, join, relative, resolve } from "node:path";
|
|
9
|
+
import { createDebug } from "obug";
|
|
10
|
+
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
11
|
+
import { isPackageExists } from "local-pkg";
|
|
12
|
+
import MagicString from "magic-string";
|
|
13
|
+
//#region src/core/type-imports/index.ts
|
|
14
|
+
const TypeImportPresets = [{
|
|
15
|
+
from: "vue-router",
|
|
16
|
+
names: ["RouterView", "RouterLink"]
|
|
17
|
+
}, {
|
|
18
|
+
from: "vue-starport",
|
|
19
|
+
names: ["Starport", "StarportCarrier"]
|
|
20
|
+
}];
|
|
21
|
+
//#endregion
|
|
22
|
+
//#region src/core/type-imports/detect.ts
|
|
23
|
+
function detectTypeImports() {
|
|
24
|
+
return TypeImportPresets.map((i) => isPackageExists(i.from) ? i : void 0).filter(notNullish);
|
|
25
|
+
}
|
|
26
|
+
function resolveTypeImports(imports) {
|
|
27
|
+
return imports.flatMap((i) => i.names.map((n) => ({
|
|
28
|
+
from: i.from,
|
|
29
|
+
name: n,
|
|
30
|
+
as: n
|
|
31
|
+
})));
|
|
32
|
+
}
|
|
33
|
+
//#endregion
|
|
34
|
+
//#region src/core/declaration.ts
|
|
35
|
+
const multilineCommentsRE = /\/\*.*?\*\//gs;
|
|
36
|
+
const singlelineCommentsRE = /\/\/.*$/gm;
|
|
37
|
+
function extractImports(code) {
|
|
38
|
+
return Object.fromEntries(Array.from(code.matchAll(/['"]?([^\s'"]+)['"]?\s*:\s*(.+?)[,;\r\n]/g)).map((i) => [i[1], i[2]]));
|
|
39
|
+
}
|
|
40
|
+
function parseDeclaration(code) {
|
|
41
|
+
if (!code) return;
|
|
42
|
+
code = code.replace(multilineCommentsRE, "").replace(singlelineCommentsRE, "");
|
|
43
|
+
const imports = {
|
|
44
|
+
component: {},
|
|
45
|
+
directive: {}
|
|
46
|
+
};
|
|
47
|
+
const componentDeclaration = /export\s+interface\s+GlobalComponents\s*\{.*?\}/s.exec(code)?.[0];
|
|
48
|
+
if (componentDeclaration) imports.component = extractImports(componentDeclaration);
|
|
49
|
+
const directiveDeclaration = /export\s+interface\s+GlobalDirectives\s*\{.*?\}/s.exec(code)?.[0];
|
|
50
|
+
if (directiveDeclaration) imports.directive = extractImports(directiveDeclaration);
|
|
51
|
+
return imports;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Converts `ComponentInfo` to an array
|
|
55
|
+
*
|
|
56
|
+
* `[name, "typeof import(path)[importName]"]`
|
|
57
|
+
*/
|
|
58
|
+
function stringifyComponentInfo(filepath, { from: path, as: name, name: importName }, importPathTransform) {
|
|
59
|
+
if (!name) return void 0;
|
|
60
|
+
path = getTransformedPath(path, importPathTransform);
|
|
61
|
+
return [name, `typeof import('${slash(isAbsolute(path) ? `./${relative(dirname(filepath), path)}` : path)}')['${importName || "default"}']`];
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Converts array of `ComponentInfo` to an import map
|
|
65
|
+
*
|
|
66
|
+
* `{ name: "typeof import(path)[importName]", ... }`
|
|
67
|
+
*/
|
|
68
|
+
function stringifyComponentsInfo(filepath, components, importPathTransform) {
|
|
69
|
+
return Object.fromEntries(components.map((info) => stringifyComponentInfo(filepath, info, importPathTransform)).filter(notNullish));
|
|
70
|
+
}
|
|
71
|
+
function getDeclarationImports(ctx, filepath) {
|
|
72
|
+
const component = stringifyComponentsInfo(filepath, [...Object.values({
|
|
73
|
+
...ctx.componentNameMap,
|
|
74
|
+
...ctx.componentCustomMap
|
|
75
|
+
}), ...resolveTypeImports(ctx.options.types)], ctx.options.importPathTransform);
|
|
76
|
+
const directive = stringifyComponentsInfo(filepath, Object.values(ctx.directiveCustomMap), ctx.options.importPathTransform);
|
|
77
|
+
if (Object.keys(component).length + Object.keys(directive).length === 0) return;
|
|
78
|
+
return {
|
|
79
|
+
component,
|
|
80
|
+
directive
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
function stringifyDeclarationImports(imports) {
|
|
84
|
+
return Object.entries(imports).sort(([a], [b]) => a.localeCompare(b)).map(([name, v]) => {
|
|
85
|
+
if (!/^\w+$/.test(name)) name = `'${name}'`;
|
|
86
|
+
return `${name}: ${v}`;
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
function getDeclaration(ctx, filepath, originalImports) {
|
|
90
|
+
const imports = getDeclarationImports(ctx, filepath);
|
|
91
|
+
if (!imports) return;
|
|
92
|
+
const declarations = {
|
|
93
|
+
component: stringifyDeclarationImports({
|
|
94
|
+
...originalImports?.component,
|
|
95
|
+
...imports.component
|
|
96
|
+
}),
|
|
97
|
+
directive: stringifyDeclarationImports({
|
|
98
|
+
...originalImports?.directive,
|
|
99
|
+
...imports.directive
|
|
100
|
+
})
|
|
101
|
+
};
|
|
102
|
+
let code = `/* eslint-disable */
|
|
103
|
+
// @ts-nocheck
|
|
104
|
+
// biome-ignore lint: disable
|
|
105
|
+
// oxlint-disable
|
|
106
|
+
// ------
|
|
107
|
+
// Generated by unplugin-vue-components
|
|
108
|
+
// Read more: https://github.com/vuejs/core/pull/3399
|
|
109
|
+
${ctx.options.dtsTsx ? `import { GlobalComponents } from 'vue'\n` : ""}
|
|
110
|
+
export {}
|
|
111
|
+
|
|
112
|
+
/* prettier-ignore */
|
|
113
|
+
declare module 'vue' {`;
|
|
114
|
+
if (Object.keys(declarations.component).length > 0) code += `
|
|
115
|
+
export interface GlobalComponents {
|
|
116
|
+
${declarations.component.join("\n ")}
|
|
117
|
+
}`;
|
|
118
|
+
if (Object.keys(declarations.directive).length > 0) code += `
|
|
119
|
+
export interface GlobalDirectives {
|
|
120
|
+
${declarations.directive.join("\n ")}
|
|
121
|
+
}`;
|
|
122
|
+
code += "\n}\n";
|
|
123
|
+
if (ctx.options.dtsTsx) {
|
|
124
|
+
if (Object.keys(declarations.component).length > 0) code += `
|
|
125
|
+
// For TSX support
|
|
126
|
+
declare global {
|
|
127
|
+
${declarations.component.map((d) => d.replace(/(.+):/, "const $1:")).join("\n ")}
|
|
128
|
+
}`;
|
|
129
|
+
}
|
|
130
|
+
return code;
|
|
131
|
+
}
|
|
132
|
+
async function writeFile$1(filePath, content) {
|
|
133
|
+
await mkdir(dirname(filePath), { recursive: true });
|
|
134
|
+
return await writeFile(filePath, content, "utf-8");
|
|
135
|
+
}
|
|
136
|
+
async function writeDeclaration(ctx, filepath, removeUnused = false) {
|
|
137
|
+
const originalContent = existsSync(filepath) ? await readFile(filepath, "utf-8") : "";
|
|
138
|
+
const code = getDeclaration(ctx, filepath, removeUnused ? void 0 : parseDeclaration(originalContent));
|
|
139
|
+
if (!code) return;
|
|
140
|
+
if (code !== originalContent) await writeFile$1(filepath, code);
|
|
141
|
+
}
|
|
142
|
+
async function writeComponentsJson(ctx, _removeUnused = false) {
|
|
143
|
+
if (!ctx.dumpComponentsInfoPath) return;
|
|
144
|
+
const components = [...Object.entries({
|
|
145
|
+
...ctx.componentNameMap,
|
|
146
|
+
...ctx.componentCustomMap
|
|
147
|
+
}).map(([_, { name, as, from }]) => ({
|
|
148
|
+
name: name || "default",
|
|
149
|
+
as,
|
|
150
|
+
from
|
|
151
|
+
})), ...resolveTypeImports(ctx.options.types)];
|
|
152
|
+
await writeFile$1(ctx.dumpComponentsInfoPath, JSON.stringify(components, null, 2));
|
|
153
|
+
}
|
|
154
|
+
//#endregion
|
|
155
|
+
//#region src/core/fs/glob.ts
|
|
156
|
+
const debug$4 = createDebug("unplugin-vue-components:glob");
|
|
157
|
+
function searchComponents(ctx) {
|
|
158
|
+
debug$4(`started with: [${ctx.options.globs.join(", ")}]`);
|
|
159
|
+
const root = ctx.root;
|
|
160
|
+
const files = globSync(ctx.options.globs, {
|
|
161
|
+
ignore: ctx.options.globsExclude,
|
|
162
|
+
onlyFiles: true,
|
|
163
|
+
cwd: root,
|
|
164
|
+
absolute: true,
|
|
165
|
+
expandDirectories: false
|
|
166
|
+
});
|
|
167
|
+
if (!files.length && !ctx.options.resolvers?.length) console.warn("[unplugin-vue-components] no components found");
|
|
168
|
+
debug$4(`${files.length} components found.`);
|
|
169
|
+
ctx.addComponents(files);
|
|
170
|
+
}
|
|
171
|
+
//#endregion
|
|
172
|
+
//#region src/core/options.ts
|
|
173
|
+
const defaultOptions = {
|
|
174
|
+
dirs: "src/components",
|
|
175
|
+
extensions: "vue",
|
|
176
|
+
deep: true,
|
|
177
|
+
dts: isPackageExists("typescript"),
|
|
178
|
+
dtsTsx: isPackageExists("@vitejs/plugin-vue-jsx"),
|
|
179
|
+
directoryAsNamespace: false,
|
|
180
|
+
collapseSamePrefixes: false,
|
|
181
|
+
globalNamespaces: [],
|
|
182
|
+
transformerUserResolveFunctions: true,
|
|
183
|
+
resolvers: [],
|
|
184
|
+
importPathTransform: (v) => v,
|
|
185
|
+
allowOverrides: false,
|
|
186
|
+
sourcemap: true,
|
|
187
|
+
dumpComponentsInfo: false,
|
|
188
|
+
syncMode: "default",
|
|
189
|
+
prefix: ""
|
|
190
|
+
};
|
|
191
|
+
function normalizeResolvers(resolvers) {
|
|
192
|
+
return toArray(resolvers).flat().map((r) => typeof r === "function" ? {
|
|
193
|
+
resolve: r,
|
|
194
|
+
type: "component"
|
|
195
|
+
} : r);
|
|
196
|
+
}
|
|
197
|
+
function resolveGlobsExclude(root, glob) {
|
|
198
|
+
const excludeReg = /^!/;
|
|
199
|
+
return slash(`${excludeReg.test(glob) ? "!" : ""}${resolve(root, glob.replace(excludeReg, ""))}`);
|
|
200
|
+
}
|
|
201
|
+
function resolveOptions(options, root) {
|
|
202
|
+
const resolved = Object.assign({}, defaultOptions, options);
|
|
203
|
+
resolved.resolvers = normalizeResolvers(resolved.resolvers);
|
|
204
|
+
resolved.extensions = toArray(resolved.extensions);
|
|
205
|
+
if (resolved.globs) {
|
|
206
|
+
resolved.globs = toArray(resolved.globs).map((glob) => resolveGlobsExclude(root, glob));
|
|
207
|
+
resolved.resolvedDirs = [];
|
|
208
|
+
} else {
|
|
209
|
+
const extsGlob = resolved.extensions.length === 1 ? resolved.extensions : `{${resolved.extensions.join(",")}}`;
|
|
210
|
+
resolved.dirs = toArray(resolved.dirs);
|
|
211
|
+
const globs = resolved.dirs.map((i) => resolveGlobsExclude(root, i));
|
|
212
|
+
resolved.resolvedDirs = globs.filter((i) => !i.startsWith("!"));
|
|
213
|
+
resolved.globs = globs.map((i) => {
|
|
214
|
+
let prefix = "";
|
|
215
|
+
if (i.startsWith("!")) {
|
|
216
|
+
prefix = "!";
|
|
217
|
+
i = i.slice(1);
|
|
218
|
+
}
|
|
219
|
+
return resolved.deep ? prefix + escapeSpecialChars(slash(join(i, `**/*.${extsGlob}`))) : prefix + escapeSpecialChars(slash(join(i, `*.${extsGlob}`)));
|
|
220
|
+
});
|
|
221
|
+
if (!resolved.extensions.length) throw new Error("[unplugin-vue-components] `extensions` option is required to search for components");
|
|
222
|
+
}
|
|
223
|
+
resolved.globsExclude = toArray(resolved.globsExclude || []).map((i) => resolveGlobsExclude(root, i));
|
|
224
|
+
resolved.globs = resolved.globs.filter((i) => {
|
|
225
|
+
if (!i.startsWith("!")) return true;
|
|
226
|
+
resolved.globsExclude.push(i.slice(1));
|
|
227
|
+
return false;
|
|
228
|
+
});
|
|
229
|
+
resolved.dts = !resolved.dts ? false : resolve(root, typeof resolved.dts === "string" ? resolved.dts : "components.d.ts");
|
|
230
|
+
if (!resolved.types && resolved.dts) resolved.types = detectTypeImports();
|
|
231
|
+
resolved.types = resolved.types || [];
|
|
232
|
+
resolved.root = root;
|
|
233
|
+
resolved.directives ??= resolved.resolvers.some((i) => i.type === "directive");
|
|
234
|
+
return resolved;
|
|
235
|
+
}
|
|
236
|
+
//#endregion
|
|
237
|
+
//#region src/core/transforms/component.ts
|
|
238
|
+
const debug$3 = createDebug("unplugin-vue-components:transform:component");
|
|
239
|
+
function resolveVue3$1(code, s, transformerUserResolveFunctions) {
|
|
240
|
+
const results = [];
|
|
241
|
+
/**
|
|
242
|
+
* when using some plugin like plugin-vue-jsx, resolveComponent will be imported as resolveComponent1 to avoid duplicate import
|
|
243
|
+
*/
|
|
244
|
+
for (const match of code.matchAll(/_?resolveComponent\d*\("(.+?)"\)/g)) {
|
|
245
|
+
if (!transformerUserResolveFunctions && !match[0].startsWith("_")) continue;
|
|
246
|
+
const matchedName = match[1];
|
|
247
|
+
if (match.index != null && matchedName && !matchedName.startsWith("_")) {
|
|
248
|
+
const start = match.index;
|
|
249
|
+
const end = start + match[0].length;
|
|
250
|
+
results.push({
|
|
251
|
+
rawName: matchedName,
|
|
252
|
+
replace: (resolved) => s.overwrite(start, end, resolved)
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
return results;
|
|
257
|
+
}
|
|
258
|
+
async function transformComponent(code, s, ctx, sfcPath) {
|
|
259
|
+
let no = 0;
|
|
260
|
+
const results = resolveVue3$1(code, s, ctx.options.transformerUserResolveFunctions);
|
|
261
|
+
for (const { rawName, replace } of results) {
|
|
262
|
+
debug$3(`| ${rawName}`);
|
|
263
|
+
const name = pascalCase(rawName);
|
|
264
|
+
ctx.updateUsageMap(sfcPath, [name]);
|
|
265
|
+
const component = await ctx.findComponent(name, "component", [sfcPath]);
|
|
266
|
+
if (component) {
|
|
267
|
+
const varName = `__unplugin_components_${no}`;
|
|
268
|
+
s.prepend(`${stringifyComponentImport({
|
|
269
|
+
...component,
|
|
270
|
+
as: varName
|
|
271
|
+
}, ctx)};\n`);
|
|
272
|
+
no += 1;
|
|
273
|
+
replace(varName);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
debug$3(`^ (${no})`);
|
|
277
|
+
}
|
|
278
|
+
//#endregion
|
|
279
|
+
//#region src/core/transforms/directive.ts
|
|
280
|
+
const debug$2 = createDebug("unplugin-vue-components:transform:directive");
|
|
281
|
+
async function transformDirective(code, s, ctx, sfcPath) {
|
|
282
|
+
let no = 0;
|
|
283
|
+
const results = resolveVue3(code, s, ctx.options.transformerUserResolveFunctions);
|
|
284
|
+
for (const { rawName, replace } of results) {
|
|
285
|
+
debug$2(`| ${rawName}`);
|
|
286
|
+
const name = `v${pascalCase(rawName)}`;
|
|
287
|
+
ctx.updateUsageMap(sfcPath, [name]);
|
|
288
|
+
const directive = await ctx.findComponent(name, "directive", [sfcPath]);
|
|
289
|
+
if (!directive) continue;
|
|
290
|
+
const varName = `__unplugin_directives_${no}`;
|
|
291
|
+
s.prepend(`${stringifyComponentImport({
|
|
292
|
+
...directive,
|
|
293
|
+
as: varName
|
|
294
|
+
}, ctx)};\n`);
|
|
295
|
+
no += 1;
|
|
296
|
+
replace(varName);
|
|
297
|
+
}
|
|
298
|
+
debug$2(`^ (${no})`);
|
|
299
|
+
}
|
|
300
|
+
function resolveVue3(code, s, transformerUserResolveFunctions) {
|
|
301
|
+
const results = [];
|
|
302
|
+
for (const match of code.matchAll(/_?resolveDirective\("(.+?)"\)/g)) {
|
|
303
|
+
const matchedName = match[1];
|
|
304
|
+
if (!transformerUserResolveFunctions && !match[0].startsWith("_")) continue;
|
|
305
|
+
if (match.index != null && matchedName && !matchedName.startsWith("_")) {
|
|
306
|
+
const start = match.index;
|
|
307
|
+
const end = start + match[0].length;
|
|
308
|
+
results.push({
|
|
309
|
+
rawName: matchedName,
|
|
310
|
+
replace: (resolved) => s.overwrite(start, end, resolved)
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
return results;
|
|
315
|
+
}
|
|
316
|
+
//#endregion
|
|
317
|
+
//#region src/core/transformer.ts
|
|
318
|
+
const debug$1 = createDebug("unplugin-vue-components:transformer");
|
|
319
|
+
function transformer(ctx) {
|
|
320
|
+
return async (code, id, path) => {
|
|
321
|
+
ctx.searchGlob();
|
|
322
|
+
const sfcPath = ctx.normalizePath(path);
|
|
323
|
+
debug$1(sfcPath);
|
|
324
|
+
const s = new MagicString(code);
|
|
325
|
+
await transformComponent(code, s, ctx, sfcPath);
|
|
326
|
+
if (ctx.options.directives) await transformDirective(code, s, ctx, sfcPath);
|
|
327
|
+
s.prepend(DISABLE_COMMENT);
|
|
328
|
+
const result = { code: s.toString() };
|
|
329
|
+
if (ctx.sourcemap) result.map = s.generateMap({
|
|
330
|
+
source: id,
|
|
331
|
+
includeContent: true,
|
|
332
|
+
hires: "boundary"
|
|
333
|
+
});
|
|
334
|
+
return result;
|
|
335
|
+
};
|
|
336
|
+
}
|
|
337
|
+
//#endregion
|
|
338
|
+
//#region src/core/context.ts
|
|
339
|
+
const debug = {
|
|
340
|
+
components: createDebug("unplugin-vue-components:context:components"),
|
|
341
|
+
search: createDebug("unplugin-vue-components:context:search"),
|
|
342
|
+
hmr: createDebug("unplugin-vue-components:context:hmr"),
|
|
343
|
+
declaration: createDebug("unplugin-vue-components:declaration"),
|
|
344
|
+
env: createDebug("unplugin-vue-components:env")
|
|
345
|
+
};
|
|
346
|
+
var Context = class {
|
|
347
|
+
rawOptions;
|
|
348
|
+
options;
|
|
349
|
+
transformer;
|
|
350
|
+
_componentPaths = /* @__PURE__ */ new Set();
|
|
351
|
+
_componentNameMap = {};
|
|
352
|
+
_componentUsageMap = {};
|
|
353
|
+
_componentCustomMap = {};
|
|
354
|
+
_directiveCustomMap = {};
|
|
355
|
+
_removeUnused = false;
|
|
356
|
+
_server;
|
|
357
|
+
root = process.cwd();
|
|
358
|
+
sourcemap = true;
|
|
359
|
+
alias = {};
|
|
360
|
+
dumpComponentsInfoPath;
|
|
361
|
+
constructor(rawOptions) {
|
|
362
|
+
this.rawOptions = rawOptions;
|
|
363
|
+
this.options = resolveOptions(rawOptions, this.root);
|
|
364
|
+
this.sourcemap = rawOptions.sourcemap ?? true;
|
|
365
|
+
this.generateDeclaration = throttle(500, this._generateDeclaration.bind(this), { noLeading: false });
|
|
366
|
+
this._removeUnused = this.options.syncMode !== "append";
|
|
367
|
+
if (this.options.dumpComponentsInfo) {
|
|
368
|
+
const dumpComponentsInfo = this.options.dumpComponentsInfo === true ? "./.components-info.json" : this.options.dumpComponentsInfo ?? false;
|
|
369
|
+
this.dumpComponentsInfoPath = dumpComponentsInfo;
|
|
370
|
+
this.generateComponentsJson = throttle(500, this._generateComponentsJson.bind(this), { noLeading: false });
|
|
371
|
+
}
|
|
372
|
+
this.transformer = transformer(this);
|
|
373
|
+
}
|
|
374
|
+
setRoot(root) {
|
|
375
|
+
if (this.root === root) return;
|
|
376
|
+
debug.env("root", root);
|
|
377
|
+
this.root = root;
|
|
378
|
+
this.options = resolveOptions(this.rawOptions, this.root);
|
|
379
|
+
}
|
|
380
|
+
transform(code, id) {
|
|
381
|
+
const { path, query } = parseId(id);
|
|
382
|
+
return this.transformer(code, id, path, query);
|
|
383
|
+
}
|
|
384
|
+
setupViteServer(server) {
|
|
385
|
+
if (this._server === server) return;
|
|
386
|
+
this._server = server;
|
|
387
|
+
this._removeUnused = this.options.syncMode === "overwrite";
|
|
388
|
+
this.setupWatcher(server.watcher);
|
|
389
|
+
}
|
|
390
|
+
setupWatcher(watcher) {
|
|
391
|
+
const { globs } = this.options;
|
|
392
|
+
this._removeUnused = this.options.syncMode === "overwrite";
|
|
393
|
+
watcher.on("unlink", (path) => {
|
|
394
|
+
if (!matchGlobs(path, globs)) return;
|
|
395
|
+
path = slash(path);
|
|
396
|
+
this.removeComponents(path);
|
|
397
|
+
this.onUpdate(path);
|
|
398
|
+
});
|
|
399
|
+
watcher.on("add", (path) => {
|
|
400
|
+
if (!matchGlobs(path, globs)) return;
|
|
401
|
+
path = slash(path);
|
|
402
|
+
this.addComponents(path);
|
|
403
|
+
this.onUpdate(path);
|
|
404
|
+
});
|
|
405
|
+
}
|
|
406
|
+
/**
|
|
407
|
+
* start watcher for webpack
|
|
408
|
+
*/
|
|
409
|
+
setupWatcherWebpack(watcher, emitUpdate) {
|
|
410
|
+
const { globs } = this.options;
|
|
411
|
+
this._removeUnused = this.options.syncMode === "overwrite";
|
|
412
|
+
watcher.on("unlink", (path) => {
|
|
413
|
+
if (!matchGlobs(path, globs)) return;
|
|
414
|
+
path = slash(path);
|
|
415
|
+
this.removeComponents(path);
|
|
416
|
+
emitUpdate(path, "unlink");
|
|
417
|
+
});
|
|
418
|
+
watcher.on("add", (path) => {
|
|
419
|
+
if (!matchGlobs(path, globs)) return;
|
|
420
|
+
path = slash(path);
|
|
421
|
+
this.addComponents(path);
|
|
422
|
+
emitUpdate(path, "add");
|
|
423
|
+
});
|
|
424
|
+
}
|
|
425
|
+
/**
|
|
426
|
+
* Record the usage of components
|
|
427
|
+
* @param path
|
|
428
|
+
* @param paths paths of used components
|
|
429
|
+
*/
|
|
430
|
+
updateUsageMap(path, paths) {
|
|
431
|
+
if (!this._componentUsageMap[path]) this._componentUsageMap[path] = /* @__PURE__ */ new Set();
|
|
432
|
+
paths.forEach((p) => {
|
|
433
|
+
this._componentUsageMap[path].add(p);
|
|
434
|
+
});
|
|
435
|
+
}
|
|
436
|
+
addComponents(paths) {
|
|
437
|
+
debug.components("add", paths);
|
|
438
|
+
const size = this._componentPaths.size;
|
|
439
|
+
toArray(paths).forEach((p) => this._componentPaths.add(p));
|
|
440
|
+
if (this._componentPaths.size !== size) {
|
|
441
|
+
this.updateComponentNameMap();
|
|
442
|
+
return true;
|
|
443
|
+
}
|
|
444
|
+
return false;
|
|
445
|
+
}
|
|
446
|
+
addCustomComponents(info) {
|
|
447
|
+
if (info.as) this._componentCustomMap[info.as] = info;
|
|
448
|
+
}
|
|
449
|
+
addCustomDirectives(info) {
|
|
450
|
+
if (info.as) this._directiveCustomMap[info.as] = info;
|
|
451
|
+
}
|
|
452
|
+
removeComponents(paths) {
|
|
453
|
+
debug.components("remove", paths);
|
|
454
|
+
const size = this._componentPaths.size;
|
|
455
|
+
toArray(paths).forEach((p) => this._componentPaths.delete(p));
|
|
456
|
+
if (this._componentPaths.size !== size) {
|
|
457
|
+
this.updateComponentNameMap();
|
|
458
|
+
return true;
|
|
459
|
+
}
|
|
460
|
+
return false;
|
|
461
|
+
}
|
|
462
|
+
onUpdate(path) {
|
|
463
|
+
this.generateDeclaration();
|
|
464
|
+
this.generateComponentsJson();
|
|
465
|
+
if (!this._server) return;
|
|
466
|
+
const payload = {
|
|
467
|
+
type: "update",
|
|
468
|
+
updates: []
|
|
469
|
+
};
|
|
470
|
+
const timestamp = Date.now();
|
|
471
|
+
const name = pascalCase(getNameFromFilePath(path, this.options));
|
|
472
|
+
Object.entries(this._componentUsageMap).forEach(([key, values]) => {
|
|
473
|
+
if (values.has(name)) {
|
|
474
|
+
const r = `/${slash(relative(this.root, key))}`;
|
|
475
|
+
payload.updates.push({
|
|
476
|
+
acceptedPath: r,
|
|
477
|
+
path: r,
|
|
478
|
+
timestamp,
|
|
479
|
+
type: "js-update"
|
|
480
|
+
});
|
|
481
|
+
}
|
|
482
|
+
});
|
|
483
|
+
if (payload.updates.length) this._server.ws.send(payload);
|
|
484
|
+
}
|
|
485
|
+
updateComponentNameMap() {
|
|
486
|
+
this._componentNameMap = {};
|
|
487
|
+
Array.from(this._componentPaths).forEach((path) => {
|
|
488
|
+
const fileName = getNameFromFilePath(path, this.options);
|
|
489
|
+
const name = this.options.prefix ? `${pascalCase(this.options.prefix)}${pascalCase(fileName)}` : pascalCase(fileName);
|
|
490
|
+
if (isExclude(name, this.options.excludeNames)) {
|
|
491
|
+
debug.components("exclude", name);
|
|
492
|
+
return;
|
|
493
|
+
}
|
|
494
|
+
if (this._componentNameMap[name] && !this.options.allowOverrides) {
|
|
495
|
+
console.warn(`[unplugin-vue-components] component "${name}"(${path}) has naming conflicts with other components, ignored.`);
|
|
496
|
+
return;
|
|
497
|
+
}
|
|
498
|
+
this._componentNameMap[name] = {
|
|
499
|
+
as: name,
|
|
500
|
+
from: path
|
|
501
|
+
};
|
|
502
|
+
});
|
|
503
|
+
}
|
|
504
|
+
async findComponent(name, type, excludePaths = []) {
|
|
505
|
+
let info = this._componentNameMap[name];
|
|
506
|
+
if (info && !excludePaths.includes(info.from) && !excludePaths.includes(info.from.slice(1))) return info;
|
|
507
|
+
for (const resolver of this.options.resolvers) {
|
|
508
|
+
if (resolver.type !== type) continue;
|
|
509
|
+
const result = await resolver.resolve(type === "directive" ? name.slice(1) : name);
|
|
510
|
+
if (!result) continue;
|
|
511
|
+
if (typeof result === "string") info = {
|
|
512
|
+
as: name,
|
|
513
|
+
from: result
|
|
514
|
+
};
|
|
515
|
+
else info = {
|
|
516
|
+
as: name,
|
|
517
|
+
...normalizeComponentInfo(result)
|
|
518
|
+
};
|
|
519
|
+
if (type === "component") this.addCustomComponents(info);
|
|
520
|
+
else if (type === "directive") this.addCustomDirectives(info);
|
|
521
|
+
return info;
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
normalizePath(path) {
|
|
525
|
+
return resolveAlias(path, this.viteConfig?.resolve?.alias || this.viteConfig?.alias || []);
|
|
526
|
+
}
|
|
527
|
+
relative(path) {
|
|
528
|
+
if (path.startsWith("/") && !path.startsWith(this.root)) return slash(path.slice(1));
|
|
529
|
+
return slash(relative(this.root, path));
|
|
530
|
+
}
|
|
531
|
+
_searched = false;
|
|
532
|
+
/**
|
|
533
|
+
* This search for components in with the given options.
|
|
534
|
+
* Will be called multiple times to ensure file loaded,
|
|
535
|
+
* should normally run only once.
|
|
536
|
+
*/
|
|
537
|
+
searchGlob() {
|
|
538
|
+
if (this._searched) return;
|
|
539
|
+
searchComponents(this);
|
|
540
|
+
debug.search(this._componentNameMap);
|
|
541
|
+
this._searched = true;
|
|
542
|
+
}
|
|
543
|
+
_generateDeclaration(removeUnused = this._removeUnused) {
|
|
544
|
+
if (!this.options.dts) return;
|
|
545
|
+
debug.declaration("generating dts");
|
|
546
|
+
return writeDeclaration(this, this.options.dts, removeUnused);
|
|
547
|
+
}
|
|
548
|
+
generateDeclaration(removeUnused = this._removeUnused) {
|
|
549
|
+
this._generateDeclaration(removeUnused);
|
|
550
|
+
}
|
|
551
|
+
_generateComponentsJson(removeUnused = this._removeUnused) {
|
|
552
|
+
if (!Object.keys(this._componentNameMap).length) return;
|
|
553
|
+
debug.components("generating components-info");
|
|
554
|
+
return writeComponentsJson(this, removeUnused);
|
|
555
|
+
}
|
|
556
|
+
generateComponentsJson(removeUnused = this._removeUnused) {
|
|
557
|
+
this._generateComponentsJson(removeUnused);
|
|
558
|
+
}
|
|
559
|
+
get componentNameMap() {
|
|
560
|
+
return this._componentNameMap;
|
|
561
|
+
}
|
|
562
|
+
get componentCustomMap() {
|
|
563
|
+
return this._componentCustomMap;
|
|
564
|
+
}
|
|
565
|
+
get directiveCustomMap() {
|
|
566
|
+
return this._directiveCustomMap;
|
|
567
|
+
}
|
|
568
|
+
};
|
|
569
|
+
//#endregion
|
|
570
|
+
//#region src/core/unplugin.ts
|
|
571
|
+
const PLUGIN_NAME = "unplugin:webpack";
|
|
572
|
+
var unplugin_default = createUnplugin((options = {}) => {
|
|
573
|
+
const filter = createFilter(options.include || [
|
|
574
|
+
/\.vue$/,
|
|
575
|
+
/\.vue\?vue/,
|
|
576
|
+
/\.vue\.[tj]sx?\?vue/,
|
|
577
|
+
/\.vue\?v=/
|
|
578
|
+
], options.exclude || [
|
|
579
|
+
/[\\/]node_modules[\\/]/,
|
|
580
|
+
/[\\/]\.git[\\/]/,
|
|
581
|
+
/[\\/]\.nuxt[\\/]/
|
|
582
|
+
]);
|
|
583
|
+
const ctx = new Context(options);
|
|
584
|
+
return {
|
|
585
|
+
name: "unplugin-vue-components",
|
|
586
|
+
enforce: "post",
|
|
587
|
+
api: {
|
|
588
|
+
async findComponent(name, filename) {
|
|
589
|
+
return await ctx.findComponent(name, "component", filename ? [filename] : []);
|
|
590
|
+
},
|
|
591
|
+
stringifyImport(info) {
|
|
592
|
+
return stringifyComponentImport(info, ctx);
|
|
593
|
+
}
|
|
594
|
+
},
|
|
595
|
+
transformInclude(id) {
|
|
596
|
+
return filter(id);
|
|
597
|
+
},
|
|
598
|
+
async transform(code, id) {
|
|
599
|
+
if (!shouldTransform(code)) return null;
|
|
600
|
+
try {
|
|
601
|
+
const result = await ctx.transform(code, id);
|
|
602
|
+
ctx.generateDeclaration();
|
|
603
|
+
ctx.generateComponentsJson();
|
|
604
|
+
return result;
|
|
605
|
+
} catch (e) {
|
|
606
|
+
this.error(e);
|
|
607
|
+
}
|
|
608
|
+
},
|
|
609
|
+
vite: {
|
|
610
|
+
async configResolved(config) {
|
|
611
|
+
ctx.setRoot(config.root);
|
|
612
|
+
ctx.sourcemap = true;
|
|
613
|
+
if (ctx.options.dts) {
|
|
614
|
+
ctx.searchGlob();
|
|
615
|
+
if (!existsSync(ctx.options.dts)) ctx.generateDeclaration();
|
|
616
|
+
}
|
|
617
|
+
if (ctx.options.dumpComponentsInfo && ctx.dumpComponentsInfoPath) {
|
|
618
|
+
if (!existsSync(ctx.dumpComponentsInfoPath)) ctx.generateComponentsJson();
|
|
619
|
+
}
|
|
620
|
+
if (config.build.watch && config.command === "build") ctx.setupWatcher(chokidar.watch(await glob(ctx.options.globs)));
|
|
621
|
+
},
|
|
622
|
+
configureServer(server) {
|
|
623
|
+
ctx.setupViteServer(server);
|
|
624
|
+
}
|
|
625
|
+
},
|
|
626
|
+
webpack(compiler) {
|
|
627
|
+
let watcher;
|
|
628
|
+
let fileDepQueue = [];
|
|
629
|
+
compiler.hooks.watchRun.tapPromise(PLUGIN_NAME, async () => {
|
|
630
|
+
if (!watcher && compiler.watching) {
|
|
631
|
+
watcher = compiler.watching;
|
|
632
|
+
ctx.setupWatcherWebpack(chokidar.watch(await glob(ctx.options.globs)), (path, type) => {
|
|
633
|
+
fileDepQueue.push({
|
|
634
|
+
path,
|
|
635
|
+
type
|
|
636
|
+
});
|
|
637
|
+
process.nextTick(() => {
|
|
638
|
+
watcher.invalidate();
|
|
639
|
+
});
|
|
640
|
+
});
|
|
641
|
+
}
|
|
642
|
+
});
|
|
643
|
+
compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
|
|
644
|
+
if (fileDepQueue.length) {
|
|
645
|
+
fileDepQueue.forEach(({ path, type }) => {
|
|
646
|
+
if (type === "unlink") compilation.fileDependencies.delete(path);
|
|
647
|
+
else compilation.fileDependencies.add(path);
|
|
648
|
+
});
|
|
649
|
+
fileDepQueue = [];
|
|
650
|
+
}
|
|
651
|
+
});
|
|
652
|
+
}
|
|
653
|
+
};
|
|
654
|
+
});
|
|
655
|
+
//#endregion
|
|
656
|
+
export { unplugin_default as t };
|