@moluoxixi/create-app 2.0.4 → 2.0.403
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.txt +21 -21
- package/README.md +129 -129
- package/dist/commands/create.d.ts +2 -1
- package/dist/commands/create.js +12 -8
- package/dist/commands/index.d.ts +1 -2
- package/dist/commands/index.js +1 -2
- package/dist/constants/index.d.ts +17 -0
- package/dist/constants/index.js +17 -0
- package/dist/generators/index.d.ts +3 -4
- package/dist/generators/index.js +3 -4
- package/dist/generators/project.d.ts +3 -2
- package/dist/generators/project.js +5 -4
- package/dist/generators/react.d.ts +4 -2
- package/dist/generators/react.js +10 -30
- package/dist/generators/vue.d.ts +4 -2
- package/dist/generators/vue.js +10 -31
- package/dist/index.d.ts +0 -1
- package/dist/index.js +21 -3
- package/dist/test.d.ts +5 -2
- package/dist/test.js +252 -206
- package/dist/types/ejs.d.ts +0 -1
- package/dist/types/ejs.js +0 -1
- package/dist/types/features.d.ts +1 -2
- package/dist/types/features.js +1 -1
- package/dist/types/index.d.ts +2 -4
- package/dist/types/index.js +2 -4
- package/dist/types/packageJson.d.ts +24 -0
- package/dist/types/packageJson.js +4 -0
- package/dist/types/viteConfig.d.ts +11 -9
- package/dist/types/viteConfig.js +0 -1
- package/dist/utils/deepMerge.d.ts +3 -1
- package/dist/utils/deepMerge.js +8 -1
- package/dist/utils/ejs.d.ts +3 -2
- package/dist/utils/ejs.js +2 -1
- package/dist/utils/featureMapping.d.ts +44 -0
- package/dist/utils/featureMapping.js +119 -0
- package/dist/utils/file.d.ts +22 -2
- package/dist/utils/file.js +35 -2
- package/dist/utils/generateFrameworkProject.d.ts +27 -0
- package/dist/utils/generateFrameworkProject.js +47 -0
- package/dist/utils/index.d.ts +11 -9
- package/dist/utils/index.js +11 -9
- package/dist/utils/install.d.ts +7 -4
- package/dist/utils/install.js +55 -12
- package/dist/utils/npmConfig.d.ts +15 -0
- package/dist/utils/npmConfig.js +79 -0
- package/dist/utils/prompts.d.ts +3 -2
- package/dist/utils/prompts.js +51 -5
- package/dist/utils/renderFeatures.d.ts +3 -2
- package/dist/utils/renderFeatures.js +41 -37
- package/dist/utils/renderTemplate.d.ts +13 -1
- package/dist/utils/renderTemplate.js +128 -61
- package/dist/utils/sortDependencies.d.ts +3 -2
- package/dist/utils/sortDependencies.js +3 -2
- package/dist/utils/viteConfigRender.d.ts +11 -14
- package/dist/utils/viteConfigRender.js +10 -173
- package/package.json +4 -2
- package/templates/common/base/.env +7 -7
- package/templates/common/base/.env.development +5 -5
- package/templates/common/base/.env.production +5 -5
- package/templates/common/base/package.json +23 -27
- package/templates/common/base/scripts/build.mts +37 -31
- package/templates/common/base/src/apis/index.ts +8 -8
- package/templates/common/base/src/apis/request.ts +43 -43
- package/templates/common/base/src/apis/services/example.ts +61 -40
- package/templates/common/base/src/apis/services/user.ts +33 -23
- package/templates/common/base/src/apis/types/common.ts +43 -28
- package/templates/common/base/src/apis/types/example.ts +15 -3
- package/templates/common/base/src/apis/types/index.ts +7 -7
- package/templates/common/base/src/apis/types/user.ts +39 -24
- package/templates/common/base/src/assets/fonts/index.css +7 -7
- package/templates/common/base/src/assets/styles/base.scss +72 -72
- package/templates/common/base/src/assets/styles/custom.scss +7 -7
- package/templates/common/base/src/assets/styles/tailwind.scss +6 -6
- package/templates/common/base/src/constants/index.ts +29 -29
- package/templates/common/base/src/utils/index.ts +88 -83
- package/templates/{vue/base/vite.config.ts → common/base/vite.config.ts.ejs} +28 -11
- package/templates/common/features/husky/.cz-config.cjs +35 -35
- package/templates/common/features/husky/commitlint.config.ts +32 -32
- package/templates/common/features/husky/node_modules/.bin/commitizen +17 -0
- package/templates/common/features/husky/node_modules/.bin/commitizen.CMD +12 -0
- package/templates/common/features/husky/node_modules/.bin/commitizen.ps1 +41 -0
- package/templates/common/features/husky/node_modules/.bin/commitlint +17 -0
- package/templates/common/features/husky/node_modules/.bin/commitlint.CMD +12 -0
- package/templates/common/features/husky/node_modules/.bin/commitlint.ps1 +41 -0
- package/templates/common/features/husky/node_modules/.bin/cz +17 -0
- package/templates/common/features/husky/node_modules/.bin/cz-cust +17 -0
- package/templates/common/features/husky/node_modules/.bin/cz-cust.CMD +12 -0
- package/templates/common/features/husky/node_modules/.bin/cz-cust.ps1 +41 -0
- package/templates/common/features/husky/node_modules/.bin/cz-customizable +17 -0
- package/templates/common/features/husky/node_modules/.bin/cz-customizable.CMD +12 -0
- package/templates/common/features/husky/node_modules/.bin/cz-customizable.ps1 +41 -0
- package/templates/common/features/husky/node_modules/.bin/cz.CMD +12 -0
- package/templates/common/features/husky/node_modules/.bin/cz.ps1 +41 -0
- package/templates/common/features/husky/node_modules/.bin/git-cz +17 -0
- package/templates/common/features/husky/node_modules/.bin/git-cz.CMD +12 -0
- package/templates/common/features/husky/node_modules/.bin/git-cz.ps1 +41 -0
- package/templates/common/features/husky/node_modules/.bin/husky +17 -0
- package/templates/common/features/husky/node_modules/.bin/husky.CMD +12 -0
- package/templates/common/features/husky/node_modules/.bin/husky.ps1 +41 -0
- package/templates/common/features/husky/node_modules/.bin/lint-staged +17 -0
- package/templates/common/features/husky/node_modules/.bin/lint-staged.CMD +12 -0
- package/templates/common/features/husky/node_modules/.bin/lint-staged.ps1 +41 -0
- package/templates/common/features/husky/package.json +6 -6
- package/templates/react/base/env.d.ts +19 -19
- package/templates/react/base/index.html +14 -14
- package/templates/react/base/node_modules/.bin/vite +17 -0
- package/templates/react/base/node_modules/.bin/vite.CMD +12 -0
- package/templates/react/base/node_modules/.bin/vite.ps1 +41 -0
- package/templates/react/base/package.json +18 -15
- package/templates/react/base/src/App.tsx +18 -18
- package/templates/react/base/src/assets/styles/main.scss +8 -8
- package/templates/react/base/src/main.tsx.ejs +51 -6
- package/templates/react/base/src/pages/about/index.tsx +14 -14
- package/templates/react/base/src/pages/home/index.tsx +14 -14
- package/templates/react/base/tsconfig.app.json +17 -17
- package/templates/react/base/tsconfig.base.json +23 -23
- package/templates/react/base/tsconfig.json +12 -12
- package/templates/react/base/tsconfig.node.json +15 -15
- package/templates/react/features/ant-design/package.json +6 -7
- package/templates/react/features/eslint/node_modules/.bin/eslint +17 -0
- package/templates/react/features/eslint/node_modules/.bin/eslint.CMD +12 -0
- package/templates/react/features/eslint/node_modules/.bin/eslint.ps1 +41 -0
- package/templates/react/features/eslint/package.json +3 -3
- package/templates/react/features/i18n/package.json +6 -7
- package/templates/react/features/i18n/src/locales/index.ts +7 -0
- package/templates/{common/base → react/features/i18n}/src/locales/lang/en.ts +30 -30
- package/templates/{common/base → react/features/i18n}/src/locales/lang/es.ts +30 -30
- package/templates/{common/base → react/features/i18n}/src/locales/lang/zh.ts +30 -30
- package/templates/react/features/manualRoutes/src/router/routes.tsx +13 -0
- package/templates/react/features/pageRoutes/package.json +1 -2
- package/templates/react/features/qiankun/package.json +6 -0
- package/templates/react/features/qiankun/src/qiankun/index.ts +80 -0
- package/templates/react/features/router/package.json +1 -1
- package/templates/react/features/sentry/package.json +6 -7
- package/templates/react/features/sentry/src/utils/sentry.ts +10 -0
- package/templates/react/features/zustand/package.json +1 -1
- package/templates/react/features/zustand/src/stores/user.ts +42 -6
- package/templates/react/features/zustand/src/types/stores.ts +8 -1
- package/templates/vue/base/env.d.ts +27 -27
- package/templates/vue/base/index.html +14 -14
- package/templates/vue/base/node_modules/.bin/vite +17 -0
- package/templates/vue/base/node_modules/.bin/vite.CMD +12 -0
- package/templates/vue/base/node_modules/.bin/vite.ps1 +41 -0
- package/templates/vue/base/node_modules/.bin/vue-tsc +17 -0
- package/templates/vue/base/node_modules/.bin/vue-tsc.CMD +12 -0
- package/templates/vue/base/node_modules/.bin/vue-tsc.ps1 +41 -0
- package/templates/vue/base/package.json +16 -13
- package/templates/vue/base/src/App.vue +13 -13
- package/templates/vue/base/src/assets/styles/main.scss +9 -9
- package/templates/vue/base/src/directives/index.ts +36 -36
- package/templates/vue/base/src/layouts/index.ts +5 -7
- package/templates/vue/base/src/main.ts.ejs +9 -25
- package/templates/vue/base/src/pages/about/index.vue +31 -31
- package/templates/vue/base/src/pages/home/index.vue +31 -31
- package/templates/vue/base/src/router/index.ts.ejs +10 -13
- package/templates/vue/base/tsconfig.app.json +17 -17
- package/templates/vue/base/tsconfig.base.json +23 -23
- package/templates/vue/base/tsconfig.json +12 -12
- package/templates/vue/base/tsconfig.node.json +15 -15
- package/templates/vue/features/ant-design-vue/package.json +6 -7
- package/templates/vue/{base → features/ant-design-vue}/src/layouts/AntDesign.vue +86 -86
- package/templates/vue/features/element-plus/package.json +6 -7
- package/templates/vue/{base → features/element-plus}/src/assets/styles/element/index.scss +27 -27
- package/templates/vue/features/element-plus/src/components/SubMenu/index.ts +9 -0
- package/templates/vue/{base → features/element-plus}/src/components/SubMenu/src/_types/index.ts +6 -6
- package/templates/vue/{base → features/element-plus}/src/components/SubMenu/src/_types/props.ts +11 -11
- package/templates/vue/{base → features/element-plus}/src/components/SubMenu/src/index.vue +24 -24
- package/templates/vue/{base → features/element-plus}/src/layouts/element.vue +81 -81
- package/templates/vue/features/eslint/node_modules/.bin/eslint +17 -0
- package/templates/vue/features/eslint/node_modules/.bin/eslint.CMD +12 -0
- package/templates/vue/features/eslint/node_modules/.bin/eslint.ps1 +41 -0
- package/templates/vue/features/eslint/package.json +3 -3
- package/templates/vue/features/i18n/package.json +5 -5
- package/templates/vue/features/i18n/src/locales/index.ts +23 -16
- package/templates/vue/features/i18n/src/locales/lang/en.ts +30 -0
- package/templates/vue/features/i18n/src/locales/lang/es.ts +30 -0
- package/templates/vue/features/i18n/src/locales/lang/zh.ts +30 -0
- package/templates/vue/features/manualRoutes/src/router/routes.ts +35 -27
- package/templates/vue/features/pageRoutes/package.json +5 -5
- package/templates/vue/features/pinia/package.json +3 -2
- package/templates/vue/features/pinia/src/stores/index.ts +8 -0
- package/templates/vue/features/pinia/src/stores/system.ts +60 -0
- package/templates/vue/features/pinia/src/stores/user.ts +33 -13
- package/templates/vue/features/qiankun/package.json +5 -5
- package/templates/vue/features/qiankun/src/qiankun/index.ts +19 -0
- package/templates/vue/features/router/package.json +1 -1
- package/templates/vue/features/sentry/package.json +6 -6
- package/templates/vue/features/sentry/src/utils/sentry.ts +12 -0
- package/dist/commands/create.d.ts.map +0 -1
- package/dist/commands/create.js.map +0 -1
- package/dist/commands/index.d.ts.map +0 -1
- package/dist/commands/index.js.map +0 -1
- package/dist/generators/index.d.ts.map +0 -1
- package/dist/generators/index.js.map +0 -1
- package/dist/generators/project.d.ts.map +0 -1
- package/dist/generators/project.js.map +0 -1
- package/dist/generators/react.d.ts.map +0 -1
- package/dist/generators/react.js.map +0 -1
- package/dist/generators/vue.d.ts.map +0 -1
- package/dist/generators/vue.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/test.d.ts.map +0 -1
- package/dist/test.js.map +0 -1
- package/dist/types/ejs.d.ts.map +0 -1
- package/dist/types/ejs.js.map +0 -1
- package/dist/types/features.d.ts.map +0 -1
- package/dist/types/features.js.map +0 -1
- package/dist/types/index.d.ts.map +0 -1
- package/dist/types/index.js.map +0 -1
- package/dist/types/viteConfig.d.ts.map +0 -1
- package/dist/types/viteConfig.js.map +0 -1
- package/dist/utils/deepMerge.d.ts.map +0 -1
- package/dist/utils/deepMerge.js.map +0 -1
- package/dist/utils/ejs.d.ts.map +0 -1
- package/dist/utils/ejs.js.map +0 -1
- package/dist/utils/file.d.ts.map +0 -1
- package/dist/utils/file.js.map +0 -1
- package/dist/utils/index.d.ts.map +0 -1
- package/dist/utils/index.js.map +0 -1
- package/dist/utils/install.d.ts.map +0 -1
- package/dist/utils/install.js.map +0 -1
- package/dist/utils/prompts.d.ts.map +0 -1
- package/dist/utils/prompts.js.map +0 -1
- package/dist/utils/renderFeatures.d.ts.map +0 -1
- package/dist/utils/renderFeatures.js.map +0 -1
- package/dist/utils/renderTemplate.d.ts.map +0 -1
- package/dist/utils/renderTemplate.js.map +0 -1
- package/dist/utils/sortDependencies.d.ts.map +0 -1
- package/dist/utils/sortDependencies.js.map +0 -1
- package/dist/utils/viteConfigRender.d.ts.map +0 -1
- package/dist/utils/viteConfigRender.js.map +0 -1
- package/templates/common/base/pnpm-workspace.yaml +0 -37
- package/templates/common/features/husky/pnpm-workspace.yaml +0 -9
- package/templates/react/base/pnpm-workspace.yaml +0 -9
- package/templates/react/base/src/stores/user.ts +0 -39
- package/templates/react/base/vite.config.ts +0 -52
- package/templates/react/features/ant-design/pnpm-workspace.yaml +0 -5
- package/templates/react/features/eslint/pnpm-workspace.yaml +0 -6
- package/templates/react/features/i18n/pnpm-workspace.yaml +0 -5
- package/templates/react/features/pageRoutes/pnpm-workspace.yaml +0 -4
- package/templates/react/features/pageRoutes/vite.config.data.ts +0 -10
- package/templates/react/features/router/pnpm-workspace.yaml +0 -3
- package/templates/react/features/sentry/pnpm-workspace.yaml +0 -5
- package/templates/react/features/sentry/vite.config.data.ts +0 -23
- package/templates/react/features/zustand/pnpm-workspace.yaml +0 -3
- package/templates/vue/base/pnpm-workspace.yaml +0 -6
- package/templates/vue/base/src/components/SubMenu/index.ts +0 -9
- package/templates/vue/base/src/stores/index.ts +0 -16
- package/templates/vue/base/src/stores/modules/system.ts +0 -52
- package/templates/vue/base/src/stores/modules/user.ts +0 -48
- package/templates/vue/features/ant-design-vue/pnpm-workspace.yaml +0 -5
- package/templates/vue/features/element-plus/pnpm-workspace.yaml +0 -5
- package/templates/vue/features/element-plus/vite.config.data.ts +0 -15
- package/templates/vue/features/eslint/pnpm-workspace.yaml +0 -6
- package/templates/vue/features/i18n/pnpm-workspace.yaml +0 -3
- package/templates/vue/features/pageRoutes/pnpm-workspace.yaml +0 -4
- package/templates/vue/features/pageRoutes/vite.config.data.ts +0 -9
- package/templates/vue/features/pinia/pnpm-workspace.yaml +0 -4
- package/templates/vue/features/qiankun/pnpm-workspace.yaml +0 -3
- package/templates/vue/features/router/pnpm-workspace.yaml +0 -3
- package/templates/vue/features/sentry/pnpm-workspace.yaml +0 -4
- package/templates/vue/features/sentry/vite.config.data.ts +0 -23
package/dist/utils/install.js
CHANGED
|
@@ -2,36 +2,79 @@
|
|
|
2
2
|
* 依赖安装工具
|
|
3
3
|
* 执行包管理器安装依赖
|
|
4
4
|
*/
|
|
5
|
-
import {
|
|
5
|
+
import { exec } from 'node:child_process';
|
|
6
|
+
import { promisify } from 'node:util';
|
|
7
|
+
import { validatePath } from "./file.js";
|
|
8
|
+
const execAsync = promisify(exec);
|
|
9
|
+
/** 重试延迟基数(毫秒) */
|
|
10
|
+
const RETRY_DELAY_BASE_MS = 1000;
|
|
11
|
+
/**
|
|
12
|
+
* 验证命令参数安全性
|
|
13
|
+
* @param packageManager 包管理器类型
|
|
14
|
+
* @param cwd 工作目录
|
|
15
|
+
* @throws {Error} 如果参数不安全
|
|
16
|
+
*/
|
|
17
|
+
function validateInstallParams(packageManager, cwd) {
|
|
18
|
+
// 验证包管理器类型
|
|
19
|
+
const validPackageManagers = ['pnpm', 'npm', 'yarn'];
|
|
20
|
+
if (!validPackageManagers.includes(packageManager)) {
|
|
21
|
+
throw new Error(`不支持的包管理器: ${packageManager}`);
|
|
22
|
+
}
|
|
23
|
+
// 验证工作目录路径(防止路径遍历攻击)
|
|
24
|
+
validatePath(cwd);
|
|
25
|
+
}
|
|
6
26
|
/**
|
|
7
27
|
* 安装依赖
|
|
8
28
|
* @param packageManager 包管理器
|
|
9
29
|
* @param cwd 工作目录
|
|
30
|
+
* @param retries 重试次数,默认 0(不重试)
|
|
31
|
+
* @returns Promise<void>
|
|
32
|
+
* @throws {Error} 如果安装失败
|
|
10
33
|
*/
|
|
11
|
-
export function installDependencies(packageManager, cwd) {
|
|
34
|
+
export async function installDependencies(packageManager, cwd, retries = 0) {
|
|
35
|
+
// 验证参数安全性
|
|
36
|
+
validateInstallParams(packageManager, cwd);
|
|
12
37
|
const commands = {
|
|
13
38
|
pnpm: 'pnpm install',
|
|
14
39
|
npm: 'npm install',
|
|
15
40
|
yarn: 'yarn install',
|
|
16
41
|
};
|
|
17
42
|
const command = commands[packageManager];
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
43
|
+
let lastError;
|
|
44
|
+
for (let attempt = 0; attempt <= retries; attempt++) {
|
|
45
|
+
try {
|
|
46
|
+
await execAsync(command, {
|
|
47
|
+
cwd,
|
|
48
|
+
});
|
|
49
|
+
return; // 成功则返回
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
lastError = error instanceof Error ? error : new Error(String(error));
|
|
53
|
+
if (attempt < retries) {
|
|
54
|
+
// 等待后重试(指数退避)
|
|
55
|
+
await new Promise(resolve => setTimeout(resolve, RETRY_DELAY_BASE_MS * (attempt + 1)));
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
// 所有重试都失败,抛出详细错误
|
|
60
|
+
throw new Error(`依赖安装失败 (${packageManager}): ${lastError?.message || '未知错误'}\n`
|
|
61
|
+
+ `工作目录: ${cwd}\n`
|
|
62
|
+
+ `命令: ${command}`, { cause: lastError });
|
|
22
63
|
}
|
|
23
64
|
/**
|
|
24
65
|
* 初始化 Git 仓库
|
|
25
66
|
* @param cwd 工作目录
|
|
67
|
+
* @returns Promise<void>
|
|
26
68
|
*/
|
|
27
|
-
export function initGit(cwd) {
|
|
69
|
+
export async function initGit(cwd) {
|
|
28
70
|
try {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
71
|
+
// 验证路径安全性
|
|
72
|
+
validatePath(cwd);
|
|
73
|
+
await execAsync('git init', { cwd });
|
|
74
|
+
await execAsync('git add .', { cwd });
|
|
75
|
+
await execAsync('git commit -m "chore: initial commit"', { cwd });
|
|
32
76
|
}
|
|
33
77
|
catch {
|
|
34
|
-
// Git
|
|
78
|
+
// Git 初始化失败不影响项目创建,静默失败
|
|
35
79
|
}
|
|
36
80
|
}
|
|
37
|
-
//# sourceMappingURL=install.js.map
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 读取 npm 配置工具
|
|
3
|
+
* 用于获取全局配置作为默认值
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* 获取默认作者信息
|
|
7
|
+
* 优先级:npm init-author-name/email > git user.name/email
|
|
8
|
+
* @returns 作者字符串,格式:Name <email> 或 Name
|
|
9
|
+
*/
|
|
10
|
+
export declare function getDefaultAuthor(): string;
|
|
11
|
+
/**
|
|
12
|
+
* 获取默认许可证
|
|
13
|
+
* @returns 许可证名称,默认为 'MIT'
|
|
14
|
+
*/
|
|
15
|
+
export declare function getDefaultLicense(): string;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 读取 npm 配置工具
|
|
3
|
+
* 用于获取全局配置作为默认值
|
|
4
|
+
*/
|
|
5
|
+
import { execSync } from 'node:child_process';
|
|
6
|
+
/**
|
|
7
|
+
* 读取 npm 配置值
|
|
8
|
+
* @param key 配置键名
|
|
9
|
+
* @returns 配置值,如果不存在则返回 null
|
|
10
|
+
*/
|
|
11
|
+
function getNpmConfig(key) {
|
|
12
|
+
try {
|
|
13
|
+
// 使用 stdio: 'pipe' 并只读取 stdout,忽略 stderr 中的警告
|
|
14
|
+
const result = execSync(`npm config get ${key}`, {
|
|
15
|
+
encoding: 'utf-8',
|
|
16
|
+
stdio: ['ignore', 'pipe', 'ignore'], // stdin: ignore, stdout: pipe, stderr: ignore
|
|
17
|
+
});
|
|
18
|
+
const value = result.trim();
|
|
19
|
+
// npm config get 返回 "undefined" 字符串表示未设置
|
|
20
|
+
if (value === 'undefined' || value === '') {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
return value;
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* 读取 Git 配置值
|
|
31
|
+
* @param key 配置键名
|
|
32
|
+
* @returns 配置值,如果不存在则返回 null
|
|
33
|
+
*/
|
|
34
|
+
function getGitConfig(key) {
|
|
35
|
+
try {
|
|
36
|
+
const value = execSync(`git config --global ${key}`, { encoding: 'utf-8' }).trim();
|
|
37
|
+
if (value === '') {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
return value;
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* 获取默认作者信息
|
|
48
|
+
* 优先级:npm init-author-name/email > git user.name/email
|
|
49
|
+
* @returns 作者字符串,格式:Name <email> 或 Name
|
|
50
|
+
*/
|
|
51
|
+
export function getDefaultAuthor() {
|
|
52
|
+
// 优先从 npm 配置读取
|
|
53
|
+
const npmName = getNpmConfig('init-author-name');
|
|
54
|
+
const npmEmail = getNpmConfig('init-author-email');
|
|
55
|
+
const npmUrl = getNpmConfig('init-author-url');
|
|
56
|
+
// 如果 npm 配置不存在,尝试从 git 配置读取
|
|
57
|
+
const gitName = npmName || getGitConfig('user.name');
|
|
58
|
+
const gitEmail = npmEmail || getGitConfig('user.email');
|
|
59
|
+
// 组合作者信息
|
|
60
|
+
const parts = [];
|
|
61
|
+
if (gitName) {
|
|
62
|
+
parts.push(gitName);
|
|
63
|
+
}
|
|
64
|
+
if (gitEmail) {
|
|
65
|
+
parts.push(`<${gitEmail}>`);
|
|
66
|
+
}
|
|
67
|
+
if (npmUrl && !gitEmail) {
|
|
68
|
+
// 如果有 URL 但没有邮箱,添加 URL
|
|
69
|
+
parts.push(`(${npmUrl})`);
|
|
70
|
+
}
|
|
71
|
+
return parts.join(' ') || '';
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* 获取默认许可证
|
|
75
|
+
* @returns 许可证名称,默认为 'MIT'
|
|
76
|
+
*/
|
|
77
|
+
export function getDefaultLicense() {
|
|
78
|
+
return getNpmConfig('init-license') || 'MIT';
|
|
79
|
+
}
|
package/dist/utils/prompts.d.ts
CHANGED
|
@@ -2,15 +2,16 @@
|
|
|
2
2
|
* 交互式问答工具
|
|
3
3
|
* 收集用户的项目配置信息(对标 create-vue)
|
|
4
4
|
*/
|
|
5
|
-
import type { ProjectConfigType } from '../types';
|
|
5
|
+
import type { ProjectConfigType } from '../types/index.ts';
|
|
6
6
|
/**
|
|
7
7
|
* 收集项目配置信息
|
|
8
8
|
* @param projectName 项目名称(可选)
|
|
9
|
+
* @returns 项目配置对象
|
|
9
10
|
*/
|
|
10
11
|
export declare function collectProjectConfig(projectName?: string): Promise<ProjectConfigType>;
|
|
11
12
|
/**
|
|
12
13
|
* 确认覆盖目录
|
|
13
14
|
* @param dirPath 目录路径
|
|
15
|
+
* @returns 是否确认覆盖
|
|
14
16
|
*/
|
|
15
17
|
export declare function confirmOverwrite(dirPath: string): Promise<boolean>;
|
|
16
|
-
//# sourceMappingURL=prompts.d.ts.map
|
package/dist/utils/prompts.js
CHANGED
|
@@ -2,13 +2,18 @@
|
|
|
2
2
|
* 交互式问答工具
|
|
3
3
|
* 收集用户的项目配置信息(对标 create-vue)
|
|
4
4
|
*/
|
|
5
|
+
import fs from 'node:fs';
|
|
5
6
|
import process from 'node:process';
|
|
6
7
|
import inquirer from 'inquirer';
|
|
8
|
+
import { getDefaultAuthor } from "./npmConfig.js";
|
|
7
9
|
/**
|
|
8
10
|
* 收集项目配置信息
|
|
9
11
|
* @param projectName 项目名称(可选)
|
|
12
|
+
* @returns 项目配置对象
|
|
10
13
|
*/
|
|
11
14
|
export async function collectProjectConfig(projectName) {
|
|
15
|
+
// 获取默认作者信息
|
|
16
|
+
const defaultAuthor = getDefaultAuthor();
|
|
12
17
|
const answers = await inquirer.prompt([
|
|
13
18
|
// 项目名称
|
|
14
19
|
{
|
|
@@ -17,12 +22,53 @@ export async function collectProjectConfig(projectName) {
|
|
|
17
22
|
message: '项目名称:',
|
|
18
23
|
default: projectName || 'my-project',
|
|
19
24
|
validate: (input) => {
|
|
20
|
-
|
|
25
|
+
const trimmed = input.trim();
|
|
26
|
+
if (!trimmed) {
|
|
21
27
|
return '项目名称不能为空';
|
|
22
28
|
}
|
|
23
|
-
|
|
29
|
+
const minLength = 1;
|
|
30
|
+
const maxLength = 214;
|
|
31
|
+
if (trimmed.length < minLength || trimmed.length > maxLength) {
|
|
32
|
+
return `项目名称长度必须在 ${minLength}-${maxLength} 个字符之间`;
|
|
33
|
+
}
|
|
34
|
+
if (!/^[\w-]+$/.test(trimmed)) {
|
|
24
35
|
return '项目名称只能包含字母、数字、连字符和下划线';
|
|
25
36
|
}
|
|
37
|
+
const reservedNames = [
|
|
38
|
+
'node',
|
|
39
|
+
'npm',
|
|
40
|
+
'test',
|
|
41
|
+
'lib',
|
|
42
|
+
'api',
|
|
43
|
+
'www',
|
|
44
|
+
'admin',
|
|
45
|
+
'root',
|
|
46
|
+
'config',
|
|
47
|
+
'build',
|
|
48
|
+
'dist',
|
|
49
|
+
'src',
|
|
50
|
+
'public',
|
|
51
|
+
'private',
|
|
52
|
+
];
|
|
53
|
+
if (reservedNames.includes(trimmed.toLowerCase())) {
|
|
54
|
+
return `项目名称不能使用保留名称: ${trimmed}`;
|
|
55
|
+
}
|
|
56
|
+
// 检查目标目录是否已存在且不为空
|
|
57
|
+
const targetDir = `${process.cwd()}/${trimmed}`;
|
|
58
|
+
if (fs.existsSync(targetDir)) {
|
|
59
|
+
try {
|
|
60
|
+
const stats = fs.statSync(targetDir);
|
|
61
|
+
if (stats.isDirectory()) {
|
|
62
|
+
const files = fs.readdirSync(targetDir);
|
|
63
|
+
if (files.length > 0) {
|
|
64
|
+
return `目录 ${targetDir} 已存在且不为空,请选择其他名称或先清空该目录`;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
// 忽略检查错误,让后续流程处理
|
|
70
|
+
}
|
|
71
|
+
}
|
|
26
72
|
return true;
|
|
27
73
|
},
|
|
28
74
|
},
|
|
@@ -38,7 +84,7 @@ export async function collectProjectConfig(projectName) {
|
|
|
38
84
|
type: 'input',
|
|
39
85
|
name: 'author',
|
|
40
86
|
message: '作者:',
|
|
41
|
-
default:
|
|
87
|
+
default: defaultAuthor,
|
|
42
88
|
},
|
|
43
89
|
// 框架选择
|
|
44
90
|
{
|
|
@@ -130,7 +176,7 @@ export async function collectProjectConfig(projectName) {
|
|
|
130
176
|
message: '是否启用 Git Hooks (husky + commitlint)?',
|
|
131
177
|
default: true,
|
|
132
178
|
},
|
|
133
|
-
//
|
|
179
|
+
// 包管理器选择
|
|
134
180
|
{
|
|
135
181
|
type: 'list',
|
|
136
182
|
name: 'packageManager',
|
|
@@ -165,6 +211,7 @@ export async function collectProjectConfig(projectName) {
|
|
|
165
211
|
/**
|
|
166
212
|
* 确认覆盖目录
|
|
167
213
|
* @param dirPath 目录路径
|
|
214
|
+
* @returns 是否确认覆盖
|
|
168
215
|
*/
|
|
169
216
|
export async function confirmOverwrite(dirPath) {
|
|
170
217
|
const { confirm } = await inquirer.prompt([
|
|
@@ -177,4 +224,3 @@ export async function confirmOverwrite(dirPath) {
|
|
|
177
224
|
]);
|
|
178
225
|
return confirm;
|
|
179
226
|
}
|
|
180
|
-
//# sourceMappingURL=prompts.js.map
|
|
@@ -2,17 +2,18 @@
|
|
|
2
2
|
* Features 渲染工具
|
|
3
3
|
* 统一处理 features 的渲染逻辑
|
|
4
4
|
*/
|
|
5
|
-
import type { ProjectConfigType } from '../types';
|
|
5
|
+
import type { ProjectConfigType } from '../types/index.ts';
|
|
6
6
|
/**
|
|
7
7
|
* 渲染框架特定的 features
|
|
8
8
|
* @param config 项目配置
|
|
9
9
|
* @param targetDir 目标目录
|
|
10
|
+
* @throws {Error} 如果路径不安全或模板渲染失败
|
|
10
11
|
*/
|
|
11
12
|
export declare function renderFrameworkFeatures(config: ProjectConfigType, targetDir: string): void;
|
|
12
13
|
/**
|
|
13
14
|
* 渲染公共 features
|
|
14
15
|
* @param config 项目配置
|
|
15
16
|
* @param targetDir 目标目录
|
|
17
|
+
* @throws {Error} 如果路径不安全或模板渲染失败
|
|
16
18
|
*/
|
|
17
19
|
export declare function renderCommonFeatures(config: ProjectConfigType, targetDir: string): void;
|
|
18
|
-
//# sourceMappingURL=renderFeatures.d.ts.map
|
|
@@ -3,25 +3,48 @@
|
|
|
3
3
|
* 统一处理 features 的渲染逻辑
|
|
4
4
|
*/
|
|
5
5
|
import path from 'node:path';
|
|
6
|
-
import { getTemplatesDir } from
|
|
7
|
-
import { renderTemplate } from
|
|
6
|
+
import { getTemplatesDir } from "./file.js";
|
|
7
|
+
import { renderTemplate } from "./renderTemplate.js";
|
|
8
|
+
import { getCommonFeatureMap, getConfigToFeatureMap, getRouteModeFeature, getUILibraryFeature, } from "./featureMapping.js";
|
|
9
|
+
/**
|
|
10
|
+
* 检查 UI 库是否适用于指定框架
|
|
11
|
+
* @param framework 框架类型
|
|
12
|
+
* @param uiLibrary UI 库类型
|
|
13
|
+
* @returns 是否适用
|
|
14
|
+
*/
|
|
15
|
+
function isUILibrarySupported(framework, uiLibrary) {
|
|
16
|
+
if (framework === 'vue') {
|
|
17
|
+
return uiLibrary === 'element-plus' || uiLibrary === 'ant-design-vue';
|
|
18
|
+
}
|
|
19
|
+
if (framework === 'react') {
|
|
20
|
+
return uiLibrary === 'ant-design';
|
|
21
|
+
}
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* 渲染 UI 库特性模板
|
|
26
|
+
* @param config 项目配置
|
|
27
|
+
* @param targetDir 目标目录
|
|
28
|
+
* @param templatesDir 模板目录
|
|
29
|
+
* @throws {Error} 如果路径不安全或模板渲染失败
|
|
30
|
+
*/
|
|
31
|
+
function renderUILibraryFeature(config, targetDir, templatesDir) {
|
|
32
|
+
const { framework, uiLibrary } = config;
|
|
33
|
+
if (isUILibrarySupported(framework, uiLibrary)) {
|
|
34
|
+
const uiLibraryFeature = getUILibraryFeature(uiLibrary);
|
|
35
|
+
renderTemplate(path.join(templatesDir, framework, 'features', uiLibraryFeature), targetDir);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
8
38
|
/**
|
|
9
39
|
* 渲染框架特定的 features
|
|
10
40
|
* @param config 项目配置
|
|
11
41
|
* @param targetDir 目标目录
|
|
42
|
+
* @throws {Error} 如果路径不安全或模板渲染失败
|
|
12
43
|
*/
|
|
13
44
|
export function renderFrameworkFeatures(config, targetDir) {
|
|
14
45
|
const templatesDir = getTemplatesDir();
|
|
15
46
|
const framework = config.framework;
|
|
16
|
-
|
|
17
|
-
const featureMap = {
|
|
18
|
-
router: 'router',
|
|
19
|
-
stateManagement: framework === 'vue' ? 'pinia' : 'zustand',
|
|
20
|
-
eslint: 'eslint',
|
|
21
|
-
i18n: 'i18n',
|
|
22
|
-
sentry: 'sentry',
|
|
23
|
-
qiankun: 'qiankun',
|
|
24
|
-
};
|
|
47
|
+
const featureMap = getConfigToFeatureMap(framework);
|
|
25
48
|
// 统一处理布尔类型的 features
|
|
26
49
|
for (const [configKey, featureName] of Object.entries(featureMap)) {
|
|
27
50
|
if (config[configKey] === true) {
|
|
@@ -29,39 +52,21 @@ export function renderFrameworkFeatures(config, targetDir) {
|
|
|
29
52
|
renderTemplate(featurePath, targetDir);
|
|
30
53
|
}
|
|
31
54
|
}
|
|
32
|
-
//
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
renderTemplate(path.join(templatesDir, framework, 'features', 'pageRoutes'), targetDir);
|
|
38
|
-
}
|
|
39
|
-
// 特殊处理:UI 库相关的 features
|
|
40
|
-
if (framework === 'vue') {
|
|
41
|
-
if (config.uiLibrary === 'element-plus') {
|
|
42
|
-
renderTemplate(path.join(templatesDir, framework, 'features', 'element-plus'), targetDir);
|
|
43
|
-
}
|
|
44
|
-
else if (config.uiLibrary === 'ant-design-vue') {
|
|
45
|
-
renderTemplate(path.join(templatesDir, framework, 'features', 'ant-design-vue'), targetDir);
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
else if (framework === 'react') {
|
|
49
|
-
if (config.uiLibrary === 'ant-design') {
|
|
50
|
-
renderTemplate(path.join(templatesDir, framework, 'features', 'ant-design'), targetDir);
|
|
51
|
-
}
|
|
52
|
-
}
|
|
55
|
+
// 路由模式
|
|
56
|
+
const routeModeFeature = getRouteModeFeature(config.routeMode);
|
|
57
|
+
renderTemplate(path.join(templatesDir, framework, 'features', routeModeFeature), targetDir);
|
|
58
|
+
// UI 库
|
|
59
|
+
renderUILibraryFeature(config, targetDir, templatesDir);
|
|
53
60
|
}
|
|
54
61
|
/**
|
|
55
62
|
* 渲染公共 features
|
|
56
63
|
* @param config 项目配置
|
|
57
64
|
* @param targetDir 目标目录
|
|
65
|
+
* @throws {Error} 如果路径不安全或模板渲染失败
|
|
58
66
|
*/
|
|
59
67
|
export function renderCommonFeatures(config, targetDir) {
|
|
60
68
|
const templatesDir = getTemplatesDir();
|
|
61
|
-
|
|
62
|
-
const commonFeatureMap = {
|
|
63
|
-
gitHooks: 'husky',
|
|
64
|
-
};
|
|
69
|
+
const commonFeatureMap = getCommonFeatureMap();
|
|
65
70
|
for (const [configKey, featureName] of Object.entries(commonFeatureMap)) {
|
|
66
71
|
if (config[configKey] === true) {
|
|
67
72
|
const featurePath = path.join(templatesDir, 'common', 'features', featureName);
|
|
@@ -69,4 +74,3 @@ export function renderCommonFeatures(config, targetDir) {
|
|
|
69
74
|
}
|
|
70
75
|
}
|
|
71
76
|
}
|
|
72
|
-
//# sourceMappingURL=renderFeatures.js.map
|
|
@@ -1,6 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* 渲染模板到目标目录
|
|
3
3
|
* 支持物理路径合并和配置文件深度合并
|
|
4
|
+
* @param src 源路径
|
|
5
|
+
* @param dest 目标路径
|
|
6
|
+
* @throws {Error} 如果路径不安全、文件操作失败
|
|
4
7
|
*/
|
|
5
8
|
export declare function renderTemplate(src: string, dest: string): void;
|
|
6
|
-
|
|
9
|
+
/**
|
|
10
|
+
* 更新 package.json 的元数据字段(name, description, author, packageManager)
|
|
11
|
+
* @param packageJsonPath package.json 文件路径
|
|
12
|
+
* @param projectName 项目名称
|
|
13
|
+
* @param description 项目描述
|
|
14
|
+
* @param author 作者
|
|
15
|
+
* @param packageManager 包管理器类型
|
|
16
|
+
* @throws {Error} 如果文件读取失败、JSON 解析失败或写入失败
|
|
17
|
+
*/
|
|
18
|
+
export declare function updatePackageJsonMetadata(packageJsonPath: string, projectName: string, description: string, author: string, packageManager: string): void;
|