优化第一阶段

This commit is contained in:
yinsx
2025-12-22 12:07:12 +08:00
parent dd99e932b4
commit 1df41ac4ab
38 changed files with 340 additions and 300 deletions

View File

@ -0,0 +1,216 @@
// 二级菜单 - 项目类型
export const projectTypes = [
{ name: "前端", desc: "React/Vue项目" },
{ name: "后端", desc: "Node.js服务端" },
{ name: "全栈", desc: "前后端一体化" },
];
// 框架选项
export const frameworkOptions = {
前端: [
{ value: "vue", label: "VueVite + Vue" },
{ value: "react", label: "ReactVite + React" },
],
后端: [
{ value: "bun", label: "BunBun运行时" },
{ value: "node", label: "Node.jsNode运行时" },
],
全栈: [
{ value: "nextjs", label: "Next.jsReact全栈框架" },
{ value: "nuxt", label: "NuxtVue全栈框架" },
],
};
const bunComponents = {
框架: [
{ value: "normal", label: "原生" },
{ value: "elysia", label: "Elysia(官方亲儿子)" },
{ value: "hono", label: "Hono(轻量级)" },
]
};
const nodeComponents = {
框架: [
{ value: "nestjs", label: "NestJS企业级框架" },
{ value: "express", label: "ExpressExpress Generator" },
{ value: "koa", label: "KoaKoa Generator" },
{ value: "egg", label: "Egg阿里Egg.js" },
{ value: "midway", label: "Midway阿里Midway" },
{ value: "fastify", label: "Fastify高性能框架" },
{ value: "adonisjs", label: "AdonisJS全功能MVC" },
]
};
//后端公共框架
const backendCommonComponents = {
数据库: [
{ value: "none", label: "不需要数据库" },
{ value: "mongoose", label: "MongoDB + Mongoose" },
{ value: "prisma", label: "Prisma支持 MySQL / PostgreSQL / SQLite" },
{ value: "typeorm", label: "TypeORM支持 MySQL / PostgreSQL 等)" },
]
};
// 组件选项 - 按框架分类
const reactComponents = {
路由: [
{ value: "none", label: "不需要路由" },
{ value: "react-router", label: "React Router" },
{ value: "tanstack-router", label: "TanStack Router" },
],
状态管理: [
{ value: "none", label: "不需要状态管理" },
{ value: "zustand", label: "Zustand轻量级推荐" },
{ value: "redux", label: "Redux Toolkit" },
{ value: "jotai", label: "Jotai原子化" },
{ value: "mobx", label: "MobX" },
],
UI组件库: [
{ value: "none", label: "不需要UI库" },
{ value: "antd", label: "Ant Design" },
{ value: "arco", label: "Arco Design" },
{ value: "shadcn", label: "shadcn/ui" },
{ value: "mui", label: "Material UI" },
],
表单验证: [
{ value: "none", label: "不需要表单验证" },
{ value: "react-hook-form", label: "React Hook Form" },
{ value: "formik", label: "Formik" },
{ value: "zod", label: "Zod" },
],
工具库: [
{ value: "ahooks", label: "ahooksReact Hooks库" },
{ value: "lodash", label: "Lodash" },
{ value: "dayjs", label: "Day.js" },
{ value: "iconify", label: "Iconify图标" },
],
国际化: [
{ value: "none", label: "不需要国际化" },
{ value: "i18next", label: "i18next" },
],
};
const vueComponents = {
路由: [
{ value: "none", label: "不需要路由" },
{ value: "vue-router", label: "Vue Router" },
],
状态管理: [
{ value: "none", label: "不需要状态管理" },
{ value: "pinia", label: "Pinia官方推荐" },
],
UI组件库: [
{ value: "none", label: "不需要UI库" },
{ value: "element-plus", label: "Element Plus" },
{ value: "naive-ui", label: "Naive UI" },
{ value: "arco-vue", label: "Arco Design Vue" },
{ value: "ant-design-vue", label: "Ant Design Vue" },
],
表单验证: [
{ value: "none", label: "不需要表单验证" },
{ value: "vee-validate", label: "VeeValidate" },
{ value: "vuelidate", label: "Vuelidate" },
{ value: "zod", label: "Zod" },
],
工具库: [
{ value: "vueuse", label: "VueUse组合式工具" },
{ value: "lodash", label: "Lodash" },
{ value: "dayjs", label: "Day.js" },
{ value: "iconify", label: "Iconify图标" },
], 国际化: [
{ value: "none", label: "不需要国际化" },
{ value: "vue-i18n", label: "Vue-i18n" },
],
};
// 通用组件React和Vue共用
const commonComponents = {
HTTP请求: [
{ value: "none", label: "不需要HTTP库" },
{ value: "axios", label: "Axios" },
{ value: "ky", label: "Ky轻量级" },
{ value: "ofetch", label: "ofetch" },
],
CSS方案: [
{ value: "none", label: "原生CSS" },
{ value: "tailwind", label: "Tailwind CSS" },
{ value: "unocss", label: "UnoCSS" },
{ value: "sass", label: "Sass/SCSS" },
{ value: "less", label: "Less" },
],
代码规范: [
{ value: "eslint", label: "ESLint" },
{ value: "prettier", label: "Prettier" },
{ value: "husky", label: "Husky" },
{ value: "lint-staged", label: "lint-staged" },
],
其他: [
{ value: "mock", label: "Mock.js" },
{ value: "pwa", label: "PWA支持" },
{ value: "storage", label: "持久化存储" },
{ value: "threejs", label: "3D集成(Three.js)" },
{ value: "babylonjs", label: "3D集成(Babylon.js)" },
],
};
// 根据框架获取组件配置
export function getComponentsByFramework(framework) {
if (!framework || framework === "none") return {};
const isReact = ["react", "nextjs"].includes(framework);
const isVue = ["vue", "nuxt"].includes(framework);
const isBun = framework === "bun";
const isNode = framework === "node";
if (isReact) {
return { ...reactComponents, ...commonComponents };
} else if (isVue) {
return { ...vueComponents, ...commonComponents };
} else if (isBun) {
return { ...bunComponents, ...backendCommonComponents };
} else if (isNode) {
return { ...nodeComponents, ...backendCommonComponents };
}
return {};
}
// 获取默认框架
function getDefaultFramework(projectType) {
const opts = frameworkOptions[projectType];
return opts?.[0]?.value || "none";
}
// 生成前端/全栈项目的步骤配置
export function generateSteps(projectType, selectedFramework) {
const defaultFramework = getDefaultFramework(projectType);
const framework = selectedFramework || defaultFramework;
const steps = [
{
name: "运行时",
type: "select",
message: "选择项目框架",
options: frameworkOptions[projectType] || [],
default: defaultFramework
}
];
const components = getComponentsByFramework(framework);
const componentNames = Object.keys(components);
componentNames.forEach(name => {
const isMulti = ["工具库", "代码规范", "其他"].includes(name);
const opts = components[name] || [];
steps.push({
name,
type: isMulti ? "multiselect" : "select",
message: `选择${name}`,
options: opts,
default: isMulti ? [] : opts[0]?.value
});
});
return steps;
}

View File

@ -0,0 +1,42 @@
import color from "picocolors";
import { projectTypes } from "./config.js";
import { gridSelect } from "../../grid.js";
import { createScaffoldUI, formatResults, waitKey } from "./ui.js";
async function run() {
while (true) {
// 二级菜单 - 项目类型
const typeResult = await gridSelect({
items: projectTypes,
title: "项目搭建器 - 选择类型",
cols: Math.min(3, projectTypes.length),
colWidth: 20,
instructions: "←→ 选择 | Enter 确认 | Esc 返回",
onCancel: "back",
mapper: item => ({ action: "select", item }),
showUpdateButton: false,
});
if (typeResult === "back") return "back";
const projectType = typeResult.item.name;
// 三级页面 - 框架+组件配置(合并)
const ui = createScaffoldUI(projectType);
const result = await ui.runInteractive();
if (result) {
const summary = formatResults(result.steps, result.results);
ui.showSummary(summary);
console.log(color.yellow("功能开发中,敬请期待..."));
await waitKey();
}
}
}
export default {
id: "scaffold",
name: "项目搭建",
desc: "快速创建项目模板",
run,
};

View File

@ -0,0 +1,41 @@
import color from "picocolors";
import { initKeypress, onKey, stopKeypress } from "../../keyboard.js";
import { createStepUI } from "../../utils/stepui.js";
import { generateSteps } from "./config.js";
// 框架 + 组件配置 UI
export function createScaffoldUI(projectType) {
return createStepUI({
title: `${projectType} - 项目配置`,
getSteps: () => generateSteps(projectType, null),
onStepChange: framework => generateSteps(projectType, framework),
});
}
// 解析配置结果
export function formatResults(steps, results) {
const summary = [];
results.forEach((val, i) => {
if (Array.isArray(val) && val.length > 0) {
summary.push(`${steps[i].name}: ${val.join(", ")}`);
} else if (val && val !== "none") {
summary.push(`${steps[i].name}: ${val}`);
}
});
return summary.length ? summary : ["未选择任何组件"];
}
// 等待按键
export async function waitKey(message = "按任意键返回") {
console.log(color.dim(`\n${message}`));
return new Promise(resolve => {
initKeypress();
onKey(() => {
stopKeypress();
resolve();
});
});
}