@ysjdemo/umi-create-cli 0.0.2 → 0.0.3
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/README.md +49 -16
- package/bin/cli.js +2 -2
- package/lib/create.js +111 -86
- package/lib/templates/basic/src/pages/Home/index.tsx +1 -1
- package/lib/templates/index.js +62 -16
- package/package.json +1 -2
package/README.md
CHANGED
|
@@ -2,26 +2,45 @@
|
|
|
2
2
|
|
|
3
3
|
一个用于创建Umi4项目的脚手架工具
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## 使用方式(推荐npx)
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
#
|
|
9
|
-
|
|
8
|
+
# 🔥 推荐:使用 npx 直接创建(无需安装)
|
|
9
|
+
# 会自动提示选择模板,默认推荐 Ant Design Pro
|
|
10
|
+
npx @ysjdemo/umi-create-cli create my-project
|
|
10
11
|
|
|
11
|
-
#
|
|
12
|
-
|
|
12
|
+
# 或直接指定模板
|
|
13
|
+
npx @ysjdemo/umi-create-cli create my-project -t antd
|
|
14
|
+
npx @ysjdemo/umi-create-cli create my-project -t basic
|
|
15
|
+
|
|
16
|
+
# 查看帮助
|
|
17
|
+
npx @ysjdemo/umi-create-cli --help
|
|
13
18
|
```
|
|
14
19
|
|
|
15
|
-
##
|
|
20
|
+
## 交互式模板选择
|
|
21
|
+
|
|
22
|
+
当您运行创建命令时,会看到如下交互界面:
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
🚀 创建 Umi4 项目...
|
|
26
|
+
📋 请选择项目模板:
|
|
27
|
+
❯ 🎨 antd - Ant Design Pro 模板 (推荐)
|
|
28
|
+
📦 basic - 基础模板
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## 安装方式(可选)
|
|
32
|
+
|
|
33
|
+
如果需要频繁使用,可以选择全局安装:
|
|
16
34
|
|
|
17
35
|
```bash
|
|
18
|
-
#
|
|
19
|
-
|
|
36
|
+
# 全局安装
|
|
37
|
+
npm install -g @ysjdemo/umi-create-cli
|
|
20
38
|
|
|
21
|
-
#
|
|
22
|
-
|
|
39
|
+
# 或使用 yarn
|
|
40
|
+
yarn global add @ysjdemo/umi-create-cli
|
|
23
41
|
|
|
24
|
-
#
|
|
42
|
+
# 安装后使用
|
|
43
|
+
ysj-umi create my-project
|
|
25
44
|
ysj-umi --version
|
|
26
45
|
```
|
|
27
46
|
|
|
@@ -31,19 +50,33 @@ ysj-umi --version
|
|
|
31
50
|
- 📦 内置常用配置模板
|
|
32
51
|
- 🎨 支持TypeScript
|
|
33
52
|
- 📱 支持多种UI库选择
|
|
53
|
+
- ⚡️ 支持npx直接使用,无需安装
|
|
54
|
+
- 🎯 交互式模板选择,默认推荐最佳实践
|
|
34
55
|
|
|
35
56
|
## 模板选项
|
|
36
57
|
|
|
37
|
-
-
|
|
38
|
-
|
|
39
|
-
-
|
|
40
|
-
|
|
58
|
+
- **🎨 Ant Design Pro 模板**(推荐):企业级后台管理系统
|
|
59
|
+
```bash
|
|
60
|
+
npx @ysjdemo/umi-create-cli create my-admin -t antd
|
|
61
|
+
```
|
|
62
|
+
- 集成 Ant Design 5.0
|
|
63
|
+
- Pro Components 组件库
|
|
64
|
+
- 完整的后台管理界面
|
|
65
|
+
- 仪表盘、用户管理、设置页面
|
|
66
|
+
|
|
67
|
+
- **📦 基础模板**:轻量级起始项目
|
|
68
|
+
```bash
|
|
69
|
+
npx @ysjdemo/umi-create-cli create my-project -t basic
|
|
70
|
+
```
|
|
71
|
+
- 基础 Umi 4 配置
|
|
72
|
+
- TypeScript 支持
|
|
73
|
+
- 简洁的项目结构
|
|
41
74
|
|
|
42
75
|
## 开发
|
|
43
76
|
|
|
44
77
|
```bash
|
|
45
78
|
# 克隆项目
|
|
46
|
-
git clone https://github.com/
|
|
79
|
+
git clone https://github.com/Ivan-YangSj/umi-cli.git
|
|
47
80
|
|
|
48
81
|
# 安装依赖
|
|
49
82
|
npm install
|
package/bin/cli.js
CHANGED
|
@@ -12,7 +12,7 @@ program
|
|
|
12
12
|
program
|
|
13
13
|
.command('create <project-name>')
|
|
14
14
|
.description('创建一个新的 Umi4 项目')
|
|
15
|
-
.option('-t, --template <template>', '使用指定模板 (basic, antd
|
|
15
|
+
.option('-t, --template <template>', '使用指定模板 (basic, antd, qiankun)')
|
|
16
16
|
.action(async (projectName, options) => {
|
|
17
17
|
try {
|
|
18
18
|
await createProject(projectName, options);
|
|
@@ -26,7 +26,7 @@ program
|
|
|
26
26
|
program
|
|
27
27
|
.command('init')
|
|
28
28
|
.description('在当前目录初始化 Umi4 项目')
|
|
29
|
-
.option('-t, --template <template>', '使用指定模板 (basic, antd
|
|
29
|
+
.option('-t, --template <template>', '使用指定模板 (basic, antd, qiankun)')
|
|
30
30
|
.action(async (options) => {
|
|
31
31
|
try {
|
|
32
32
|
await initProject(options);
|
package/lib/create.js
CHANGED
|
@@ -1,146 +1,171 @@
|
|
|
1
|
-
const fs = require(
|
|
2
|
-
const path = require(
|
|
3
|
-
const inquirer = require(
|
|
4
|
-
const chalk = require(
|
|
5
|
-
const ora = require(
|
|
6
|
-
const { generateTemplate, getAvailableTemplates } = require(
|
|
1
|
+
const fs = require("fs-extra");
|
|
2
|
+
const path = require("path");
|
|
3
|
+
const inquirer = require("inquirer");
|
|
4
|
+
const chalk = require("chalk");
|
|
5
|
+
const ora = require("ora");
|
|
6
|
+
const { generateTemplate, getAvailableTemplates } = require("./templates");
|
|
7
|
+
|
|
8
|
+
// 默认选择的模板
|
|
9
|
+
const BASE_TEMPLATE = "qiankun";
|
|
10
|
+
|
|
11
|
+
const templateChoices = [
|
|
12
|
+
{
|
|
13
|
+
name: `🏗️ qiankun + antd + umi - 微前端模板 ${chalk.cyan("(推荐)")}`,
|
|
14
|
+
value: "qiankun",
|
|
15
|
+
short: "qiankun",
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
name: `🎨 antd + umi - Ant Design Pro 模板`,
|
|
19
|
+
value: "antd",
|
|
20
|
+
short: "antd",
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
name: `📦 umi - 基础模板`,
|
|
24
|
+
value: "umi",
|
|
25
|
+
short: "umi",
|
|
26
|
+
},
|
|
27
|
+
];
|
|
7
28
|
|
|
8
29
|
async function createProject(projectName, options) {
|
|
9
|
-
const { template
|
|
10
|
-
|
|
30
|
+
const { template } = options;
|
|
31
|
+
|
|
11
32
|
console.log(`🚀 创建 Umi4 项目...`);
|
|
12
|
-
|
|
33
|
+
|
|
13
34
|
// 获取可用模板列表
|
|
14
35
|
const availableTemplates = await getAvailableTemplates();
|
|
15
|
-
|
|
16
|
-
// 如果指定的模板不存在,让用户选择
|
|
36
|
+
|
|
17
37
|
let selectedTemplate = template;
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
38
|
+
|
|
39
|
+
// 如果没有指定模板,或者指定的模板不存在,让用户选择
|
|
40
|
+
if (!template || !availableTemplates.includes(template)) {
|
|
41
|
+
if (template && !availableTemplates.includes(template)) {
|
|
42
|
+
console.log(chalk.yellow(`⚠️ 模板 "${template}" 不存在`));
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
console.log(chalk.blue(`📋 请选择项目模板:`));
|
|
46
|
+
|
|
22
47
|
const { chosenTemplate } = await inquirer.prompt([
|
|
23
48
|
{
|
|
24
|
-
type:
|
|
25
|
-
name:
|
|
26
|
-
message:
|
|
27
|
-
choices:
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
value: t
|
|
31
|
-
}))
|
|
32
|
-
}
|
|
49
|
+
type: "list",
|
|
50
|
+
name: "chosenTemplate",
|
|
51
|
+
message: "选择项目模板:",
|
|
52
|
+
choices: templateChoices,
|
|
53
|
+
default: BASE_TEMPLATE, // 默认选择antd
|
|
54
|
+
},
|
|
33
55
|
]);
|
|
34
56
|
selectedTemplate = chosenTemplate;
|
|
35
57
|
}
|
|
36
|
-
|
|
58
|
+
|
|
59
|
+
console.log(chalk.cyan(`📋 使用模板: ${selectedTemplate}`));
|
|
60
|
+
|
|
37
61
|
const targetDir = path.resolve(projectName);
|
|
38
|
-
|
|
62
|
+
|
|
39
63
|
// 检查目录是否已存在
|
|
40
64
|
if (await fs.pathExists(targetDir)) {
|
|
41
65
|
const { overwrite } = await inquirer.prompt([
|
|
42
66
|
{
|
|
43
|
-
type:
|
|
44
|
-
name:
|
|
67
|
+
type: "confirm",
|
|
68
|
+
name: "overwrite",
|
|
45
69
|
message: `目录 ${projectName} 已存在,是否覆盖?`,
|
|
46
|
-
default: false
|
|
47
|
-
}
|
|
70
|
+
default: false,
|
|
71
|
+
},
|
|
48
72
|
]);
|
|
49
|
-
|
|
73
|
+
|
|
50
74
|
if (!overwrite) {
|
|
51
|
-
console.log(chalk.red(
|
|
75
|
+
console.log(chalk.red("❌ 项目创建取消"));
|
|
52
76
|
return;
|
|
53
77
|
}
|
|
54
|
-
|
|
78
|
+
|
|
55
79
|
await fs.remove(targetDir);
|
|
56
80
|
}
|
|
57
|
-
|
|
58
|
-
const spinner = ora(
|
|
59
|
-
|
|
81
|
+
|
|
82
|
+
const spinner = ora("正在创建项目...").start();
|
|
83
|
+
|
|
60
84
|
try {
|
|
61
85
|
// 生成项目文件
|
|
62
86
|
await generateTemplate(projectName, selectedTemplate, targetDir);
|
|
63
|
-
|
|
64
|
-
spinner.succeed(
|
|
65
|
-
|
|
66
|
-
console.log(chalk.green(
|
|
67
|
-
console.log(
|
|
87
|
+
|
|
88
|
+
spinner.succeed("项目文件生成完成");
|
|
89
|
+
|
|
90
|
+
console.log(chalk.green("✅ 项目创建成功!"));
|
|
91
|
+
console.log("");
|
|
68
92
|
console.log(chalk.cyan(`📁 进入项目目录: cd ${projectName}`));
|
|
69
|
-
console.log(chalk.cyan(
|
|
70
|
-
console.log(chalk.cyan(
|
|
71
|
-
|
|
93
|
+
console.log(chalk.cyan("📦 安装依赖: npm install 或 yarn"));
|
|
94
|
+
console.log(chalk.cyan("🚀 启动项目: npm start 或 yarn start"));
|
|
72
95
|
} catch (error) {
|
|
73
|
-
spinner.fail(
|
|
96
|
+
spinner.fail("项目创建失败");
|
|
74
97
|
console.error(chalk.red(error.message));
|
|
75
98
|
process.exit(1);
|
|
76
99
|
}
|
|
77
100
|
}
|
|
78
101
|
|
|
79
102
|
async function initProject(options) {
|
|
80
|
-
const { template
|
|
103
|
+
const { template } = options;
|
|
81
104
|
const projectName = path.basename(process.cwd());
|
|
82
|
-
|
|
105
|
+
|
|
83
106
|
console.log(`🚀 初始化 Umi4 项目...`);
|
|
84
|
-
|
|
107
|
+
|
|
85
108
|
// 获取可用模板列表
|
|
86
109
|
const availableTemplates = await getAvailableTemplates();
|
|
87
|
-
|
|
88
|
-
// 如果指定的模板不存在,让用户选择
|
|
110
|
+
|
|
89
111
|
let selectedTemplate = template;
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
112
|
+
|
|
113
|
+
// 如果没有指定模板,或者指定的模板不存在,让用户选择
|
|
114
|
+
if (!template || !availableTemplates.includes(template)) {
|
|
115
|
+
if (template && !availableTemplates.includes(template)) {
|
|
116
|
+
console.log(chalk.yellow(`⚠️ 模板 "${template}" 不存在`));
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
console.log(chalk.blue(`📋 请选择项目模板:`));
|
|
120
|
+
|
|
94
121
|
const { chosenTemplate } = await inquirer.prompt([
|
|
95
122
|
{
|
|
96
|
-
type:
|
|
97
|
-
name:
|
|
98
|
-
message:
|
|
99
|
-
choices:
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
value: t
|
|
103
|
-
}))
|
|
104
|
-
}
|
|
123
|
+
type: "list",
|
|
124
|
+
name: "chosenTemplate",
|
|
125
|
+
message: "选择项目模板:",
|
|
126
|
+
choices: templateChoices,
|
|
127
|
+
default: BASE_TEMPLATE, // 默认选择antd
|
|
128
|
+
},
|
|
105
129
|
]);
|
|
106
130
|
selectedTemplate = chosenTemplate;
|
|
107
131
|
}
|
|
108
|
-
|
|
132
|
+
|
|
133
|
+
console.log(chalk.cyan(`📋 使用模板: ${selectedTemplate}`));
|
|
134
|
+
|
|
109
135
|
const targetDir = process.cwd();
|
|
110
|
-
|
|
136
|
+
|
|
111
137
|
// 检查当前目录是否为空
|
|
112
138
|
const files = await fs.readdir(targetDir);
|
|
113
139
|
if (files.length > 0) {
|
|
114
140
|
const { proceed } = await inquirer.prompt([
|
|
115
141
|
{
|
|
116
|
-
type:
|
|
117
|
-
name:
|
|
118
|
-
message:
|
|
119
|
-
default: false
|
|
120
|
-
}
|
|
142
|
+
type: "confirm",
|
|
143
|
+
name: "proceed",
|
|
144
|
+
message: "当前目录不为空,是否继续?",
|
|
145
|
+
default: false,
|
|
146
|
+
},
|
|
121
147
|
]);
|
|
122
|
-
|
|
148
|
+
|
|
123
149
|
if (!proceed) {
|
|
124
|
-
console.log(chalk.red(
|
|
150
|
+
console.log(chalk.red("❌ 项目初始化取消"));
|
|
125
151
|
return;
|
|
126
152
|
}
|
|
127
153
|
}
|
|
128
|
-
|
|
129
|
-
const spinner = ora(
|
|
130
|
-
|
|
154
|
+
|
|
155
|
+
const spinner = ora("正在初始化项目...").start();
|
|
156
|
+
|
|
131
157
|
try {
|
|
132
158
|
// 生成项目文件
|
|
133
159
|
await generateTemplate(projectName, selectedTemplate, targetDir);
|
|
134
|
-
|
|
135
|
-
spinner.succeed(
|
|
136
|
-
|
|
137
|
-
console.log(chalk.green(
|
|
138
|
-
console.log(
|
|
139
|
-
console.log(chalk.cyan(
|
|
140
|
-
console.log(chalk.cyan(
|
|
141
|
-
|
|
160
|
+
|
|
161
|
+
spinner.succeed("项目文件生成完成");
|
|
162
|
+
|
|
163
|
+
console.log(chalk.green("✅ 项目初始化成功!"));
|
|
164
|
+
console.log("");
|
|
165
|
+
console.log(chalk.cyan("📦 安装依赖: npm install 或 yarn"));
|
|
166
|
+
console.log(chalk.cyan("🚀 启动项目: npm start 或 yarn start"));
|
|
142
167
|
} catch (error) {
|
|
143
|
-
spinner.fail(
|
|
168
|
+
spinner.fail("项目初始化失败");
|
|
144
169
|
console.error(chalk.red(error.message));
|
|
145
170
|
process.exit(1);
|
|
146
171
|
}
|
|
@@ -148,5 +173,5 @@ async function initProject(options) {
|
|
|
148
173
|
|
|
149
174
|
module.exports = {
|
|
150
175
|
createProject,
|
|
151
|
-
initProject
|
|
152
|
-
};
|
|
176
|
+
initProject,
|
|
177
|
+
};
|
|
@@ -28,7 +28,7 @@ const HomePage: React.FC = () => {
|
|
|
28
28
|
<a href="https://umijs.org/" target="_blank" rel="noopener noreferrer">
|
|
29
29
|
查看 Umi 文档
|
|
30
30
|
</a>
|
|
31
|
-
<a href="https://github.com/
|
|
31
|
+
<a href="https://github.com/Ivan-YangSj/umi-cli" target="_blank" rel="noopener noreferrer">
|
|
32
32
|
GitHub 仓库
|
|
33
33
|
</a>
|
|
34
34
|
</div>
|
package/lib/templates/index.js
CHANGED
|
@@ -1,51 +1,81 @@
|
|
|
1
1
|
const fs = require('fs-extra');
|
|
2
2
|
const path = require('path');
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
/**
|
|
5
|
+
* 模板变量替换函数
|
|
6
|
+
* 将模板文件中的占位符(如{{projectName}})替换为实际的值
|
|
7
|
+
* @param {string} content - 文件内容
|
|
8
|
+
* @param {object} variables - 变量对象,包含要替换的键值对
|
|
9
|
+
* @returns {string} 替换后的内容
|
|
10
|
+
*/
|
|
5
11
|
function replaceTemplateVariables(content, variables) {
|
|
6
12
|
let result = content;
|
|
13
|
+
// 遍历所有变量,逐一替换
|
|
7
14
|
for (const [key, value] of Object.entries(variables)) {
|
|
15
|
+
// 创建占位符格式:{{变量名}}
|
|
8
16
|
const placeholder = `{{${key}}}`;
|
|
17
|
+
// 全局替换所有匹配的占位符
|
|
9
18
|
result = result.replace(new RegExp(placeholder, 'g'), value || '');
|
|
10
19
|
}
|
|
11
20
|
return result;
|
|
12
21
|
}
|
|
13
22
|
|
|
14
|
-
|
|
23
|
+
/**
|
|
24
|
+
* 递归复制目录并替换模板变量
|
|
25
|
+
* 这是核心函数,负责将模板目录完整复制到目标位置,并处理模板变量
|
|
26
|
+
* @param {string} srcDir - 源目录路径(模板目录)
|
|
27
|
+
* @param {string} destDir - 目标目录路径(项目生成位置)
|
|
28
|
+
* @param {object} variables - 模板变量对象
|
|
29
|
+
*/
|
|
15
30
|
async function copyTemplateDir(srcDir, destDir, variables) {
|
|
31
|
+
// 确保目标目录存在,如果不存在则创建
|
|
16
32
|
await fs.ensureDir(destDir);
|
|
17
33
|
|
|
34
|
+
// 读取源目录下的所有文件和文件夹
|
|
18
35
|
const items = await fs.readdir(srcDir);
|
|
19
36
|
|
|
37
|
+
// 遍历每个项目(文件或文件夹)
|
|
20
38
|
for (const item of items) {
|
|
21
|
-
const srcPath = path.join(srcDir, item);
|
|
22
|
-
const destPath = path.join(destDir, item);
|
|
39
|
+
const srcPath = path.join(srcDir, item); // 源文件/文件夹的完整路径
|
|
40
|
+
const destPath = path.join(destDir, item); // 目标文件/文件夹的完整路径
|
|
23
41
|
|
|
42
|
+
// 获取文件/文件夹的统计信息
|
|
24
43
|
const stat = await fs.stat(srcPath);
|
|
25
44
|
|
|
26
45
|
if (stat.isDirectory()) {
|
|
27
|
-
//
|
|
46
|
+
// 如果是目录,递归调用自己,复制整个子目录
|
|
28
47
|
await copyTemplateDir(srcPath, destPath, variables);
|
|
29
48
|
} else {
|
|
30
|
-
//
|
|
49
|
+
// 如果是文件,读取文件内容并处理模板变量
|
|
31
50
|
const content = await fs.readFile(srcPath, 'utf8');
|
|
51
|
+
// 替换文件中的模板变量(如{{projectName}})
|
|
32
52
|
const processedContent = replaceTemplateVariables(content, variables);
|
|
53
|
+
// 将处理后的内容写入目标文件
|
|
33
54
|
await fs.writeFile(destPath, processedContent);
|
|
34
55
|
}
|
|
35
56
|
}
|
|
36
57
|
}
|
|
37
58
|
|
|
59
|
+
/**
|
|
60
|
+
* 生成模板项目的主函数
|
|
61
|
+
* @param {string} projectName - 项目名称
|
|
62
|
+
* @param {string} templateType - 模板类型(如react、vue等)
|
|
63
|
+
* @param {string} targetDir - 目标生成目录
|
|
64
|
+
*/
|
|
38
65
|
async function generateTemplate(projectName, templateType, targetDir) {
|
|
66
|
+
// 获取模板根目录路径
|
|
39
67
|
const templatesDir = path.join(__dirname, './');
|
|
68
|
+
// 构建特定模板目录路径
|
|
40
69
|
const templateDir = path.join(templatesDir, templateType);
|
|
70
|
+
// 构建通用文件目录路径
|
|
41
71
|
const commonDir = path.join(templatesDir, 'common');
|
|
42
72
|
|
|
43
|
-
//
|
|
73
|
+
// 检查指定的模板是否存在
|
|
44
74
|
if (!await fs.pathExists(templateDir)) {
|
|
45
75
|
throw new Error(`模板 "${templateType}" 不存在`);
|
|
46
76
|
}
|
|
47
77
|
|
|
48
|
-
//
|
|
78
|
+
// 定义模板变量,这些变量会在模板文件中被替换
|
|
49
79
|
const variables = {
|
|
50
80
|
projectName: projectName || 'my-umi-app'
|
|
51
81
|
};
|
|
@@ -53,17 +83,25 @@ async function generateTemplate(projectName, templateType, targetDir) {
|
|
|
53
83
|
// 确保目标目录存在
|
|
54
84
|
await fs.ensureDir(targetDir);
|
|
55
85
|
|
|
56
|
-
//
|
|
57
|
-
|
|
86
|
+
// 创建项目的基础目录结构
|
|
87
|
+
// 这些是前端项目常用的目录结构
|
|
88
|
+
const baseDirs = [
|
|
89
|
+
'src/pages', // 页面组件目录
|
|
90
|
+
'src/components', // 公共组件目录
|
|
91
|
+
'src/services', // API服务目录
|
|
92
|
+
'src/utils' // 工具函数目录
|
|
93
|
+
];
|
|
94
|
+
|
|
95
|
+
// 遍历并创建所有基础目录
|
|
58
96
|
for (const dir of baseDirs) {
|
|
59
97
|
await fs.ensureDir(path.join(targetDir, dir));
|
|
60
98
|
}
|
|
61
99
|
|
|
62
|
-
//
|
|
100
|
+
// 复制模板特定的文件(如React模板、Vue模板等)
|
|
63
101
|
console.log(`📂 正在复制模板文件...`);
|
|
64
102
|
await copyTemplateDir(templateDir, targetDir, variables);
|
|
65
103
|
|
|
66
|
-
//
|
|
104
|
+
// 复制通用文件(如配置文件、README等,所有模板都需要的文件)
|
|
67
105
|
if (await fs.pathExists(commonDir)) {
|
|
68
106
|
console.log(`📄 正在复制通用配置文件...`);
|
|
69
107
|
await copyTemplateDir(commonDir, targetDir, variables);
|
|
@@ -72,14 +110,20 @@ async function generateTemplate(projectName, templateType, targetDir) {
|
|
|
72
110
|
console.log(`✅ 模板文件复制完成`);
|
|
73
111
|
}
|
|
74
112
|
|
|
75
|
-
|
|
113
|
+
/**
|
|
114
|
+
* 获取所有可用的模板列表
|
|
115
|
+
* 扫描模板目录,返回所有可用的模板类型
|
|
116
|
+
* @returns {Array<string>} 可用模板列表
|
|
117
|
+
*/
|
|
76
118
|
async function getAvailableTemplates() {
|
|
77
119
|
const templatesDir = path.join(__dirname, './');
|
|
78
120
|
|
|
121
|
+
// 如果模板目录不存在,返回空数组
|
|
79
122
|
if (!await fs.pathExists(templatesDir)) {
|
|
80
123
|
return [];
|
|
81
124
|
}
|
|
82
125
|
|
|
126
|
+
// 读取模板目录下的所有项目
|
|
83
127
|
const items = await fs.readdir(templatesDir);
|
|
84
128
|
const templates = [];
|
|
85
129
|
|
|
@@ -87,7 +131,8 @@ async function getAvailableTemplates() {
|
|
|
87
131
|
const itemPath = path.join(templatesDir, item);
|
|
88
132
|
const stat = await fs.stat(itemPath);
|
|
89
133
|
|
|
90
|
-
//
|
|
134
|
+
// 只返回目录类型的模板,排除common目录和index.js文件
|
|
135
|
+
// common目录是通用文件目录,不是模板类型
|
|
91
136
|
if (stat.isDirectory() && item !== 'common') {
|
|
92
137
|
templates.push(item);
|
|
93
138
|
}
|
|
@@ -96,7 +141,8 @@ async function getAvailableTemplates() {
|
|
|
96
141
|
return templates;
|
|
97
142
|
}
|
|
98
143
|
|
|
144
|
+
// 导出主要功能函数
|
|
99
145
|
module.exports = {
|
|
100
|
-
generateTemplate,
|
|
101
|
-
getAvailableTemplates
|
|
146
|
+
generateTemplate, // 生成模板项目
|
|
147
|
+
getAvailableTemplates // 获取可用模板列表
|
|
102
148
|
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ysjdemo/umi-create-cli",
|
|
3
3
|
"author": "ysj <411367308@qq.com>",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.3",
|
|
5
5
|
"description": "一个用于创建Umi4项目的脚手架工具",
|
|
6
6
|
"main": "index.js",
|
|
7
7
|
"bin": {
|
|
@@ -11,7 +11,6 @@
|
|
|
11
11
|
"start": "node bin/cli.js",
|
|
12
12
|
"test": "echo \"Error: no test specified\" && exit 1",
|
|
13
13
|
"prepublishOnly": "echo 'Preparing to publish...'",
|
|
14
|
-
"publish:auto": "node scripts/publish.js",
|
|
15
14
|
"version:patch": "npm version patch",
|
|
16
15
|
"version:minor": "npm version minor",
|
|
17
16
|
"version:major": "npm version major"
|