wyt-cli 1.0.2
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/bin/commands/create.js +96 -0
- package/bin/lib/const.js +1 -0
- package/bin/lib/utils.js +15 -0
- package/bin/main.js +52 -0
- package/bin/templates/default/main.js +1 -0
- package/bin/templates/default/package-lock.json +0 -0
- package/bin/templates/default/package.json +11 -0
- package/package.json +28 -0
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
// commands/create.js
|
|
2
|
+
|
|
3
|
+
import path from "path";
|
|
4
|
+
import { require, projectRoot } from "../lib/utils.js";
|
|
5
|
+
|
|
6
|
+
// 外部依赖
|
|
7
|
+
import { Command } from "commander";
|
|
8
|
+
import fs from "fs-extra";
|
|
9
|
+
import ora from "ora";
|
|
10
|
+
import chalk from "chalk";
|
|
11
|
+
import inquirer from "inquirer";
|
|
12
|
+
|
|
13
|
+
// 命令配置
|
|
14
|
+
export default function () {
|
|
15
|
+
const command = new Command("create");
|
|
16
|
+
command.description("创建一个新项目");
|
|
17
|
+
command.argument("[project-name]", "项目名称(仅支持字母、数字和中划线)", "my-project");
|
|
18
|
+
command.option("-t, --template <template-name>", "指定项目模板", "default");
|
|
19
|
+
command.option("-d, --dir <directory>", "指定创建目录", process.cwd());
|
|
20
|
+
command.option("-f, --force", "强制覆盖已存在目录");
|
|
21
|
+
command.action(core);
|
|
22
|
+
|
|
23
|
+
return command;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// 核心创建逻辑
|
|
27
|
+
function core(projectName, options) {
|
|
28
|
+
try {
|
|
29
|
+
// 校验项目名称是否合法
|
|
30
|
+
if (!/^[a-zA-Z0-9-]+$/.test(projectName)) {
|
|
31
|
+
console.error("项目名称只能包含字母、数字和中划线!");
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
const spinner = ora("正在创建项目...").start();
|
|
35
|
+
const targetDir = path.resolve(options.dir, projectName);
|
|
36
|
+
// 校验目录存在性
|
|
37
|
+
if (fs.existsSync(targetDir)) {
|
|
38
|
+
if (!options.force) {
|
|
39
|
+
spinner.fail(`目录 ${targetDir} 已存在`);
|
|
40
|
+
throw new Error("使用 --force 强制覆盖");
|
|
41
|
+
}
|
|
42
|
+
spinner.stop();
|
|
43
|
+
inquirer
|
|
44
|
+
.prompt([
|
|
45
|
+
{
|
|
46
|
+
type: "confirm",
|
|
47
|
+
name: "confirmOverwrite",
|
|
48
|
+
message: `目录 ${targetDir} 已存在,是否覆盖?`,
|
|
49
|
+
default: true,
|
|
50
|
+
},
|
|
51
|
+
])
|
|
52
|
+
.then((answers) => {
|
|
53
|
+
if (answers.confirmOverwrite) {
|
|
54
|
+
spinner.info("强制覆盖已存在目录");
|
|
55
|
+
fs.emptyDirSync(targetDir);
|
|
56
|
+
createProject(projectName, targetDir, options);
|
|
57
|
+
|
|
58
|
+
// 关闭进度条
|
|
59
|
+
spinner.succeed(chalk.green(`项目 ${projectName} 强制创建成功!`));
|
|
60
|
+
} else {
|
|
61
|
+
spinner.fail("操作已取消");
|
|
62
|
+
process.exit(1);
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
} else {
|
|
66
|
+
createProject(projectName, targetDir, options);
|
|
67
|
+
|
|
68
|
+
// 关闭进度条
|
|
69
|
+
spinner.succeed(chalk.green(`项目 ${projectName} 创建成功!`));
|
|
70
|
+
}
|
|
71
|
+
} catch (error) {
|
|
72
|
+
console.error(chalk.red(`\n错误:${error.message}`));
|
|
73
|
+
process.exit(1);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// 创建项目
|
|
78
|
+
function createProject(projectName, targetDir, options) {
|
|
79
|
+
// 复制模板文件
|
|
80
|
+
const templatePath = path.resolve(projectRoot, "bin", "templates", options.template);
|
|
81
|
+
fs.ensureDirSync(targetDir); // 创建项目目录
|
|
82
|
+
fs.copySync(templatePath, targetDir, {
|
|
83
|
+
filter: (src) => {
|
|
84
|
+
// 定义要排除的文件/目录名
|
|
85
|
+
const excludes = new Set(["node_modules", "package-lock.json"]);
|
|
86
|
+
// 获取当前处理的文件/目录名
|
|
87
|
+
const basename = path.basename(src);
|
|
88
|
+
// 过滤逻辑:存在排除列表中的不复制
|
|
89
|
+
return !excludes.has(basename);
|
|
90
|
+
},
|
|
91
|
+
});
|
|
92
|
+
// 更新 package.json
|
|
93
|
+
const pkg = require(path.join(templatePath, "package.json"));
|
|
94
|
+
pkg.name = projectName;
|
|
95
|
+
fs.writeFileSync(path.join(targetDir, "package.json"), JSON.stringify(pkg, null, 2));
|
|
96
|
+
}
|
package/bin/lib/const.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const LOWEST_NODE_VERSION = "18.0.0"; // 最低的 node 版本
|
package/bin/lib/utils.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// bin/lib/index.js
|
|
2
|
+
import { createRequire } from "module";
|
|
3
|
+
import { fileURLToPath } from "url";
|
|
4
|
+
import path from "path";
|
|
5
|
+
|
|
6
|
+
// 转换 URL 为系统路径
|
|
7
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
8
|
+
const __dirname = path.dirname(__filename);
|
|
9
|
+
|
|
10
|
+
// 计算项目根目录(假设该文件在 bin/lib/ 下)
|
|
11
|
+
export const projectRoot = path.resolve(__dirname, "../../");
|
|
12
|
+
|
|
13
|
+
// ES6 自定义 require 函数,用于读取 .json 文件信息
|
|
14
|
+
// import.meta.url 的路径基准点是 当前文件所在目录(即 bin/lib/index.js)
|
|
15
|
+
export const require = createRequire(projectRoot + "/");
|
package/bin/main.js
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import configureCreateCommand from "./commands/create.js";
|
|
3
|
+
import { require } from "./lib/utils.js";
|
|
4
|
+
import { LOWEST_NODE_VERSION } from "./lib/const.js";
|
|
5
|
+
|
|
6
|
+
// 外部依赖
|
|
7
|
+
import semver from "semver";
|
|
8
|
+
import chalk from "chalk";
|
|
9
|
+
import { Command } from "commander";
|
|
10
|
+
|
|
11
|
+
// 全局变量
|
|
12
|
+
const program = new Command();
|
|
13
|
+
const { version } = require("./package.json");
|
|
14
|
+
|
|
15
|
+
// 主程序
|
|
16
|
+
const main = () => {
|
|
17
|
+
try {
|
|
18
|
+
checkGlobalUpdate();
|
|
19
|
+
checkNodeVersion();
|
|
20
|
+
handleProgramCommand();
|
|
21
|
+
} catch (error) {
|
|
22
|
+
console.error(chalk.red(`错误:${error.message}`));
|
|
23
|
+
process.exit(1);
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
main();
|
|
27
|
+
|
|
28
|
+
// 处理 CLI 命令
|
|
29
|
+
function handleProgramCommand() {
|
|
30
|
+
// 基本信息
|
|
31
|
+
program.name("cli-test").description(`这是 hrp3.0 项目的命令行工具,当前版本为${version}`);
|
|
32
|
+
program.version(version, "-v, --version", "显示版本信息");
|
|
33
|
+
program.helpOption("-h, --help", "显示帮助信息").helpCommand(false);
|
|
34
|
+
|
|
35
|
+
// 注册子命令
|
|
36
|
+
program.addCommand(configureCreateCommand());
|
|
37
|
+
|
|
38
|
+
// 解析命令行参数
|
|
39
|
+
program.parse(program.argv);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// 检测 node 版本
|
|
43
|
+
function checkNodeVersion() {
|
|
44
|
+
const currentVersion = process.version.slice(1);
|
|
45
|
+
const lowestVersion = LOWEST_NODE_VERSION;
|
|
46
|
+
if (!semver.gte(currentVersion, lowestVersion)) {
|
|
47
|
+
throw new Error(`当前 node 版本过低,请升级至 ${lowestVersion} 及以上版本`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// 检测全局更新
|
|
52
|
+
function checkGlobalUpdate() {}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
console.log("Hello, World!");
|
|
File without changes
|
package/package.json
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "wyt-cli",
|
|
3
|
+
"version": "1.0.2",
|
|
4
|
+
"description": "HRP3.0 项目命令行工具",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"wyt-cli": "./bin/main.js"
|
|
8
|
+
},
|
|
9
|
+
"publishConfig": {
|
|
10
|
+
"access": "public"
|
|
11
|
+
},
|
|
12
|
+
"type": "module",
|
|
13
|
+
"scripts": {
|
|
14
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [],
|
|
17
|
+
"author": "",
|
|
18
|
+
"license": "ISC",
|
|
19
|
+
"dependencies": {
|
|
20
|
+
"axios": "^1.13.2",
|
|
21
|
+
"chalk": "^5.6.2",
|
|
22
|
+
"commander": "^14.0.2",
|
|
23
|
+
"fs-extra": "^11.3.3",
|
|
24
|
+
"inquirer": "^13.2.0",
|
|
25
|
+
"ora": "^9.0.0",
|
|
26
|
+
"semver": "^7.7.3"
|
|
27
|
+
}
|
|
28
|
+
}
|