befly-vite 1.1.12 → 1.2.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/index.js CHANGED
@@ -91,7 +91,7 @@ export function createBeflyViteConfig(options = {}) {
91
91
  const { root, scanViews, resolvers = {}, manualChunks, userConfig = {} } = options;
92
92
 
93
93
  // 计算根目录(如果未提供)
94
- const projectRoot = root || process.cwd();
94
+ const appRoot = root || process.cwd();
95
95
 
96
96
  const baseConfig = defineConfig({
97
97
  base: "./",
@@ -112,7 +112,7 @@ export function createBeflyViteConfig(options = {}) {
112
112
 
113
113
  resolve: {
114
114
  alias: {
115
- "@": fileURLToPath(new URL("src", `file:///${projectRoot.replace(/\\/g, "/")}/`))
115
+ "@": fileURLToPath(new URL("src", `file:///${appRoot.replace(/\\/g, "/")}/`))
116
116
  }
117
117
  },
118
118
 
package/package.json CHANGED
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "name": "befly-vite",
3
- "version": "1.1.12",
3
+ "version": "1.2.0",
4
+ "gitHead": "faa8189c7d23cf45885c03d1425cba8f5bf45df9",
4
5
  "private": false,
5
6
  "description": "Befly Vite 配置预设和插件集合",
6
7
  "keywords": [
@@ -11,29 +12,37 @@
11
12
  "vue"
12
13
  ],
13
14
  "homepage": "https://chensuiyi.me",
14
- "author": "chensuiyi <bimostyle@qq.com>",
15
15
  "license": "Apache-2.0",
16
- "type": "module",
17
- "main": "index.js",
18
- "exports": {
19
- ".": "./index.js",
20
- "./utils/*": "./utils/*.js"
21
- },
16
+ "author": "chensuiyi <bimostyle@qq.com>",
22
17
  "files": [
23
- "README.md",
24
- "configs/",
25
18
  "index.js",
26
19
  "package.json",
20
+ "README.md",
21
+ "configs/",
27
22
  "plugins/",
28
23
  "utils/"
29
24
  ],
25
+ "type": "module",
26
+ "main": "index.js",
27
+ "exports": {
28
+ ".": "./index.js",
29
+ "./utils/*": "./utils/*.js"
30
+ },
31
+ "publishConfig": {
32
+ "access": "public",
33
+ "registry": "https://registry.npmjs.org"
34
+ },
35
+ "scripts": {
36
+ "scanViewsDir": "bun ./bin/scanViewsDir.ts"
37
+ },
30
38
  "dependencies": {
31
- "@unocss/preset-attributify": "^66.5.10",
32
- "@unocss/preset-uno": "^66.5.10",
39
+ "@unocss/preset-attributify": "^66.5.11",
40
+ "@unocss/preset-uno": "^66.5.11",
33
41
  "@vitejs/plugin-vue": "^6.0.3",
34
42
  "@vue-macros/reactivity-transform": "^3.1.1",
35
- "sass": "^1.96.0",
36
- "unocss": "^66.5.10",
43
+ "befly-shared": "1.0.0",
44
+ "sass": "^1.97.1",
45
+ "unocss": "^66.5.11",
37
46
  "unplugin-auto-import": "^20.3.0",
38
47
  "unplugin-icons": "^22.5.0",
39
48
  "unplugin-vue-components": "^30.0.0",
@@ -43,15 +52,10 @@
43
52
  "vite-plugin-vue-devtools": "^8.0.5"
44
53
  },
45
54
  "peerDependencies": {
46
- "vite": "^8.0.0-beta.3",
55
+ "vite": "^8.0.0-beta.5",
47
56
  "vue": "^3.5.26"
48
57
  },
49
58
  "engines": {
50
59
  "bun": ">=1.3.0"
51
- },
52
- "publishConfig": {
53
- "access": "public",
54
- "registry": "https://registry.npmjs.org"
55
- },
56
- "gitHead": "d42bf60ba6b8b11fef7e759fa008ada075829772"
60
+ }
57
61
  }
@@ -4,6 +4,7 @@
4
4
  * @property {string=} pidField
5
5
  * @property {string=} childrenField
6
6
  * @property {any=} rootPid
7
+ * @property {string=} sortField
7
8
  * @property {(node: any) => any=} mapFn
8
9
  */
9
10
 
@@ -18,29 +19,50 @@ export function arrayToTree(items, options = {}) {
18
19
  const pidField = typeof options.pidField === "string" ? options.pidField : "pid";
19
20
  const childrenField = typeof options.childrenField === "string" ? options.childrenField : "children";
20
21
  const rootPid = "rootPid" in options ? options.rootPid : 0;
22
+ const sortField = "sortField" in options ? (typeof options.sortField === "string" && options.sortField.length > 0 ? options.sortField : null) : "sort";
21
23
  const mapFn = typeof options.mapFn === "function" ? options.mapFn : null;
22
24
 
23
- /** @type {T[]} */
24
- const tree = [];
25
+ /**
26
+ * pid -> items[]
27
+ * @type {Map<any, T[]>}
28
+ */
29
+ const pidMap = new Map();
25
30
 
26
31
  for (const item of items) {
27
32
  // @ts-ignore
28
- const pid = item[pidField];
33
+ const pid = item ? item[pidField] : undefined;
34
+ const list = pidMap.get(pid);
35
+ if (list) {
36
+ list.push(item);
37
+ } else {
38
+ pidMap.set(pid, [item]);
39
+ }
40
+ }
29
41
 
30
- if (Object.is(pid, rootPid)) {
42
+ /**
43
+ * @param {any} pid
44
+ * @param {Set<any>} stack
45
+ * @returns {T[]}
46
+ */
47
+ const build = (pid, stack) => {
48
+ /** @type {T[]} */
49
+ const tree = [];
50
+ const list = pidMap.get(pid) || [];
51
+
52
+ for (const item of list) {
31
53
  const node = Object.assign({}, item);
32
54
  const mappedNode = mapFn ? mapFn(node) : node;
33
55
 
34
56
  // 子节点 rootPid = node[id]
35
57
  // @ts-ignore
36
- const nextRootPid = mappedNode[idField];
37
- const children = arrayToTree(items, {
38
- idField: idField,
39
- pidField: pidField,
40
- childrenField: childrenField,
41
- rootPid: nextRootPid,
42
- mapFn: mapFn
43
- });
58
+ const nextRootPid = mappedNode ? mappedNode[idField] : undefined;
59
+
60
+ let children = [];
61
+ if (!stack.has(nextRootPid)) {
62
+ stack.add(nextRootPid);
63
+ children = build(nextRootPid, stack);
64
+ stack.delete(nextRootPid);
65
+ }
44
66
 
45
67
  if (children.length > 0) {
46
68
  // @ts-ignore
@@ -49,7 +71,30 @@ export function arrayToTree(items, options = {}) {
49
71
 
50
72
  tree.push(mappedNode);
51
73
  }
52
- }
53
74
 
54
- return tree;
75
+ if (sortField) {
76
+ tree.sort((a, b) => {
77
+ // @ts-ignore
78
+ const av = a ? a[sortField] : undefined;
79
+ // @ts-ignore
80
+ const bv = b ? b[sortField] : undefined;
81
+
82
+ const aMissing = av === undefined || av === null;
83
+ const bMissing = bv === undefined || bv === null;
84
+ if (aMissing && bMissing) return 0;
85
+ if (aMissing) return 1;
86
+ if (bMissing) return -1;
87
+
88
+ if (typeof av === "number" && typeof bv === "number") {
89
+ return av - bv;
90
+ }
91
+
92
+ return String(av).localeCompare(String(bv), undefined, { numeric: true, sensitivity: "base" });
93
+ });
94
+ }
95
+
96
+ return tree;
97
+ };
98
+
99
+ return build(rootPid, new Set());
55
100
  }
@@ -2,29 +2,33 @@ import { existsSync, readdirSync, realpathSync } from "node:fs";
2
2
  import { join } from "node:path";
3
3
 
4
4
  /**
5
- * 扫描项目和所有 @befly-addon 包的 views 目录
5
+ * 扫描项目和所有 @befly-addon 包的视图目录
6
6
  * 用于 unplugin-vue-router 的 routesFolder 配置
7
+ *
8
+ * 约定:addon 只允许从 adminViews 扫描路由:
9
+ * - <addonRoot>/adminViews
10
+ *
7
11
  * 注意:此函数只能在 vite.config.js 中使用(Node.js 环境),不能在浏览器中使用
8
12
  * @returns {Array<{ src: string, path: string, exclude: string[] }>} 路由文件夹配置数组
9
13
  */
10
14
  export function scanViews() {
11
- const projectRoot = process.cwd();
12
- const addonBasePath = join(projectRoot, "node_modules", "@befly-addon");
15
+ const appRoot = process.cwd();
16
+ const addonBasePath = join(appRoot, "node_modules", "@befly-addon");
13
17
 
14
18
  /** @type {Array<{ src: string, path: string, exclude: string[] }>} */
15
19
  const routesFolders = [];
16
20
 
17
21
  // 1. 项目自身 views
18
- const projectViewsPath = join(projectRoot, "src", "views");
19
- if (existsSync(projectViewsPath)) {
22
+ const appViewsPath = join(appRoot, "src", "views");
23
+ if (existsSync(appViewsPath)) {
20
24
  routesFolders.push({
21
- src: realpathSync(projectViewsPath),
25
+ src: realpathSync(appViewsPath),
22
26
  path: "",
23
27
  exclude: ["**/components/**"]
24
28
  });
25
29
  }
26
30
 
27
- // 2. 扫描 @befly-addon/*/views
31
+ // 2. 扫描 @befly-addon/*/adminViews(仅此目录允许生成 addon 路由)
28
32
  if (!existsSync(addonBasePath)) {
29
33
  return routesFolders;
30
34
  }
@@ -38,10 +42,10 @@ export function scanViews() {
38
42
  continue;
39
43
  }
40
44
 
41
- const viewsPath = join(addonPath, "views");
42
- if (existsSync(viewsPath)) {
45
+ const adminViewsPath = join(addonPath, "adminViews");
46
+ if (existsSync(adminViewsPath)) {
43
47
  routesFolders.push({
44
- src: realpathSync(viewsPath),
48
+ src: realpathSync(adminViewsPath),
45
49
  path: `addon/${addonName}/`,
46
50
  exclude: ["**/components/**"]
47
51
  });