@colpu/cli 0.2.1 → 1.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/.eslintrc.js CHANGED
@@ -1,4 +1,4 @@
1
- module.exports = {
1
+ export default {
2
2
  "parserOptions": { // 设置解析器选项
3
3
  "ecmaVersion": 8, // 指定要使用的 ECMAScript 版本 8
4
4
  "sourceType": "module", //指定代码为 ECMAScript 模块
package/.hintrc ADDED
@@ -0,0 +1,14 @@
1
+ {
2
+ "extends": [
3
+ "development"
4
+ ],
5
+ "hints": {
6
+ "no-inline-styles": "off",
7
+ "axe/forms": [
8
+ "default",
9
+ {
10
+ "label": "off"
11
+ }
12
+ ]
13
+ }
14
+ }
package/package.json CHANGED
@@ -1,28 +1,28 @@
1
1
  {
2
2
  "name": "@colpu/cli",
3
- "version": "0.2.1",
3
+ "version": "1.0.1",
4
4
  "description": "项目启动cli",
5
- "main": "index.js",
5
+ "type": "module",
6
+ "main": "src/index.js",
6
7
  "scripts": {
7
- "dev": "node bin/colpu-cli dev",
8
+ "dev": "node src/bin/colpu-cli dev",
8
9
  "test": "echo \"Error: no test specified\" && exit 1"
9
10
  },
10
11
  "bin": {
11
- "colpu-cli": "bin/colpu-cli"
12
+ "colpu-cli": "src/bin/colpu-cli"
12
13
  },
13
- "author": "",
14
+ "author": "ycg520520",
14
15
  "license": "ISC",
15
16
  "dependencies": {
16
- "@colpu/cli": "^0.2.1",
17
- "chalk": "^4.1.1",
18
- "debug": "^4.3.2",
19
- "git-clone": "^0.1.0",
20
- "global": "^4.4.0",
21
- "inquirer": "^8.1.1",
22
- "lodash": "^4.17.21",
23
- "ora": "^5.4.1",
24
- "shelljs": "^0.8.4",
25
- "shipit-deploy": "^5.3.0",
26
- "table": "^6.7.1"
17
+ "chalk": "^5.6.2",
18
+ "commander": "^14.0.3",
19
+ "debug": "^4.4.3",
20
+ "execa": "^9.6.1",
21
+ "globby": "^16.1.1",
22
+ "inquirer": "^13.3.0",
23
+ "lodash": "^4.17.23",
24
+ "ora": "^9.3.0",
25
+ "shelljs": "^0.10.0",
26
+ "table": "^6.9.0"
27
27
  }
28
28
  }
@@ -0,0 +1,11 @@
1
+ #! /usr/bin/env node
2
+ /*
3
+ * @Author: colpu
4
+ * @Date: 2025-03-29 17:51:11
5
+ * @LastEditors: colpu ycg520520@qq.com
6
+ * @LastEditTime: 2026-02-28 17:30:31
7
+ *
8
+ * Copyright (c) 2025 by colpu, All Rights Reserved.
9
+ */
10
+ import Cli from '../index.js';
11
+ new Cli();
@@ -0,0 +1,19 @@
1
+ /**
2
+ * @Author: colpu
3
+ * @Date: 2025-03-29 17:57:34
4
+ * @LastEditors: colpu ycg520520@qq.com
5
+ * @LastEditTime: 2026-02-28 18:02:25
6
+ * @
7
+ * @Copyright (c) 2025 by colpu, All Rights Reserved.
8
+ */
9
+ /**
10
+ * @function commond 执行命令方法
11
+ * @param {String} env 环境变量
12
+ * @param {String} argv bash 参数
13
+ * @description 执行打包
14
+ */
15
+ import build from '@colpu/build/src/build';
16
+
17
+ export default async function build(env, argv) {
18
+ await build();
19
+ }
@@ -1,12 +1,16 @@
1
- const shell = require('shelljs'); // 脚本执行
2
- const _ = require('lodash');
3
- const inquirer = require('inquirer');
4
1
  /**
5
- @description 发布命令
6
- @cmd npm run shipit
7
- */
8
- module.exports = async function commond(env, argv) {
9
- const otherArgv = argv.split(' ').splice(1);
2
+ * @Author: colpu
3
+ * @Date: 2025-03-29 17:57:34
4
+ * @LastEditors: colpu ycg520520@qq.com
5
+ * @LastEditTime: 2026-02-09 16:11:19
6
+ * @
7
+ * @Copyright (c) 2025 by colpu, All Rights Reserved.
8
+ */
9
+ import shell from 'shelljs'; // 脚本执行
10
+ import _ from 'lodash';
11
+ import inquirer from 'inquirer';
12
+ export default async function create(env, argv) {
13
+ const otherArgv = argv.splice(1);
10
14
  // 选择模式
11
15
  const choicesMap = {
12
16
  master: '网站开发模板,前后端同构开发',
@@ -1,12 +1,20 @@
1
- const shell = require('shelljs'); // 脚本执行
1
+ /**
2
+ * @Author: colpu
3
+ * @Date: 2025-03-29 17:57:34
4
+ * @LastEditors: colpu ycg520520@qq.com
5
+ * @LastEditTime: 2026-02-28 18:02:11
6
+ * @
7
+ * @Copyright (c) 2025 by colpu, All Rights Reserved.
8
+ */
9
+ import shell from 'shelljs'; // 脚本执行
10
+
2
11
  /**
3
12
  * @function commond 执行命令方法
4
13
  * @param {String} env 环境变量
5
14
  * @param {String} argv bash 参数
6
15
  * @description 本地开发
7
16
  */
8
- module.exports = async function commond(env, argv) {
9
- process.env.NODE_ENV = env;
17
+ export default async function daemon(env, argv) {
10
18
  if (!shell.which('pm2')) {
11
19
  // 在控制台输出内容
12
20
  shell.echo('抱歉没有安装pm2');
@@ -16,4 +24,4 @@ module.exports = async function commond(env, argv) {
16
24
  shell.echo(bash);
17
25
  shell.exec(bash);
18
26
  }
19
- }
27
+ };
@@ -0,0 +1,50 @@
1
+ /**
2
+ * @Author: colpu
3
+ * @Date: 2025-03-29 17:57:34
4
+ * @LastEditors: colpu ycg520520@qq.com
5
+ * @LastEditTime: 2026-03-01 17:54:39
6
+ * @
7
+ * @Copyright (c) 2025 by colpu, All Rights Reserved.
8
+ */
9
+ import shell from "shelljs"; // 脚本执行
10
+ import { Command } from "commander";
11
+ import { writeJSModuleToJSON } from "../utils/index.js"; // 写入JSON文件
12
+ /**
13
+ * @function deploy 执行命令方法
14
+ * @param {String} env 环境变量
15
+ * @param {String} argv bash 参数
16
+ * @description 本地开发
17
+ */
18
+ const program = new Command();
19
+ const PROCESS_CWD = process.cwd(); // 进程启动位置
20
+ export default async function deploy(env, argv) {
21
+ if (!shell.which("pm2")) {
22
+ // 在控制台输出内容
23
+ shell.echo("抱歉没有安装pm2");
24
+ shell.exit();
25
+ } else {
26
+ let bash = "";
27
+ if (argv.includes("-h") || argv.includes("--help")) {
28
+ program.option(
29
+ "-g, --generate",
30
+ `生成pm2配置文件,默认生成launched.config.json,通过pm2 deploy命令部署。原因是PM2读取配置文件不支持ESM模块的顶层await import语法`,
31
+ );
32
+ program.parse();
33
+ return;
34
+ }
35
+ if (argv.includes("-g") || argv.includes("--generate")) {
36
+ const index = argv.indexOf("-g") || argv.indexOf("--generate");
37
+ argv.splice(index, 1);
38
+
39
+ await writeJSModuleToJSON(
40
+ `${PROCESS_CWD}/launched.config.js`,
41
+ );
42
+ bash = `pm2 deploy launched.config.json ${env} ${argv.join(" ")}`;
43
+ shell.echo("✅ PM2 配置文件已生成");
44
+ } else {
45
+ bash = `pm2 deploy launched.config.js ${env} ${argv.join(" ")}`;
46
+ }
47
+ shell.echo(bash);
48
+ shell.exec(bash);
49
+ }
50
+ }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * @Author: colpu
3
+ * @Date: 2025-03-29 17:57:35
4
+ * @LastEditors: colpu ycg520520@qq.com
5
+ * @LastEditTime: 2026-02-28 18:01:15
6
+ * @
7
+ * @Copyright (c) 2025 by colpu, All Rights Reserved.
8
+ */
9
+ /**
10
+ * @function commond 执行命令方法
11
+ * @param {String} env 环境变量
12
+ * @param {String} argv bash 参数
13
+ * @description 本地开发
14
+ */
15
+ import { loadFile } from "../utils/index.js";
16
+ export default async function commond(env, argv) {
17
+ loadFile(`${process.cwd()}/node_modules/@colpu/build`)();
18
+ };
@@ -0,0 +1,36 @@
1
+ /**
2
+ * @Author: colpu
3
+ * @Date: 2025-07-16 16:10:15
4
+ * @LastEditors: colpu ycg520520@qq.com
5
+ * @LastEditTime: 2026-02-28 18:32:29
6
+ * @
7
+ * @Copyright (c) 2025 by colpu, All Rights Reserved.
8
+ */
9
+
10
+ /**
11
+ * @description help命令提示
12
+ * @cmd npm run help
13
+ */
14
+ import Table from "table";
15
+ import envs from "../config/envs.js";
16
+
17
+ export default async () => {
18
+ const envList = Object.keys(envs).join(",");
19
+ const data = [
20
+ ["命令", "可选参数", "说明"],
21
+ ["colpu-cli help", "-", "命令帮助"],
22
+ ["colpu-cli dev", "-", "本地开发"],
23
+ ["colpu-cli inspect", "-", "开发调试"],
24
+ ["colpu-cli build", "-", "发布构建"],
25
+ ["colpu-cli service", envList, "启动node服务"],
26
+ ["colpu-cli daemon", envList, "启动守护进程,当前为pm2守护进程"],
27
+ ["colpu-cli deploy", envList, "启动pm2发布环境,生成pm2配置json文件"],
28
+ ["colpu-cli create", "你需要创建的目录", "下载模板"],
29
+ ];
30
+
31
+ const config = {
32
+ border: Table.getBorderCharacters("norc"),
33
+ };
34
+ const output = Table.table(data, config);
35
+ console.log(output);
36
+ };
@@ -0,0 +1,122 @@
1
+ /**
2
+ * @Author: colpu
3
+ * @Date: 2023-11-06 13:55:06
4
+ * @LastEditors: colpu ycg520520@qq.com
5
+ * @LastEditTime: 2026-02-10 09:31:49
6
+ * @
7
+ * @Copyright (c) 2025 by colpu, All Rights Reserved.
8
+ */
9
+ import inquirer from "inquirer";
10
+
11
+ import spinnerFactory from "ora";
12
+ const spinner = spinnerFactory(); // 终端旋转器,loading颜色变化
13
+ import chalk from "chalk"; // 终端字符串样式模块
14
+ import shell from "shelljs"; // 脚本执行
15
+ const CWD = process.cwd();
16
+
17
+ /**
18
+ * @function commond 执行命令方法
19
+ * @param {String} env 环境变量
20
+ * @param {String} argv bash 参数
21
+ * @description 用于克隆初始化项目( 待完成)
22
+ */
23
+ import fs from "fs";
24
+ import { loadFile, readJSONSync } from "../utils/index.js";
25
+
26
+ function defaultConfig(data) {
27
+ const DEFAULT = {
28
+ name: "example",
29
+ version: "1.0.0",
30
+ description: "您什么都没留下~",
31
+ license: "ISC",
32
+ port: 3000,
33
+ };
34
+ for (let key in data) {
35
+ if (!data[key]) {
36
+ delete data[key];
37
+ }
38
+ }
39
+ return Object.assign(DEFAULT, data);
40
+ }
41
+ const promptList = [
42
+ {
43
+ type: "input",
44
+ message: "请输入项目名称:",
45
+ suffix: "***推荐使用英文和下划线进行命名***",
46
+ name: "name",
47
+ },
48
+ {
49
+ type: "input",
50
+ message: "版本:",
51
+ name: "version",
52
+ },
53
+ {
54
+ type: "input",
55
+ message: "描述:",
56
+ name: "description",
57
+ },
58
+ {
59
+ type: "input",
60
+ message: "仓库地址:",
61
+ name: "repository",
62
+ },
63
+ {
64
+ type: "input",
65
+ message: "作者:",
66
+ name: "author",
67
+ },
68
+ {
69
+ type: "input",
70
+ message: "许可协议",
71
+ name: "license",
72
+ },
73
+ {
74
+ type: "input",
75
+ message: "端口",
76
+ name: "port",
77
+ },
78
+ ];
79
+ export default async function init(env, argv) {
80
+ const branchs = ["master", "api"];
81
+ const answers = await inquirer.prompt(promptList);
82
+ const answersConfig = defaultConfig(answers);
83
+ const repo = "https://gitee.com/ycg520520/colpu-example.git"; // git仓库地址
84
+ if (!shell.which("git")) {
85
+ // 在控制台输出内容
86
+ shell.echo("抱歉没有安装git");
87
+ shell.exit(1);
88
+ } else {
89
+ let branch = argv[1];
90
+ branch = branchs.indexOf(branch) > -1 ? branch : "";
91
+ const clone = `git clone ${branch ? `-b ${branch} ` : ""}${repo} ${
92
+ answersConfig.name
93
+ }`;
94
+ spinner.start(`正在下载项目 (${clone})...`);
95
+ shell.exec(clone, async (code, stdout, stderr) => {
96
+ debugger;
97
+ if (code == 0) {
98
+ spinner.succeed(chalk.green("模板克隆成功^_^。"));
99
+ // 初始化项目
100
+ spinner.info(chalk.green(`正在初始化项目: ${answersConfig.name}`));
101
+ const projectDir = `${CWD}/${answersConfig.name}/`;
102
+ const packagePath = `${projectDir}package.json`;
103
+ const configPath = `${projectDir}src/config/index.js`;
104
+ const pkg = await readJSONSync(packagePath);
105
+ const config = await loadFile(configPath);
106
+ Object.assign(pkg, answersConfig);
107
+ pkg.repository.url = config.repository || repo;
108
+ config.port = config.port;
109
+ fs.writeFileSync(packagePath, JSON.stringify(pkg, null, "\t"));
110
+ let configStr = `export default `;
111
+ configStr += JSON.stringify(config, null, "\t");
112
+ configStr = configStr.replace(/"([a-zA-Z0-9_]+)":/gi, "$1:");
113
+ fs.writeFileSync(configPath, configStr);
114
+ spinner.succeed(chalk.green(`初始化项目 ${answersConfig.name} 成功`));
115
+ spinner.stop();
116
+ } else {
117
+ console.error(stderr);
118
+ process.exit();
119
+ }
120
+ });
121
+ }
122
+ }
@@ -0,0 +1,22 @@
1
+ /**
2
+ * @Author: colpu
3
+ * @Date: 2025-03-29 17:57:34
4
+ * @LastEditors: colpu ycg520520@qq.com
5
+ * @LastEditTime: 2026-02-28 18:36:53
6
+ * @
7
+ * @Copyright (c) 2025 by colpu, All Rights Reserved.
8
+ */
9
+ import shell from 'shelljs'; // 脚本执行
10
+
11
+ /**
12
+ * @function inspect 执行命令方法
13
+ * @param {String} env 环境变量
14
+ * @param {String} argv bash 参数
15
+ * @description 本地开发
16
+ */
17
+
18
+ export default async function inspect(env, argv) {
19
+ const bash = `NODE_ENV=${env} node --inspect-brk ./node_modules/@colpu/cli/src/script/service.js`
20
+ shell.echo(bash);
21
+ shell.exec(bash);
22
+ };
@@ -0,0 +1,24 @@
1
+ /**
2
+ * @Author: colpu
3
+ * @Date: 2025-03-29 17:57:34
4
+ * @LastEditors: colpu ycg520520@qq.com
5
+ * @LastEditTime: 2026-02-28 18:21:39
6
+ * @
7
+ * @Copyright (c) 2025 by colpu, All Rights Reserved.
8
+ */
9
+ import shell from "shelljs"; // 脚本执行
10
+ /**
11
+ * @function service 执行命令方法
12
+ * @param {String} env 环境变量
13
+ * @param {String} argv bash 参数
14
+ * @description 用于启动服务
15
+ */
16
+ export default function service(env, argv) {
17
+ if (env === "development") {
18
+ const bash = `nodemon ./node_modules/@colpu/cli/src/script/service.js`;
19
+ shell.echo("启动开发环境服务...");
20
+ shell.exec(bash);
21
+ } else {
22
+ import("../script/service.js");
23
+ }
24
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * @Author: colpu
3
+ * @Date: 2026-02-28 13:56:44
4
+ * @LastEditors: colpu ycg520520@qq.com
5
+ * @LastEditTime: 2026-02-28 17:57:14
6
+ * @
7
+ * @Copyright (c) 2026 by colpu, All Rights Reserved.
8
+ */
9
+ export default {
10
+ development: "开发环境(development)",
11
+ preview: "预览环境(preview)",
12
+ release: "预发布环境(release)",
13
+ production: "正式环境(production)",
14
+ }
package/src/index.d.ts ADDED
@@ -0,0 +1,19 @@
1
+ /*
2
+ * @Author: colpu
3
+ * @Date: 2026-02-09 12:42:17
4
+ * @LastEditors: colpu ycg520520@qq.com
5
+ * @LastEditTime: 2026-02-09 15:26:41
6
+ *
7
+ * Copyright (c) 2026 by colpu, All Rights Reserved.
8
+ */
9
+ export declare module "@colpu/cli" {
10
+ interface Cli {
11
+ options: Record<string, any>;
12
+ choices: string[];
13
+ envs: string[];
14
+ argv: string;
15
+ init: Function;
16
+ loadCommand: Function;
17
+ exactInquirer: Function;
18
+ }
19
+ }
package/src/index.js ADDED
@@ -0,0 +1,101 @@
1
+ #! /usr/bin/env node
2
+ /**
3
+ * @Author: colpu
4
+ * @Date: 2025-03-29 17:57:34
5
+ * @LastEditors: colpu ycg520520@qq.com
6
+ * @LastEditTime: 2026-02-28 18:30:46
7
+ * @Description 构建、开发命令入口
8
+ * @cmd npm run xxx
9
+ * dev | build | production
10
+ * 本地开发 | 发布打包 | 运行生成环境
11
+ * Copyright (c) 2025 by colpu, All Rights Reserved.
12
+ */
13
+ import inquirer from "inquirer";
14
+ import shell from "shelljs"; // 脚本执行
15
+ import { globbySync } from 'globby';
16
+ import chalk from 'chalk';
17
+ import { loadFile, getConfig, fixFilepath } from "./utils/index.js";
18
+ const resolve = import.meta.resolve;
19
+ import envs from "./config/envs.js";
20
+ export { inquirer, getConfig, loadFile };
21
+ export default class Cli {
22
+ constructor() {
23
+ this.options = {
24
+ // 支持命令
25
+ commands: globbySync('*', {
26
+ cwd: fixFilepath(resolve('./command'))
27
+ }).map(item => item.replace(/\.js$/, '')),
28
+ //环境配置
29
+ envs
30
+ };
31
+ // 组装选择项
32
+ const choices = Object.assign({}, envs, {
33
+ exit: "退出",
34
+ });
35
+ this.choiceValues = Object.values(choices).map((item) => item);
36
+ this.choiceKeys = Object.keys(choices);
37
+ // 获取命令行参数
38
+ this.envKeys = Object.keys(envs);
39
+ this.argv = process.argv.slice(2);
40
+ this.init();
41
+ }
42
+
43
+ async init() {
44
+ const _this = this;
45
+ const argv = _this.argv;
46
+ const commands = _this.options.commands;
47
+ const envs = _this.envKeys;
48
+ const _command = argv[0]; // 主命令
49
+ const command = ['-h', '--help'].includes(_command) ? 'help' : _command;
50
+ let env = argv[1]; // 环境命令
51
+ if (!commands.includes(command)) {
52
+ console.log(chalk.red(`命令: ${_command} 不存在,请重新输入`));
53
+ shell.exit();
54
+ }
55
+
56
+ // 如果需要选择环境,同时环境命令不在指定范围的,需要提示并将选择好环境变量装入到对应位置
57
+ const isSelectENV = env && envs.includes(env);
58
+ // 没有选择环境则在终端做提示选择
59
+ if (!isSelectENV && command !== 'help') {
60
+ const sel = await _this.exactInquirer();
61
+ if (sel === "exit") {
62
+ shell.exit();
63
+ }
64
+ env = sel;
65
+ // 将环境变量装入到argv中,位置在主命令后面
66
+ argv.splice(1, 0, sel);
67
+ }
68
+
69
+ // 环境变量在argv的位置
70
+ const envIndex = argv.indexOf(env);
71
+ if (envIndex > -1) {
72
+ argv.splice(0, envIndex + 1);
73
+ }
74
+
75
+ await _this.loadCommand(command, env, argv);
76
+ }
77
+ async loadCommand(command, env, argv = []) {
78
+ process.env.NODE_ENV = env;
79
+ const handdle = await loadFile(resolve(`./command/${command}.js`));
80
+ handdle(env, argv);
81
+ }
82
+
83
+ /**
84
+ * @function exactInquirer 执行用户交互提示
85
+ * @description 当用户输入的命令不环境不完全时,进行提示
86
+ * @return {Promise<String>} 环境参数
87
+ */
88
+ async exactInquirer() {
89
+ const choices = this.choiceValues;
90
+ const promptList = [
91
+ {
92
+ type: "rawlist",
93
+ message: chalk.bold(chalk.blue("靠谱少年,请选择需要的执行环境: ")),
94
+ name: "content",
95
+ choices,
96
+ },
97
+ ];
98
+ const { content } = await inquirer.prompt(promptList);
99
+ return this.choiceKeys[choices.indexOf(content)];
100
+ }
101
+ }
@@ -0,0 +1,11 @@
1
+ /**
2
+ * @Author: colpu
3
+ * @Date: 2025-03-29 17:57:34
4
+ * @LastEditors: colpu ycg520520@qq.com
5
+ * @LastEditTime: 2026-02-28 16:45:03
6
+ * @
7
+ * @Copyright (c) 2025 by colpu, All Rights Reserved.
8
+ */
9
+ import Server from "@colpu/core";
10
+ const app = new Server();
11
+ app.start();
@@ -0,0 +1,147 @@
1
+ /**
2
+ * @Author: colpu
3
+ * @Date: 2025-03-29 19:38:16
4
+ * @LastEditors: colpu ycg520520@qq.com
5
+ * @LastEditTime: 2026-03-01 18:26:02
6
+ * @
7
+ * @Copyright (c) 2025 by colpu, All Rights Reserved.
8
+ */
9
+ import path from "node:path";
10
+ import _ from "lodash";
11
+ import { readFileSync, writeFileSync } from "node:fs";
12
+ import { fileURLToPath } from "node:url";
13
+ import BuiltinModule from "node:module";
14
+ import debugFactory from "debug";
15
+ const debug = debugFactory("@colpu/cli:utils");
16
+ // Guard against poorly mocked module constructors.
17
+ const Module =
18
+ typeof module !== "undefined" && module.constructor.length > 1
19
+ ? module.constructor
20
+ : /* istanbul ignore next */
21
+ BuiltinModule;
22
+
23
+ export const extensions = Module._extensions;
24
+ export const extensionNames = Object.keys(extensions).concat([
25
+ ".cjs",
26
+ ".mjs",
27
+ ".ts",
28
+ ]);
29
+ debug("Module extensions: %j", extensionNames);
30
+
31
+
32
+ /**
33
+ * @function fixFilepath
34
+ * @description 将file://开头的文件路径转换为绝对路径
35
+ * @param {String} filepath
36
+ * @returns {String}
37
+ */
38
+ export function fixFilepath(filepath) {
39
+ if (filepath.startsWith("file://")) {
40
+ filepath = fileURLToPath(filepath);
41
+ }
42
+ return filepath;
43
+ }
44
+
45
+ /**
46
+ * @function loadFile
47
+ * @description: 动态加载文件
48
+ * @param {String} filepath 文件路径必须是绝对路径或者以file:///开头的文件
49
+ * @param {Boolean} importDefaultOnly
50
+ * @return {Promise}
51
+ */
52
+ export async function loadFile(filepath, importDefaultOnly = true) {
53
+ filepath = fixFilepath(filepath);
54
+ try {
55
+ // 如果不是js模块,只返回内容缓冲区
56
+ const extname = path.extname(filepath);
57
+ if (extname && !extensionNames.includes(extname)) {
58
+ return readFileSync(filepath);
59
+ }
60
+ const promise = import(filepath).then((mod) => {
61
+ if (importDefaultOnly) return mod.default;
62
+ return mod;
63
+ });
64
+ return promise;
65
+ } catch (e) {
66
+ if (!(e instanceof Error)) {
67
+ console.trace(e);
68
+ throw e;
69
+ }
70
+ const err = new Error(
71
+ `[@colpu/cli/utils] load file: ${filepath}, error: ${e.message}`
72
+ );
73
+ err.cause = e;
74
+ debug("[loadFile] handle %s error: %s", filepath, e);
75
+ throw err;
76
+ }
77
+ }
78
+
79
+ /**
80
+ * @function readJSONSync
81
+ * @description 同步读取json文件
82
+ * @param {String} filepath
83
+ * @returns {Object}
84
+ */
85
+ export function readJSONSync(filepath) {
86
+ return JSON.parse(readFileSync(fixFilepath(filepath), "utf8"));
87
+ }
88
+
89
+ /**
90
+ * @function writeJSModuleToJSON
91
+ * @description 将js模块写入json文件
92
+ * @param {String} filepath
93
+ * @param {String} writepath
94
+ * @returns
95
+ */
96
+ export async function writeJSModuleToJSON(filepath, writepath) {
97
+ try {
98
+ // 1. 动态导入模块(适用于 ES Modules)
99
+ const module = await import(filepath);
100
+ // 2. 写回文件
101
+ const promise = writeFileSync(
102
+ writepath ? writepath : filepath.replace(".js", ".json"),
103
+ JSON.stringify(module.default, null, 2),
104
+ "utf8",
105
+ );
106
+ console.log("JS 模块写入成功!");
107
+ return promise;
108
+ } catch (err) {
109
+ console.error("出错:", err);
110
+ }
111
+ }
112
+
113
+ /**
114
+ * @function getConfig 获取配置
115
+ * @param {String} root 配置文件目录
116
+ * @param {Object} options 配置选项
117
+ * @param {String} options.env 环境变量,默认为development
118
+ * @param {String} options.dir 配置文件目录,默认为src
119
+ * @returns {Promise<Object>} 配置
120
+ */
121
+ export async function getConfig(root, options = {}) {
122
+ const { env = "development", dir = "src" } = options;
123
+ if (!root) {
124
+ throw new Error("root is required");
125
+ }
126
+ root = fixFilepath(root);
127
+ console.time("加载config时间");
128
+ const pkg = readJSONSync(path.join(root, "package.json"));
129
+ const directory = path.join(root, dir, "config");
130
+ const names = ["index.js", `${env}.js`];
131
+ const config = { root };
132
+ for (const filename of names) {
133
+ const filepath = `${directory}/${filename}`;
134
+ if (filepath) {
135
+ const envConfig = await loadFile(filepath);
136
+ _.merge(config, envConfig);
137
+ }
138
+ }
139
+ debug("loadConfig: %s", directory);
140
+ console.timeEnd("加载config时间");
141
+ return {
142
+ name: pkg.name,
143
+ pkg,
144
+ config,
145
+ env,
146
+ };
147
+ };
package/bin/colpu-cli DELETED
@@ -1,3 +0,0 @@
1
- #! /usr/bin/env node
2
- const Cli = require('../index');
3
- new Cli();
package/command/build.js DELETED
@@ -1,11 +0,0 @@
1
- /**
2
- * @function commond 执行命令方法
3
- * @param {String} env 环境变量
4
- * @param {String} argv bash 参数
5
- * @description 执行打包
6
- */
7
- const build = require(`${process.cwd()}/node_modules/@colpu/build/src/build`);
8
- module.exports = async function commond(env, argv) {
9
- process.env.NODE_ENV = 'production';
10
- await build();
11
- }
package/command/deploy.js DELETED
@@ -1,19 +0,0 @@
1
- const shell = require('shelljs'); // 脚本执行
2
- /**
3
- * @function commond 执行命令方法
4
- * @param {String} env 环境变量
5
- * @param {String} argv bash 参数
6
- * @description 本地开发
7
- */
8
- module.exports = async function commond(env, argv) {
9
- process.env.NODE_ENV = env;
10
- if (!shell.which('pm2')) {
11
- // 在控制台输出内容
12
- shell.echo('抱歉没有安装pm2');
13
- shell.exit(1);
14
- } else {
15
- const bash = `pm2 deploy launched.config.js ${env} ${argv}`;
16
- shell.echo(bash);
17
- shell.exec(bash);
18
- }
19
- }
package/command/dev.js DELETED
@@ -1,10 +0,0 @@
1
- /**
2
- * @function commond 执行命令方法
3
- * @param {String} env 环境变量
4
- * @param {String} argv bash 参数
5
- * @description 本地开发
6
- */
7
- module.exports = async function commond(env, argv) {
8
- process.env.NODE_ENV = 'development';
9
- require(`${process.cwd()}/node_modules/@colpu/build`)();
10
- }
package/command/help.js DELETED
@@ -1,28 +0,0 @@
1
- /**
2
- * @description help命令提示
3
- * @cmd npm run help
4
- */
5
-
6
- const Table = require('table');
7
-
8
- module.exports = async () => {
9
- const data = [
10
- ['命令', '可选参数', '说明'],
11
- ['colpu-cli help', '-', '命令帮助'],
12
- ['colpu-cli start', '-', '本地开发【快捷命令】'],
13
- ['colpu-cli dev', '-', '本地开发'],
14
- ['colpu-cli inspect', '-', '开发调试'],
15
- ['colpu-cli build', '-', '发布构建'],
16
- ['colpu-cli service', 'local,preview,release,production', '启动node服务'],
17
- ['colpu-cli daemon', 'local,preview,release,production', '启动守护进程,当前为pm2守护进程'],
18
- ['colpu-cli deploy', 'local,preview,release,production', '启动pm2发布环境'],
19
- ['colpu-cli shipit', 'local,preview,release,production', '启动shipit发布环境'],
20
- ['colpu-cli create', '你需要创建的目录', '下载模板'],
21
- ];
22
-
23
- const config = {
24
- border: Table.getBorderCharacters('norc')
25
- };
26
- const output = Table.table(data, config);
27
- console.log(output);
28
- }
package/command/init.js DELETED
@@ -1,96 +0,0 @@
1
- const inquirer = require('inquirer');
2
- const spinner = require('ora')(); // 终端旋转器,loading颜色变化
3
- const chalk = require('chalk'); // 终端字符串样式模块
4
- const shell = require('shelljs'); // 脚本执行
5
- const CWD = process.cwd();
6
- /**
7
- * @function commond 执行命令方法
8
- * @param {String} env 环境变量
9
- * @param {String} argv bash 参数
10
- * @description 用于克隆初始化项目( 待完成)
11
- */
12
- const fs = require('fs');
13
- module.exports = async function commond(env, argv) {
14
- const promptList = [{
15
- type: "input",
16
- message: "请输入项目名称:",
17
- suffix: '***推荐使用英文和下划线进行命名***',
18
- name: "name",
19
- }, {
20
- type: "input",
21
- message: "版本",
22
- name: "version"
23
- }, {
24
- type: "input",
25
- message: "描述",
26
- name: "description"
27
- }, {
28
- type: "input",
29
- message: "仓库地址",
30
- name: "repository"
31
- }, {
32
- type: "input",
33
- message: "作者",
34
- name: "author"
35
- }, {
36
- type: "input",
37
- message: "许可协议",
38
- name: "license"
39
- }, {
40
- type: "input",
41
- message: "端口",
42
- name: "port"
43
- }];
44
- const branchs = ['master', 'api'];
45
- const answers = await inquirer.prompt(promptList);
46
- const answersConfig = defaultConfig(answers);
47
- const repo = 'https://gitee.com/ycg520520/colpu-example.git'; // git仓库地址
48
- spinner.start(`正在下载项目 (${repo})...`);
49
- if (!shell.which('git')) {
50
- // 在控制台输出内容
51
- shell.echo('抱歉没有安装git');
52
- shell.exit(1);
53
- } else {
54
- let branch = argv.split(' ')[1];
55
- branch = (branchs.indexOf(branch) > -1 ? branch : '');
56
- shell.exec(`git clone ${branch?`-b ${branch} `:''}${repo} ${answersConfig.name}`, err => {
57
- if (err) {
58
- console.error(err);
59
- process.exit();
60
- }
61
- spinner.succeed(chalk.green('模板克隆成功^_^。'));
62
- // 初始化项目
63
- spinner.stop();
64
- spinner.info(chalk.green(`正在初始化项目: ${answersConfig.name}`));
65
- const packagePath = `${CWD}/${answersConfig.name}/package.json`
66
- const configPath = `${CWD}/${answersConfig.name}/src/config/index.js`
67
- const package = require(packagePath);
68
- const config = require(configPath);
69
- Object.assign(package, answersConfig)
70
- package.repository.url = config.repository;
71
- config.port = config.port;
72
- fs.writeFileSync(packagePath, JSON.stringify(package, null, '\t'));
73
- let configStr = `module.exports = `;
74
- configStr += JSON.stringify(config, null, '\t');
75
- configStr = configStr.replace(/"([a-zA-Z0-9_]+)":/gi, '$1:')
76
- fs.writeFileSync(configPath, configStr);
77
- spinner.succeed(chalk.green(`初始化项目 ${answersConfig.name} 成功`));
78
- })
79
- }
80
- }
81
-
82
- function defaultConfig(data) {
83
- const DEFAULT = {
84
- name: 'example',
85
- version: '1.0.0',
86
- description: '您什么都没留下~',
87
- license: 'ISC',
88
- port: 3000
89
- }
90
- for (let key in data) {
91
- if (!data[key]) {
92
- delete data[key]
93
- }
94
- }
95
- return Object.assign(DEFAULT, data);
96
- }
@@ -1,15 +0,0 @@
1
- const shell = require('shelljs'); // 脚本执行
2
-
3
- /**
4
- * @function commond 执行命令方法
5
- * @param {String} env 环境变量
6
- * @param {String} argv bash 参数
7
- * @description 本地开发
8
- */
9
-
10
- module.exports = async function commond(env, argv) {
11
- process.env.NODE_ENV = env;
12
- const bash = `NODE_ENV=${env} node --inspect-brk ./node_modules/@colpu/cli/script/service.js`
13
- shell.echo(bash);
14
- shell.exec(bash);
15
- }
@@ -1,10 +0,0 @@
1
- /**
2
- * @function commond 执行命令方法
3
- * @param {String} env 环境变量
4
- * @param {String} argv bash 参数
5
- * @description 用于启动服务
6
- */
7
- module.exports = function commond(env, argv) {
8
- process.env.NODE_ENV = env || 'production';
9
- require('../script/service');
10
- }
package/command/shipit.js DELETED
@@ -1,14 +0,0 @@
1
- const shell = require('shelljs'); // 脚本执行
2
- const _ = require('lodash');
3
- /**
4
- @description 发布命令
5
- @cmd npm run shipit
6
- */
7
- module.exports = async function commond(env, argv) {
8
- process.env.NODE_ENV = env;
9
- const otherArgv = argv.split(' ').splice(2);
10
- const defaultShift = '--shipitfile ./node_modules/@colpu/cli/config/shipit.js';
11
- const bash = `shipit ${env} deploy ${otherArgv.length > 0 ? otherArgv.join(' ') : defaultShift}`;
12
- shell.echo(bash);
13
- shell.exec(bash);
14
- };
package/config/index.js DELETED
@@ -1,28 +0,0 @@
1
- const path = require('path');
2
- const fs = require('fs');
3
- const _ = require('lodash');
4
- const debug = require('debug')('cli:config');
5
- const util = require('../util');
6
- const defaultENV = process.env.NODE_ENV || 'development';
7
- module.exports = (root, dir = 'src', env = defaultENV) => {
8
- console.time('加载config时间');
9
- const pkg = JSON.parse(fs.readFileSync(path.join(root, 'package.json')));
10
- const directory = path.join(root, dir, 'config');
11
- const names = ['index', env];
12
- const config = { root }
13
- for (const filename of names) {
14
- const filepath = util.resolveModule(`${directory}/${filename}`);
15
- if (filepath) {
16
- const envConfig = require(filepath);
17
- _.merge(config, envConfig);
18
- }
19
- }
20
- debug('loadConfig: %s', directory);
21
- console.timeEnd('加载config时间');
22
- return {
23
- name: pkg.name,
24
- pkg,
25
- config,
26
- env
27
- }
28
- };
package/config/shipit.js DELETED
@@ -1,97 +0,0 @@
1
- const Server = require(`${process.cwd()}/node_modules/@colpu/core`);
2
- const argv = process.argv;
3
- const env = argv[2];
4
- const {
5
- name,
6
- config = {},
7
- pkg = {}
8
- } = new Server({
9
- env
10
- });
11
- const WORKSPACE = `/data/tmp/${name}`; // 本地构建临时目录
12
- const PRODUCTION_DIR = `/data/project/${name}`; // 服务器 预发布/生产目录
13
- const TEST_DIR = `/DataSSD/${name}`; // 服务器 local目录
14
- const commonBash = [
15
- 'pm2 save'
16
- ];
17
- console.log(config)
18
- // 构建环境变量
19
- const enumEnv = {
20
- local: 'local',
21
- preview: 'preview',
22
- production: 'production'
23
- };
24
-
25
- module.exports = function (shipit) {
26
- require('shipit-deploy')(shipit);
27
- const branch = config.deploy.branch || 'master';
28
- shipit.initConfig({
29
- production: {
30
- servers: config.deploy.servers,
31
- deployTo: WORKSPACE,
32
- branch
33
- },
34
- preview: {
35
- servers: config.deploy.servers,
36
- deployTo: WORKSPACE,
37
- branch
38
- },
39
- local: {
40
- servers: config.deploy.servers,
41
- deployTo: WORKSPACE,
42
- branch
43
- },
44
- default: {
45
- workspace: WORKSPACE, // 本地的临时工作目录
46
- repositoryUrl: pkg.repository.url,
47
- ignores: ['.git', 'node_modules'],
48
- keepReleases: 2,
49
- shallowClone: false,
50
- deleteOnRollback: false
51
- }
52
- });
53
-
54
- // 1、创建本地临时目录
55
- shipit.on('init', () => {
56
- return shipit.local(`mkdir -p ${WORKSPACE}`);
57
- });
58
-
59
- // 2、仓库拉取完成,执行代码构建和资源发布(上传阿里oss)
60
- shipit.on('fetched', function () {
61
- shipit.start(['build']);
62
- });
63
-
64
- // 3、发布完成,执行构建pm2服务启动
65
- shipit.on('published', function () {
66
- const env = shipit.options.environment;
67
- const options = {
68
- workspace: WORKSPACE,
69
- dir: env === enumEnv.local ? TEST_DIR : PRODUCTION_DIR,
70
- env
71
- };
72
- const command = generateRemoteCmd(options);
73
- return shipit.remote(command);
74
- });
75
-
76
- // 自定义事件进行项目build
77
- shipit.blTask('build', function () {
78
- const command = [
79
- `cd ${WORKSPACE}`,
80
- `yarn install --no-lockfile`
81
- ].join(' && ');
82
- return shipit.local(command);
83
- });
84
- };
85
-
86
- // cmd远程命令生成
87
- function generateRemoteCmd(options) {
88
- const { workspace, dir, env } = options;
89
- return [
90
- `mkdir -p ${dir}`,
91
- `cp -rf ${workspace}/current/. ${dir}`,
92
- `cd ${dir}`,
93
- `yarn install --no-lockfile --production`,
94
- `(pm2 delete ${name} || echo)`,
95
- `npm run ${env}`
96
- ].concat(commonBash).filter((cmd) => cmd).join(' && ');
97
- }
package/index.js DELETED
@@ -1,82 +0,0 @@
1
- #! /usr/bin/env node
2
-
3
- /**
4
- * @description 构建、开发命令入口
5
- * @cmd npm run xxx
6
- * dev | build | production
7
- * 本地开发 | 发布打包 | 运行生成环境
8
- */
9
- const inquirer = require('inquirer');
10
- const shell = require('shelljs'); // 脚本执行
11
- module.exports = class Cli {
12
- constructor(options) {
13
- const DEFAULT = {
14
- modes: ['deploy', 'service', 'daemon', 'shipit'], // 构建模式
15
- env_config: {
16
- local: '局域网环境(local)',
17
- preview: '测试环境(preview)',
18
- release: '预发布环境(release)',
19
- production: '正式环境(production)',
20
- exit: '退出',
21
- } //环境配置
22
- }
23
- this.options = Object.assign(DEFAULT, options);
24
- const ENV_CONFIG = this.options.env_config;
25
- this.choices = Object.values(ENV_CONFIG);
26
- this.envs = Object.keys(ENV_CONFIG);
27
- this.argv = process.argv.slice(2); // 获取命令行参数
28
- this.init();
29
- }
30
-
31
- async init() {
32
- const _this = this;
33
- const argv = _this.argv;
34
- const modes = _this.options.modes;
35
- const envs = _this.envs;
36
- const command = argv[0]; // 主命令
37
- let env = argv[1]; // 环境命令
38
-
39
- // 如果需要选择环境,同时环境命令不在指定范围的,需要提示并将选择好环境变量装入到对应位置
40
- const isSelectENV = envs.indexOf(env) === -1 && modes.includes(command);
41
- if (isSelectENV) {
42
- env = await _this.exactInquirer();
43
- if (env === 'exit') {
44
- shell.exit();
45
- }
46
- argv.splice(1, 0, env); // 将环境变量装入
47
- }
48
-
49
- const envIndex = argv.indexOf(env); // 环境变量在argv的位置
50
- if (envIndex > -1 && isSelectENV) {
51
- argv.splice(0, envIndex + 1)
52
- }
53
- // 规范开发环境变量,非指定envs变量都为development
54
- if (envs.indexOf(env) === -1) {
55
- env = 'development'
56
- }
57
- await _this.loadCommand(command, env, argv);
58
- }
59
- async loadCommand(command, env = 'development', argv = []) {
60
- await require(`./command/${command}`)(env, argv.join(' '));
61
- }
62
-
63
-
64
- /**
65
- * @function exactInquirer 执行用户交互提示
66
- * @description 当用户输入的命令不环境不完全时,进行提示
67
- * @return {String} 环境参数
68
- */
69
- async exactInquirer() {
70
- const choices = this.choices;
71
- const promptList = [{
72
- type: 'rawlist',
73
- message: '靠谱少年,请选择需要的执行环境: ',
74
- name: 'mode',
75
- choices
76
- }];
77
- const {
78
- mode
79
- } = await inquirer.prompt(promptList);
80
- return this.envs[choices.indexOf(mode)];
81
- }
82
- }
package/script/service.js DELETED
@@ -1,3 +0,0 @@
1
- const Server = require('@colpu/core');
2
- const app = new Server();
3
- app.start();
package/util/index.js DELETED
@@ -1,11 +0,0 @@
1
- module.exports = {
2
- resolveModule(filepath) {
3
- let fullpath;
4
- try {
5
- fullpath = require.resolve(filepath);
6
- } catch (err) {
7
- return undefined;
8
- }
9
- return fullpath;
10
- }
11
- }