@ysjdemo/umi-create-cli 0.0.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/README.md ADDED
@@ -0,0 +1,117 @@
1
+ # @cfmm/umi-create-cli
2
+
3
+ 一个用于快速创建 Umi 4 项目的脚手架工具。
4
+
5
+ ## ✨ 特性
6
+
7
+ - 🚀 快速创建 Umi 4 项目
8
+ - 🎨 提供多种项目模板
9
+ - 📦 自动配置常用依赖和配置
10
+ - 💻 支持 TypeScript
11
+ - 🔧 预配置 ESLint 和 Prettier
12
+
13
+ ## 📦 安装
14
+
15
+ ### 全局安装
16
+ ```bash
17
+ npm install -g @cfmm/umi-create-cli
18
+ ```
19
+
20
+ ### 或使用 npx(推荐)
21
+ ```bash
22
+ npx @cfmm/umi-create-cli create my-project
23
+ ```
24
+
25
+ ## 🚀 使用
26
+
27
+ ### 创建新项目
28
+ ```bash
29
+ # 使用默认模板(basic)
30
+ ysj-umi create my-project
31
+
32
+ # 指定模板类型
33
+ ysj-umi create my-project -t antd
34
+ ```
35
+
36
+ ### 在当前目录初始化
37
+ ```bash
38
+ # 在当前目录初始化项目
39
+ ysj-umi init
40
+
41
+ # 指定模板类型
42
+ ysj-umi init -t antd
43
+ ```
44
+
45
+ ### 查看帮助
46
+ ```bash
47
+ ysj-umi --help
48
+ ```
49
+
50
+ ## 📋 可用模板
51
+
52
+ ### 1. basic - 基础模板
53
+ - ✅ Umi 4 基础配置
54
+ - ✅ React 18 + TypeScript
55
+ - ✅ 基础路由配置
56
+ - ✅ 简单的页面示例
57
+
58
+ ### 2. antd - Ant Design Pro 模板
59
+ - ✅ 基于 Ant Design 5.0
60
+ - ✅ Pro Components 组件库
61
+ - ✅ 完整的后台管理界面
62
+ - ✅ 仪表盘、用户管理、设置页面
63
+ - ✅ 表格、表单等常用功能
64
+
65
+ ## 📁 项目结构
66
+
67
+ 创建的项目具有以下目录结构:
68
+
69
+ ```
70
+ my-project/
71
+ ├── src/
72
+ │ ├── components/ # 通用组件
73
+ │ ├── pages/ # 页面组件
74
+ │ ├── services/ # API 服务
75
+ │ └── utils/ # 工具函数
76
+ ├── .umirc.ts # Umi 配置文件
77
+ ├── .gitignore # Git 忽略文件
78
+ ├── .prettierrc # Prettier 配置
79
+ ├── tsconfig.json # TypeScript 配置
80
+ ├── package.json # 项目依赖
81
+ └── README.md # 项目说明
82
+ ```
83
+
84
+ ## 🛠️ 开发流程
85
+
86
+ 创建项目后,进入项目目录并安装依赖:
87
+
88
+ ```bash
89
+ cd my-project
90
+ npm install
91
+ ```
92
+
93
+ 启动开发服务器:
94
+
95
+ ```bash
96
+ npm start
97
+ ```
98
+
99
+ 构建生产版本:
100
+
101
+ ```bash
102
+ npm run build
103
+ ```
104
+
105
+ ## 📖 相关文档
106
+
107
+ - [Umi 4 官方文档](https://umijs.org/)
108
+ - [Ant Design 文档](https://ant.design/)
109
+ - [Pro Components 文档](https://procomponents.ant.design/)
110
+
111
+ ## 🤝 贡献
112
+
113
+ 欢迎提交 Issue 和 Pull Request!
114
+
115
+ ## 📄 许可证
116
+
117
+ [MIT](LICENSE)
package/bin/cli.js ADDED
@@ -0,0 +1,39 @@
1
+ #!/usr/bin/env node
2
+
3
+ const { program } = require('commander');
4
+ const { createProject, initProject } = require('../lib/create');
5
+
6
+ program
7
+ .name('ysj-umi')
8
+ .description('Umi4 项目脚手架工具')
9
+ .version(require('../package.json').version);
10
+
11
+ // create 命令
12
+ program
13
+ .command('create <project-name>')
14
+ .description('创建一个新的 Umi4 项目')
15
+ .option('-t, --template <template>', '使用指定模板 (basic, antd)', 'basic')
16
+ .action(async (projectName, options) => {
17
+ try {
18
+ await createProject(projectName, options);
19
+ } catch (error) {
20
+ console.error('创建项目失败:', error.message);
21
+ process.exit(1);
22
+ }
23
+ });
24
+
25
+ // init 命令
26
+ program
27
+ .command('init')
28
+ .description('在当前目录初始化 Umi4 项目')
29
+ .option('-t, --template <template>', '使用指定模板 (basic, antd)', 'basic')
30
+ .action(async (options) => {
31
+ try {
32
+ await initProject(options);
33
+ } catch (error) {
34
+ console.error('初始化项目失败:', error.message);
35
+ process.exit(1);
36
+ }
37
+ });
38
+
39
+ program.parse();
package/lib/create.js ADDED
@@ -0,0 +1,152 @@
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
+ async function createProject(projectName, options) {
9
+ const { template = 'basic' } = options;
10
+
11
+ console.log(`🚀 创建 Umi4 项目...`);
12
+
13
+ // 获取可用模板列表
14
+ const availableTemplates = await getAvailableTemplates();
15
+
16
+ // 如果指定的模板不存在,让用户选择
17
+ let selectedTemplate = template;
18
+ if (!availableTemplates.includes(template)) {
19
+ console.log(chalk.yellow(`⚠️ 模板 "${template}" 不存在`));
20
+ console.log(chalk.blue(`📋 可用模板: ${availableTemplates.join(', ')}`));
21
+
22
+ const { chosenTemplate } = await inquirer.prompt([
23
+ {
24
+ type: 'list',
25
+ name: 'chosenTemplate',
26
+ message: '请选择要使用的模板:',
27
+ choices: availableTemplates.map(t => ({
28
+ name: t === 'basic' ? `${t} (基础模板)` :
29
+ t === 'antd' ? `${t} (Ant Design Pro)` : t,
30
+ value: t
31
+ }))
32
+ }
33
+ ]);
34
+ selectedTemplate = chosenTemplate;
35
+ }
36
+
37
+ const targetDir = path.resolve(projectName);
38
+
39
+ // 检查目录是否已存在
40
+ if (await fs.pathExists(targetDir)) {
41
+ const { overwrite } = await inquirer.prompt([
42
+ {
43
+ type: 'confirm',
44
+ name: 'overwrite',
45
+ message: `目录 ${projectName} 已存在,是否覆盖?`,
46
+ default: false
47
+ }
48
+ ]);
49
+
50
+ if (!overwrite) {
51
+ console.log(chalk.red('❌ 项目创建取消'));
52
+ return;
53
+ }
54
+
55
+ await fs.remove(targetDir);
56
+ }
57
+
58
+ const spinner = ora('正在创建项目...').start();
59
+
60
+ try {
61
+ // 生成项目文件
62
+ await generateTemplate(projectName, selectedTemplate, targetDir);
63
+
64
+ spinner.succeed('项目文件生成完成');
65
+
66
+ console.log(chalk.green('✅ 项目创建成功!'));
67
+ console.log('');
68
+ console.log(chalk.cyan(`📁 进入项目目录: cd ${projectName}`));
69
+ console.log(chalk.cyan('📦 安装依赖: npm install 或 yarn'));
70
+ console.log(chalk.cyan('🚀 启动项目: npm start 或 yarn start'));
71
+
72
+ } catch (error) {
73
+ spinner.fail('项目创建失败');
74
+ console.error(chalk.red(error.message));
75
+ process.exit(1);
76
+ }
77
+ }
78
+
79
+ async function initProject(options) {
80
+ const { template = 'basic' } = options;
81
+ const projectName = path.basename(process.cwd());
82
+
83
+ console.log(`🚀 初始化 Umi4 项目...`);
84
+
85
+ // 获取可用模板列表
86
+ const availableTemplates = await getAvailableTemplates();
87
+
88
+ // 如果指定的模板不存在,让用户选择
89
+ let selectedTemplate = template;
90
+ if (!availableTemplates.includes(template)) {
91
+ console.log(chalk.yellow(`⚠️ 模板 "${template}" 不存在`));
92
+ console.log(chalk.blue(`📋 可用模板: ${availableTemplates.join(', ')}`));
93
+
94
+ const { chosenTemplate } = await inquirer.prompt([
95
+ {
96
+ type: 'list',
97
+ name: 'chosenTemplate',
98
+ message: '请选择要使用的模板:',
99
+ choices: availableTemplates.map(t => ({
100
+ name: t === 'basic' ? `${t} (基础模板)` :
101
+ t === 'antd' ? `${t} (Ant Design Pro)` : t,
102
+ value: t
103
+ }))
104
+ }
105
+ ]);
106
+ selectedTemplate = chosenTemplate;
107
+ }
108
+
109
+ const targetDir = process.cwd();
110
+
111
+ // 检查当前目录是否为空
112
+ const files = await fs.readdir(targetDir);
113
+ if (files.length > 0) {
114
+ const { proceed } = await inquirer.prompt([
115
+ {
116
+ type: 'confirm',
117
+ name: 'proceed',
118
+ message: '当前目录不为空,是否继续?',
119
+ default: false
120
+ }
121
+ ]);
122
+
123
+ if (!proceed) {
124
+ console.log(chalk.red('❌ 项目初始化取消'));
125
+ return;
126
+ }
127
+ }
128
+
129
+ const spinner = ora('正在初始化项目...').start();
130
+
131
+ try {
132
+ // 生成项目文件
133
+ await generateTemplate(projectName, selectedTemplate, targetDir);
134
+
135
+ spinner.succeed('项目文件生成完成');
136
+
137
+ console.log(chalk.green('✅ 项目初始化成功!'));
138
+ console.log('');
139
+ console.log(chalk.cyan('📦 安装依赖: npm install 或 yarn'));
140
+ console.log(chalk.cyan('🚀 启动项目: npm start 或 yarn start'));
141
+
142
+ } catch (error) {
143
+ spinner.fail('项目初始化失败');
144
+ console.error(chalk.red(error.message));
145
+ process.exit(1);
146
+ }
147
+ }
148
+
149
+ module.exports = {
150
+ createProject,
151
+ initProject
152
+ };
@@ -0,0 +1,38 @@
1
+ import { defineConfig } from '@umijs/max';
2
+
3
+ export default defineConfig({
4
+ antd: {},
5
+ access: {},
6
+ model: {},
7
+ initialState: {},
8
+ request: {},
9
+ layout: {
10
+ title: '{{projectName}}',
11
+ logo: 'https://img.alicdn.com/tfs/TB1YHEpwUT1gK0jSZFhXXaAtVXa-28-27.svg',
12
+ },
13
+ routes: [
14
+ {
15
+ path: '/',
16
+ redirect: '/dashboard',
17
+ },
18
+ {
19
+ name: '仪表盘',
20
+ path: '/dashboard',
21
+ component: './Dashboard',
22
+ icon: 'DashboardOutlined',
23
+ },
24
+ {
25
+ name: '用户管理',
26
+ path: '/users',
27
+ component: './Users',
28
+ icon: 'UserOutlined',
29
+ },
30
+ {
31
+ name: '设置',
32
+ path: '/settings',
33
+ component: './Settings',
34
+ icon: 'SettingOutlined',
35
+ },
36
+ ],
37
+ npmClient: 'npm',
38
+ });
@@ -0,0 +1,65 @@
1
+ # {{projectName}}
2
+
3
+ 这是一个使用 cfmm-cli-umi 脚手架创建的 Umi 4 + Ant Design Pro 项目。
4
+
5
+ ## 特性
6
+
7
+ - 🚀 基于 Umi 4 和 Ant Design 5
8
+ - 📦 开箱即用的 Pro Components
9
+ - 🎨 美观的管理后台界面
10
+ - 📱 响应式设计
11
+ - 🔐 内置权限管理
12
+ - 📈 丰富的图表组件
13
+
14
+ ## 开始使用
15
+
16
+ ### 安装依赖
17
+
18
+ ```bash
19
+ npm install
20
+ # 或
21
+ yarn
22
+ ```
23
+
24
+ ### 启动开发服务器
25
+
26
+ ```bash
27
+ npm start
28
+ # 或
29
+ yarn start
30
+ ```
31
+
32
+ ### 构建生产版本
33
+
34
+ ```bash
35
+ npm run build
36
+ # 或
37
+ yarn build
38
+ ```
39
+
40
+ ## 项目结构
41
+
42
+ ```
43
+ ├── src/
44
+ │ ├── components/ # 通用组件
45
+ │ ├── pages/ # 页面组件
46
+ │ │ ├── Dashboard/ # 仪表盘
47
+ │ │ ├── Users/ # 用户管理
48
+ │ │ └── Settings/ # 系统设置
49
+ │ ├── services/ # API 服务
50
+ │ └── utils/ # 工具函数
51
+ ├── .umirc.ts # Umi 配置文件
52
+ └── package.json
53
+ ```
54
+
55
+ ## 页面说明
56
+
57
+ - **仪表盘**: 数据统计展示
58
+ - **用户管理**: 用户列表和管理
59
+ - **系统设置**: 应用配置管理
60
+
61
+ ## 更多信息
62
+
63
+ - [Umi 4 文档](https://umijs.org/)
64
+ - [Ant Design 文档](https://ant.design/)
65
+ - [Pro Components 文档](https://procomponents.ant.design/)
@@ -0,0 +1,27 @@
1
+ {
2
+ "name": "{{projectName}}",
3
+ "private": true,
4
+ "author": "cfmm-cli-umi",
5
+ "scripts": {
6
+ "build": "umi build",
7
+ "dev": "umi dev",
8
+ "format": "prettier --cache --write .",
9
+ "postinstall": "umi setup",
10
+ "setup": "umi setup",
11
+ "start": "npm run dev"
12
+ },
13
+ "dependencies": {
14
+ "@umijs/max": "^4.0.0",
15
+ "@ant-design/pro-components": "^2.6.0",
16
+ "@ant-design/icons": "^5.0.0",
17
+ "antd": "^5.0.0",
18
+ "react": "^18.2.0",
19
+ "react-dom": "^18.2.0"
20
+ },
21
+ "devDependencies": {
22
+ "@types/react": "^18.0.0",
23
+ "@types/react-dom": "^18.0.0",
24
+ "prettier": "^2.7.1",
25
+ "typescript": "^5.0.0"
26
+ }
27
+ }
@@ -0,0 +1,58 @@
1
+ import { Card, Col, Row, Statistic } from 'antd';
2
+ import { ArrowDownOutlined, ArrowUpOutlined } from '@ant-design/icons';
3
+ import { PageContainer } from '@ant-design/pro-components';
4
+ import React from 'react';
5
+
6
+ const DashboardPage: React.FC = () => {
7
+ return (
8
+ <PageContainer>
9
+ <Row gutter={16}>
10
+ <Col span={6}>
11
+ <Card>
12
+ <Statistic
13
+ title="用户总数"
14
+ value={1128}
15
+ precision={0}
16
+ valueStyle={{ color: '#3f8600' }}
17
+ prefix={<ArrowUpOutlined />}
18
+ />
19
+ </Card>
20
+ </Col>
21
+ <Col span={6}>
22
+ <Card>
23
+ <Statistic
24
+ title="订单数量"
25
+ value={893}
26
+ precision={0}
27
+ valueStyle={{ color: '#cf1322' }}
28
+ prefix={<ArrowDownOutlined />}
29
+ />
30
+ </Card>
31
+ </Col>
32
+ <Col span={6}>
33
+ <Card>
34
+ <Statistic
35
+ title="销售额"
36
+ value={25863}
37
+ precision={2}
38
+ prefix="¥"
39
+ valueStyle={{ color: '#3f8600' }}
40
+ />
41
+ </Card>
42
+ </Col>
43
+ <Col span={6}>
44
+ <Card>
45
+ <Statistic
46
+ title="活跃用户"
47
+ value={523}
48
+ precision={0}
49
+ valueStyle={{ color: '#1890ff' }}
50
+ />
51
+ </Card>
52
+ </Col>
53
+ </Row>
54
+ </PageContainer>
55
+ );
56
+ };
57
+
58
+ export default DashboardPage;
@@ -0,0 +1,73 @@
1
+ import { PageContainer } from '@ant-design/pro-components';
2
+ import { Card, Form, Input, Button, Switch, Space, message } from 'antd';
3
+ import React from 'react';
4
+
5
+ const SettingsPage: React.FC = () => {
6
+ const [form] = Form.useForm();
7
+
8
+ const onFinish = (values: any) => {
9
+ console.log('设置保存:', values);
10
+ message.success('设置保存成功!');
11
+ };
12
+
13
+ return (
14
+ <PageContainer>
15
+ <Card title="系统设置">
16
+ <Form
17
+ form={form}
18
+ layout="vertical"
19
+ onFinish={onFinish}
20
+ initialValues={{
21
+ siteName: '{{projectName}}',
22
+ emailNotification: true,
23
+ pushNotification: false,
24
+ }}
25
+ >
26
+ <Form.Item
27
+ label="站点名称"
28
+ name="siteName"
29
+ rules={[{ required: true, message: '请输入站点名称' }]}
30
+ >
31
+ <Input placeholder="请输入站点名称" />
32
+ </Form.Item>
33
+
34
+ <Form.Item
35
+ label="站点描述"
36
+ name="description"
37
+ >
38
+ <Input.TextArea rows={4} placeholder="请输入站点描述" />
39
+ </Form.Item>
40
+
41
+ <Form.Item
42
+ label="邮件通知"
43
+ name="emailNotification"
44
+ valuePropName="checked"
45
+ >
46
+ <Switch />
47
+ </Form.Item>
48
+
49
+ <Form.Item
50
+ label="推送通知"
51
+ name="pushNotification"
52
+ valuePropName="checked"
53
+ >
54
+ <Switch />
55
+ </Form.Item>
56
+
57
+ <Form.Item>
58
+ <Space>
59
+ <Button type="primary" htmlType="submit">
60
+ 保存设置
61
+ </Button>
62
+ <Button onClick={() => form.resetFields()}>
63
+ 重置
64
+ </Button>
65
+ </Space>
66
+ </Form.Item>
67
+ </Form>
68
+ </Card>
69
+ </PageContainer>
70
+ );
71
+ };
72
+
73
+ export default SettingsPage;
@@ -0,0 +1,88 @@
1
+ import { PageContainer, ProTable } from '@ant-design/pro-components';
2
+ import { Button, Tag, Space } from 'antd';
3
+ import { PlusOutlined } from '@ant-design/icons';
4
+ import React from 'react';
5
+
6
+ const UsersPage: React.FC = () => {
7
+ const columns = [
8
+ {
9
+ title: 'ID',
10
+ dataIndex: 'id',
11
+ key: 'id',
12
+ width: 80,
13
+ },
14
+ {
15
+ title: '用户名',
16
+ dataIndex: 'name',
17
+ key: 'name',
18
+ },
19
+ {
20
+ title: '邮箱',
21
+ dataIndex: 'email',
22
+ key: 'email',
23
+ },
24
+ {
25
+ title: '状态',
26
+ dataIndex: 'status',
27
+ key: 'status',
28
+ render: (status: string) => (
29
+ <Tag color={status === 'active' ? 'green' : 'red'}>
30
+ {status === 'active' ? '活跃' : '禁用'}
31
+ </Tag>
32
+ ),
33
+ },
34
+ {
35
+ title: '操作',
36
+ key: 'action',
37
+ render: () => (
38
+ <Space size="middle">
39
+ <Button type="link" size="small">编辑</Button>
40
+ <Button type="link" size="small" danger>删除</Button>
41
+ </Space>
42
+ ),
43
+ },
44
+ ];
45
+
46
+ const mockData = [
47
+ {
48
+ id: 1,
49
+ name: '张三',
50
+ email: 'zhangsan@example.com',
51
+ status: 'active',
52
+ },
53
+ {
54
+ id: 2,
55
+ name: '李四',
56
+ email: 'lisi@example.com',
57
+ status: 'active',
58
+ },
59
+ {
60
+ id: 3,
61
+ name: '王五',
62
+ email: 'wangwu@example.com',
63
+ status: 'inactive',
64
+ },
65
+ ];
66
+
67
+ return (
68
+ <PageContainer>
69
+ <ProTable
70
+ columns={columns}
71
+ dataSource={mockData}
72
+ rowKey="id"
73
+ pagination={{
74
+ showSizeChanger: true,
75
+ showQuickJumper: true,
76
+ }}
77
+ toolBarRender={() => [
78
+ <Button key="button" icon={<PlusOutlined />} type="primary">
79
+ 新建用户
80
+ </Button>,
81
+ ]}
82
+ search={false}
83
+ />
84
+ </PageContainer>
85
+ );
86
+ };
87
+
88
+ export default UsersPage;
@@ -0,0 +1,29 @@
1
+ import { defineConfig } from '@umijs/max';
2
+
3
+ export default defineConfig({
4
+ antd: {},
5
+ access: {},
6
+ model: {},
7
+ initialState: {},
8
+ request: {},
9
+ layout: {
10
+ title: '{{projectName}}',
11
+ },
12
+ routes: [
13
+ {
14
+ path: '/',
15
+ redirect: '/home',
16
+ },
17
+ {
18
+ name: '首页',
19
+ path: '/home',
20
+ component: './Home',
21
+ },
22
+ {
23
+ name: '关于',
24
+ path: '/about',
25
+ component: './About',
26
+ },
27
+ ],
28
+ npmClient: 'npm',
29
+ });
@@ -0,0 +1,46 @@
1
+ # {{projectName}}
2
+
3
+ 这是一个使用 cfmm-cli-umi 脚手架创建的 Umi 4 项目。
4
+
5
+ ## 开始使用
6
+
7
+ ### 安装依赖
8
+
9
+ ```bash
10
+ npm install
11
+ # 或
12
+ yarn
13
+ ```
14
+
15
+ ### 启动开发服务器
16
+
17
+ ```bash
18
+ npm start
19
+ # 或
20
+ yarn start
21
+ ```
22
+
23
+ ### 构建生产版本
24
+
25
+ ```bash
26
+ npm run build
27
+ # 或
28
+ yarn build
29
+ ```
30
+
31
+ ## 项目结构
32
+
33
+ ```
34
+ ├── src/
35
+ │ ├── components/ # 通用组件
36
+ │ ├── pages/ # 页面组件
37
+ │ ├── services/ # API 服务
38
+ │ └── utils/ # 工具函数
39
+ ├── .umirc.ts # Umi 配置文件
40
+ └── package.json
41
+ ```
42
+
43
+ ## 更多信息
44
+
45
+ - [Umi 4 文档](https://umijs.org/)
46
+ - [Ant Design 文档](https://ant.design/)
@@ -0,0 +1,26 @@
1
+ {
2
+ "name": "{{projectName}}",
3
+ "private": true,
4
+ "author": "cfmm-cli-umi",
5
+ "scripts": {
6
+ "build": "umi build",
7
+ "dev": "umi dev",
8
+ "format": "prettier --cache --write .",
9
+ "postinstall": "umi setup",
10
+ "setup": "umi setup",
11
+ "start": "npm run dev"
12
+ },
13
+ "dependencies": {
14
+ "@umijs/max": "^4.0.0",
15
+ "@ant-design/pro-components": "^2.6.0",
16
+ "antd": "^5.0.0",
17
+ "react": "^18.2.0",
18
+ "react-dom": "^18.2.0"
19
+ },
20
+ "devDependencies": {
21
+ "@types/react": "^18.0.0",
22
+ "@types/react-dom": "^18.0.0",
23
+ "prettier": "^2.7.1",
24
+ "typescript": "^5.0.0"
25
+ }
26
+ }
@@ -0,0 +1,17 @@
1
+ import { Spin } from 'antd';
2
+ import React from 'react';
3
+
4
+ const Loading: React.FC = () => {
5
+ return (
6
+ <div style={{
7
+ display: 'flex',
8
+ justifyContent: 'center',
9
+ alignItems: 'center',
10
+ height: '200px'
11
+ }}>
12
+ <Spin size="large" />
13
+ </div>
14
+ );
15
+ };
16
+
17
+ export default Loading;
@@ -0,0 +1,23 @@
1
+ import { PageContainer } from '@ant-design/pro-components';
2
+ import { Card, Typography } from 'antd';
3
+ import React from 'react';
4
+
5
+ const { Title, Paragraph } = Typography;
6
+
7
+ const AboutPage: React.FC = () => {
8
+ return (
9
+ <PageContainer>
10
+ <Card>
11
+ <Title level={2}>关于我们</Title>
12
+ <Paragraph>
13
+ 这是关于页面的示例内容。
14
+ </Paragraph>
15
+ <Paragraph>
16
+ 你可以在这里添加你的项目介绍、团队信息等内容。
17
+ </Paragraph>
18
+ </Card>
19
+ </PageContainer>
20
+ );
21
+ };
22
+
23
+ export default AboutPage;
@@ -0,0 +1,23 @@
1
+ import { PageContainer } from '@ant-design/pro-components';
2
+ import { Card, Typography } from 'antd';
3
+ import React from 'react';
4
+
5
+ const { Title, Paragraph } = Typography;
6
+
7
+ const HomePage: React.FC = () => {
8
+ return (
9
+ <PageContainer>
10
+ <Card>
11
+ <Title level={2}>欢迎使用 Umi 4!</Title>
12
+ <Paragraph>
13
+ 这是一个使用 cfmm-cli-umi 脚手架创建的基础 Umi 4 项目。
14
+ </Paragraph>
15
+ <Paragraph>
16
+ 你可以开始编辑 <code>src/pages/Home/index.tsx</code> 来开发你的应用。
17
+ </Paragraph>
18
+ </Card>
19
+ </PageContainer>
20
+ );
21
+ };
22
+
23
+ export default HomePage;
@@ -0,0 +1,27 @@
1
+ .navs {
2
+ ul {
3
+ padding: 0;
4
+ margin: 0;
5
+ list-style: none;
6
+ display: flex;
7
+ background: #f6f6f6;
8
+ padding: 10px;
9
+ }
10
+
11
+ li {
12
+ margin-right: 20px;
13
+ }
14
+
15
+ a {
16
+ text-decoration: none;
17
+ color: #333;
18
+ padding: 8px 16px;
19
+ border-radius: 4px;
20
+ transition: background-color 0.3s;
21
+
22
+ &:hover {
23
+ background-color: #e6f7ff;
24
+ color: #1890ff;
25
+ }
26
+ }
27
+ }
@@ -0,0 +1,18 @@
1
+ import { Link, Outlet } from '@umijs/max';
2
+ import styles from './index.less';
3
+
4
+ export default function Layout() {
5
+ return (
6
+ <div className={styles.navs}>
7
+ <ul>
8
+ <li>
9
+ <Link to="/home">首页</Link>
10
+ </li>
11
+ <li>
12
+ <Link to="/about">关于</Link>
13
+ </li>
14
+ </ul>
15
+ <Outlet />
16
+ </div>
17
+ );
18
+ }
@@ -0,0 +1,5 @@
1
+ node_modules
2
+ .umi
3
+ .umi-production
4
+ .umi-test
5
+ /dist
@@ -0,0 +1,8 @@
1
+ {
2
+ "printWidth": 80,
3
+ "singleQuote": true,
4
+ "trailingComma": "all",
5
+ "proseWrap": "never",
6
+ "overrides": [{ "files": ".prettierrc", "options": { "parser": "json" } }],
7
+ "plugins": ["prettier-plugin-organize-imports", "prettier-plugin-packagejson"]
8
+ }
@@ -0,0 +1,3 @@
1
+ {
2
+ "extends": "./src/.umi/tsconfig.json"
3
+ }
@@ -0,0 +1,102 @@
1
+ const fs = require('fs-extra');
2
+ const path = require('path');
3
+
4
+ // 模板变量替换函数
5
+ function replaceTemplateVariables(content, variables) {
6
+ let result = content;
7
+ for (const [key, value] of Object.entries(variables)) {
8
+ const placeholder = `{{${key}}}`;
9
+ result = result.replace(new RegExp(placeholder, 'g'), value || '');
10
+ }
11
+ return result;
12
+ }
13
+
14
+ // 递归复制目录并替换模板变量
15
+ async function copyTemplateDir(srcDir, destDir, variables) {
16
+ await fs.ensureDir(destDir);
17
+
18
+ const items = await fs.readdir(srcDir);
19
+
20
+ for (const item of items) {
21
+ const srcPath = path.join(srcDir, item);
22
+ const destPath = path.join(destDir, item);
23
+
24
+ const stat = await fs.stat(srcPath);
25
+
26
+ if (stat.isDirectory()) {
27
+ // 递归处理子目录
28
+ await copyTemplateDir(srcPath, destPath, variables);
29
+ } else {
30
+ // 处理文件
31
+ const content = await fs.readFile(srcPath, 'utf8');
32
+ const processedContent = replaceTemplateVariables(content, variables);
33
+ await fs.writeFile(destPath, processedContent);
34
+ }
35
+ }
36
+ }
37
+
38
+ async function generateTemplate(projectName, templateType, targetDir) {
39
+ const templatesDir = path.join(__dirname, './');
40
+ const templateDir = path.join(templatesDir, templateType);
41
+ const commonDir = path.join(templatesDir, 'common');
42
+
43
+ // 检查模板是否存在
44
+ if (!await fs.pathExists(templateDir)) {
45
+ throw new Error(`模板 "${templateType}" 不存在`);
46
+ }
47
+
48
+ // 模板变量
49
+ const variables = {
50
+ projectName: projectName || 'my-umi-app'
51
+ };
52
+
53
+ // 确保目标目录存在
54
+ await fs.ensureDir(targetDir);
55
+
56
+ // 首先创建基础目录结构
57
+ const baseDirs = ['src/pages', 'src/components', 'src/services', 'src/utils'];
58
+ for (const dir of baseDirs) {
59
+ await fs.ensureDir(path.join(targetDir, dir));
60
+ }
61
+
62
+ // 复制模板特定的文件
63
+ console.log(`📂 正在复制模板文件...`);
64
+ await copyTemplateDir(templateDir, targetDir, variables);
65
+
66
+ // 复制通用文件
67
+ if (await fs.pathExists(commonDir)) {
68
+ console.log(`📄 正在复制通用配置文件...`);
69
+ await copyTemplateDir(commonDir, targetDir, variables);
70
+ }
71
+
72
+ console.log(`✅ 模板文件复制完成`);
73
+ }
74
+
75
+ // 获取可用的模板列表
76
+ async function getAvailableTemplates() {
77
+ const templatesDir = path.join(__dirname, './');
78
+
79
+ if (!await fs.pathExists(templatesDir)) {
80
+ return [];
81
+ }
82
+
83
+ const items = await fs.readdir(templatesDir);
84
+ const templates = [];
85
+
86
+ for (const item of items) {
87
+ const itemPath = path.join(templatesDir, item);
88
+ const stat = await fs.stat(itemPath);
89
+
90
+ // 排除common目录和index.js文件,只返回实际的模板目录
91
+ if (stat.isDirectory() && item !== 'common') {
92
+ templates.push(item);
93
+ }
94
+ }
95
+
96
+ return templates;
97
+ }
98
+
99
+ module.exports = {
100
+ generateTemplate,
101
+ getAvailableTemplates
102
+ };
package/package.json ADDED
@@ -0,0 +1,53 @@
1
+ {
2
+ "name": "@ysjdemo/umi-create-cli",
3
+ "author": "ysj <411367308@qq.com>",
4
+ "version": "0.0.1",
5
+ "description": "一个用于创建Umi4项目的脚手架工具",
6
+ "main": "index.js",
7
+ "bin": {
8
+ "ysj-umi": "./bin/cli.js"
9
+ },
10
+ "scripts": {
11
+ "start": "node bin/cli.js",
12
+ "test": "echo \"Error: no test specified\" && exit 1",
13
+ "prepublishOnly": "echo 'Preparing to publish...'",
14
+ "publish:auto": "node scripts/publish.js",
15
+ "version:patch": "npm version patch",
16
+ "version:minor": "npm version minor",
17
+ "version:major": "npm version major"
18
+ },
19
+ "files": [
20
+ "bin/",
21
+ "lib/",
22
+ "README.md"
23
+ ],
24
+ "keywords": [
25
+ "umi",
26
+ "umi4",
27
+ "cli"
28
+ ],
29
+ "license": "MIT",
30
+ "repository": {
31
+ "type": "git",
32
+ "url": "https://github.com/yourusername/cfmm-cli-umi.git"
33
+ },
34
+ "bugs": {
35
+ "url": "https://github.com/yourusername/cfmm-cli-umi/issues"
36
+ },
37
+ "homepage": "https://github.com/yourusername/cfmm-cli-umi#readme",
38
+ "publishConfig": {
39
+ "access": "public"
40
+ },
41
+ "dependencies": {
42
+ "chalk": "^4.1.2",
43
+ "commander": "^9.4.1",
44
+ "download-git-repo": "^3.0.2",
45
+ "fs-extra": "^11.1.1",
46
+ "inquirer": "^8.2.5",
47
+ "ora": "^5.4.1"
48
+ },
49
+ "engines": {
50
+ "node": ">=14.0.0"
51
+ },
52
+ "packageManager": "yarn@4.9.1"
53
+ }