vite-plugin-generoutes 0.2.0 → 0.2.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/index.d.ts CHANGED
@@ -10,13 +10,23 @@ import { Plugin } from 'vite';
10
10
 
11
11
  interface Options {
12
12
  /**
13
- * default: `src/router/pages`
13
+ * pages 文件夹
14
+ *
15
+ * default: `src/pages`
14
16
  */
15
17
  pagesFolder: string;
16
18
  /**
17
- * default: `src/router/generoutes.js`
19
+ * 路由文件路径
20
+ *
21
+ * default: `${pagesFolder}/generoutes.js`
18
22
  */
19
23
  routesPath?: string;
24
+ /**
25
+ * 是否嵌套
26
+ *
27
+ * default: false
28
+ */
29
+ nested: boolean;
20
30
  }
21
31
  declare function VitePluginGeneroutes(options?: Partial<Options>): Plugin<any>;
22
32
 
package/dist/index.js CHANGED
@@ -6,39 +6,54 @@ import { parse } from "@vue/compiler-sfc";
6
6
  import { debounce, slash } from "@antfu/utils";
7
7
  import chokidar from "chokidar";
8
8
  import prettier from "prettier";
9
+
10
+ // src/utils.ts
9
11
  function toPascalCase(str) {
10
12
  return str.toLowerCase().replace(/(?:^|-)([a-z])/g, (_, p1) => {
11
13
  return p1.toUpperCase();
12
14
  });
13
15
  }
16
+ function convertToTree(routes) {
17
+ const nodeMap = {};
18
+ const result = [];
19
+ routes.forEach((route) => {
20
+ const { parent, ...node } = route;
21
+ nodeMap[node.name] = node;
22
+ });
23
+ routes.forEach((route) => {
24
+ if (route.parent) {
25
+ const parentNode = nodeMap[route.parent];
26
+ if (parentNode) {
27
+ if (!parentNode.children) {
28
+ parentNode.children = [];
29
+ }
30
+ parentNode.children.push(nodeMap[route.name]);
31
+ }
32
+ } else {
33
+ result.push(nodeMap[route.name]);
34
+ }
35
+ });
36
+ return result;
37
+ }
38
+
39
+ // src/index.ts
14
40
  var defaultOptions = {
15
- pagesFolder: "src/pages"
41
+ pagesFolder: "src/pages",
42
+ nested: false
16
43
  };
17
44
  function VitePluginGeneroutes(options = {}) {
18
45
  if (options.routesPath && ![".ts", ".js"].includes(path.extname(options.routesPath)))
19
46
  throw new Error("routesPath must be a js or ts file path, such as src/router/generoutes.js");
20
- const defineOptionsCache = /* @__PURE__ */ new Map();
21
47
  let rootDir;
22
48
  const pagesFolder = options.pagesFolder || defaultOptions.pagesFolder;
23
- const routesPath = options.routesPath || path.resolve(pagesFolder, "generoutes.js");
24
- async function writerRoutesFile() {
25
- const { routes } = generateMenusAndRoutes();
26
- let routesStr = `
27
- // ! \u6B64\u6587\u4EF6\u7531 vite-plugin-generoutes \u81EA\u52A8\u751F\u6210\uFF0C\u5EFA\u8BAE\u6DFB\u52A0\u5230 .gitignore\uFF0C\u8BF7\u52FF\u76F4\u63A5\u5728\u6B64\u6587\u4EF6\u4FEE\u6539!!!
28
- // ! This file is generated by vite-plugin-generoutes, it is recommended to add it to .gitignore, do not modify it directly in this file!!!
29
-
30
- export const routes = ${JSON.stringify(routes, null, 2)}
31
- `;
32
- routesStr = routesStr.replace(/"##(.*)##"/g, (_, p1) => `() => import('${p1}')`);
33
- routesStr = await prettier.format(routesStr, { parser: "babel", semi: false, singleQuote: true });
34
- fs.writeFileSync(`${path.resolve(rootDir, routesPath)}`, routesStr);
35
- }
36
- const debounceWriter = debounce(500, writerRoutesFile);
49
+ const routesPath = options.routesPath || path.join(pagesFolder, "generoutes.js");
50
+ const nested = options.nested || defaultOptions.nested;
51
+ const defineOptionsCache = /* @__PURE__ */ new Map();
37
52
  function generateMenusAndRoutes() {
38
53
  const pages = globSync(`${pagesFolder}/**/index.vue`).concat(globSync(`${pagesFolder}/**/\\[...all\\].vue`));
39
54
  const routes = pages.map((filePath) => {
40
55
  filePath = slash(filePath);
41
- const defineOptions = parseDefineOptions(filePath);
56
+ const defineOptions = parseDefineOptions(filePath) || {};
42
57
  defineOptionsCache.set(filePath, JSON.stringify(defineOptions));
43
58
  const meta = defineOptions?.meta || {};
44
59
  if (meta.enabled === false)
@@ -61,13 +76,29 @@ function VitePluginGeneroutes(options = {}) {
61
76
  name,
62
77
  path: routePath,
63
78
  component,
64
- meta
79
+ meta,
80
+ parent: defineOptions?.parent
65
81
  };
66
82
  }).filter(Boolean);
67
83
  return {
68
- routes
84
+ routes: nested ? convertToTree(routes) : routes
69
85
  };
70
86
  }
87
+ async function writerRoutesFile() {
88
+ const { routes } = generateMenusAndRoutes();
89
+ let routesStr = `
90
+ // ! \u6B64\u6587\u4EF6\u7531 vite-plugin-generoutes \u81EA\u52A8\u751F\u6210\uFF0C\u5EFA\u8BAE\u6DFB\u52A0\u5230 .gitignore\uFF0C\u8BF7\u52FF\u76F4\u63A5\u5728\u6B64\u6587\u4EF6\u4FEE\u6539!!!
91
+ // ! This file is generated by vite-plugin-generoutes, it is recommended to add it to .gitignore, do not modify it directly in this file!!!
92
+
93
+ export const routes = ${JSON.stringify(routes, null, 2)}
94
+ `;
95
+ routesStr = routesStr.replace(/"##(.*)##"/g, (_, p1) => `() => import('${p1}')`);
96
+ routesStr = await prettier.format(routesStr, { parser: "babel", semi: false, singleQuote: true });
97
+ const filePath = path.resolve(rootDir, routesPath);
98
+ await fs.ensureDir(path.dirname(filePath));
99
+ fs.writeFileSync(filePath, routesStr);
100
+ }
101
+ const debounceWriter = debounce(500, writerRoutesFile);
71
102
  function createWatcher() {
72
103
  const watcher = chokidar.watch([`${pagesFolder}/**/index.vue`, `${pagesFolder}/**/[...all].vue`], { ignoreInitial: true });
73
104
  return watcher.on("all", async (event, path2) => {
@@ -82,12 +113,11 @@ function VitePluginGeneroutes(options = {}) {
82
113
  name: "vite-plugin-generoutes",
83
114
  async configResolved(config) {
84
115
  rootDir = config.root;
85
- await fs.ensureDir(path.dirname(routesPath));
86
116
  await writerRoutesFile();
87
117
  config.command !== "build" && createWatcher();
88
118
  },
89
119
  async handleHotUpdate({ file, read }) {
90
- if (file.includes("src/pages") && (file.endsWith("index.vue") || file.endsWith("[...all].vue"))) {
120
+ if (file.includes(pagesFolder) && (file.endsWith("index.vue") || file.endsWith("[...all].vue"))) {
91
121
  const prevDefineOptions = defineOptionsCache.get(slash(path.relative(rootDir, file)));
92
122
  if (!prevDefineOptions) {
93
123
  debounceWriter();
@@ -106,16 +136,16 @@ function parseDefineOptions(filePath, content) {
106
136
  const { descriptor } = parse(content);
107
137
  const setupScript = descriptor.scriptSetup?.content;
108
138
  if (setupScript) {
109
- const defineOptionsMatch = setupScript.match(/defineOptions\(([^)]+)\)/);
139
+ const defineOptionsMatch = setupScript.match(/defineOptions\s*\(\s*(\{[\s\S]*?\})\s*\)/);
110
140
  if (defineOptionsMatch) {
111
141
  try {
112
142
  return new Function(`return ${defineOptionsMatch[1]}`)();
113
143
  } catch (e) {
114
- console.error(`Failed to parse defineOptions in ${filePath}:`, e);
144
+ throw new Error(`Failed to parse defineOptions in ${filePath}: ${e}`);
115
145
  }
116
146
  }
117
147
  }
118
- return null;
148
+ return {};
119
149
  }
120
150
  var src_default = VitePluginGeneroutes;
121
151
  export {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "vite-plugin-generoutes",
3
3
  "type": "module",
4
- "version": "0.2.0",
4
+ "version": "0.2.1",
5
5
  "packageManager": "pnpm@9.1.1",
6
6
  "description": "_description_",
7
7
  "author": "Ronnie Zhang <zclzone@outlook.com>",
@@ -78,4 +78,4 @@
78
78
  "lint-staged": {
79
79
  "*": "eslint --fix"
80
80
  }
81
- }
81
+ }