befly-vite 1.2.0 → 1.2.2
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/bin/scanViewsDir.ts +114 -0
- package/package.json +4 -3
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import type { ViewDirMeta } from "befly-shared/utils/scanViewsDir";
|
|
2
|
+
|
|
3
|
+
import { existsSync } from "node:fs";
|
|
4
|
+
import { readFile, readdir, writeFile } from "node:fs/promises";
|
|
5
|
+
import { join, resolve } from "node:path";
|
|
6
|
+
import { fileURLToPath } from "node:url";
|
|
7
|
+
|
|
8
|
+
import { cleanDirName, extractDefinePageMetaFromScriptSetup, extractScriptSetupBlock, normalizeMenuTree } from "befly-shared/utils/scanViewsDir";
|
|
9
|
+
|
|
10
|
+
type MenuConfig = {
|
|
11
|
+
name: string;
|
|
12
|
+
path: string;
|
|
13
|
+
icon?: string;
|
|
14
|
+
sort?: number;
|
|
15
|
+
children?: MenuConfig[];
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* 扫描 views 目录,构建菜单树(与 core/sync/syncMenu.ts 中的 scanViewsDir 逻辑一致)
|
|
20
|
+
*/
|
|
21
|
+
export async function scanViewsDir(viewsDir: string, prefix: string, parentPath: string = ""): Promise<MenuConfig[]> {
|
|
22
|
+
if (!existsSync(viewsDir)) {
|
|
23
|
+
return [];
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const menus: MenuConfig[] = [];
|
|
27
|
+
const entries = await readdir(viewsDir, { withFileTypes: true });
|
|
28
|
+
|
|
29
|
+
for (const entry of entries) {
|
|
30
|
+
if (!entry.isDirectory() || entry.name === "components") {
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const dirPath = join(viewsDir, entry.name);
|
|
35
|
+
const indexVuePath = join(dirPath, "index.vue");
|
|
36
|
+
|
|
37
|
+
if (!existsSync(indexVuePath)) {
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
let meta: ViewDirMeta | null = null;
|
|
42
|
+
try {
|
|
43
|
+
const content = await readFile(indexVuePath, "utf-8");
|
|
44
|
+
|
|
45
|
+
const scriptSetup = extractScriptSetupBlock(content);
|
|
46
|
+
if (!scriptSetup) {
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
meta = extractDefinePageMetaFromScriptSetup(scriptSetup);
|
|
51
|
+
if (!meta?.title) {
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
} catch {
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (!meta?.title) {
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const cleanName = cleanDirName(entry.name);
|
|
63
|
+
let menuPath: string;
|
|
64
|
+
if (cleanName === "index") {
|
|
65
|
+
menuPath = parentPath;
|
|
66
|
+
} else {
|
|
67
|
+
menuPath = parentPath ? `${parentPath}/${cleanName}` : `/${cleanName}`;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const fullPath = prefix ? (menuPath ? `${prefix}${menuPath}` : prefix) : menuPath || "/";
|
|
71
|
+
|
|
72
|
+
const menu: MenuConfig = {
|
|
73
|
+
name: meta.title,
|
|
74
|
+
path: fullPath,
|
|
75
|
+
sort: meta.order ?? 999999
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
const children = await scanViewsDir(dirPath, prefix, menuPath);
|
|
79
|
+
if (children.length > 0) {
|
|
80
|
+
menu.children = children;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
menus.push(menu);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
menus.sort((a, b) => (a.sort ?? 999999) - (b.sort ?? 999999));
|
|
87
|
+
return menus;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
async function main(): Promise<void> {
|
|
91
|
+
// 固定扫描目录:仓库 packages/admin/src/views
|
|
92
|
+
// 固定输出:同目录下的 menu.json
|
|
93
|
+
const fileDir = resolve(fileURLToPath(new URL(".", import.meta.url)));
|
|
94
|
+
const repoRoot = resolve(fileDir, "..", "..", "..");
|
|
95
|
+
|
|
96
|
+
const absDir = resolve(repoRoot, "packages", "admin", "src", "views");
|
|
97
|
+
const outPath = join(absDir, "menu.json");
|
|
98
|
+
|
|
99
|
+
if (!existsSync(absDir)) {
|
|
100
|
+
process.stderr.write(`Missing views dir: ${absDir}\n`);
|
|
101
|
+
process.exitCode = 1;
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const menus = await scanViewsDir(absDir, "");
|
|
106
|
+
const normalized = normalizeMenuTree(menus);
|
|
107
|
+
|
|
108
|
+
const content = `${JSON.stringify(normalized, null, 4)}\n`;
|
|
109
|
+
await writeFile(outPath, content, { encoding: "utf-8" });
|
|
110
|
+
|
|
111
|
+
process.stdout.write(`Wrote ${normalized.length} root menus to ${outPath}\n`);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
await main();
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "befly-vite",
|
|
3
|
-
"version": "1.2.
|
|
4
|
-
"gitHead": "
|
|
3
|
+
"version": "1.2.2",
|
|
4
|
+
"gitHead": "47bed37852a0435186337bae81258ae2de1d29a4",
|
|
5
5
|
"private": false,
|
|
6
6
|
"description": "Befly Vite 配置预设和插件集合",
|
|
7
7
|
"keywords": [
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
"index.js",
|
|
19
19
|
"package.json",
|
|
20
20
|
"README.md",
|
|
21
|
+
"bin/",
|
|
21
22
|
"configs/",
|
|
22
23
|
"plugins/",
|
|
23
24
|
"utils/"
|
|
@@ -40,7 +41,7 @@
|
|
|
40
41
|
"@unocss/preset-uno": "^66.5.11",
|
|
41
42
|
"@vitejs/plugin-vue": "^6.0.3",
|
|
42
43
|
"@vue-macros/reactivity-transform": "^3.1.1",
|
|
43
|
-
"befly-shared": "1.
|
|
44
|
+
"befly-shared": "1.3.1",
|
|
44
45
|
"sass": "^1.97.1",
|
|
45
46
|
"unocss": "^66.5.11",
|
|
46
47
|
"unplugin-auto-import": "^20.3.0",
|