一、项目概述
最近在学习Node相关的东西,根据视频中的内容写出了一个自定义 CLI 工具,主要用于快速生成 Vue 项目骨架及相关组件(如页面、路由、Store 等),简化 Vue 项目的初始化和开发流程。通过命令行指令,可快速克隆项目模板、创建组件、页面+路由配置、Store 配置等。
二、项目结构
python
02.LEARN_CLI/
├── index.js # CLI 入口文件
├── package.json # 项目配置(依赖、入口指令等)
├── lib/
│ ├── core/
│ │ ├── actions.js # 核心动作实现(创建项目、组件等逻辑)
│ │ ├── create.js # 命令定义(注册 CLI 指令)
│ │ ├── help.js # 帮助信息配置
│ ├── config/
│ │ ├── repo-config.js # 项目模板仓库配置
│ ├── utils/
│ │ ├── terminal.js # 终端命令执行工具
│ │ ├── utils.js # 通用工具(模板编译、文件操作等)
三、核心文件解析
1. 入口文件:index.js
- 作用:CLI 工具的入口,初始化命令行解析器并加载配置
- 核心逻辑:
-
- 引入
commander库处理命令行指令 - 注册版本号(从
package.json读取) - 加载帮助信息(
helpOptions)和自定义命令(createCommands) - 解析进程参数(
process.argv)
- 引入
javascript
#!/usr/bin/env node
const program = require("commander");
const helpOptions = require("./lib/core/help");
const createCommands = require("./lib/core/create");
program.version(require("./package.json").version); // 注册版本号
helpOptions(); // 加载帮助选项
createCommands(); // 注册自定义命令
program.parse(process.argv); // 解析命令行参数
2. 命令定义:lib/core/create.js
- 作用:定义 CLI 支持的所有指令,并关联对应的执行逻辑(actions)
- 支持的命令:
-
create <project>:创建项目addcpn <name>:添加 Vue 组件addpage <page>:添加 Vue 页面及路由配置addstore <store>:添加 Vue Store 配置
scss
// 示例:create 命令定义
program
.command("create <project> [others...]")
.description("clone repository into a folder")
.action(createProjectAction); // 关联到 actions 中的创建项目逻辑
3. 核心动作:lib/core/actions.js
- 作用:实现各命令的具体逻辑(如克隆仓库、生成文件等)
- 主要动作:
(1)createProjectAction:创建项目
- 流程:
-
- 从配置的仓库(
vueRepo)克隆项目模板 - 自动执行
npm install安装依赖 - 执行
npm run serve启动项目 - 自动打开浏览器访问
http://localhost:8080/
- 从配置的仓库(
javascript
const createProjectAction = async (project) => {
await download(vueRepo, project, { clone: true }); // 克隆仓库
const command = process.platform === "win32" ? "npm.cmd" : "npm";
await commandSpawn(command, ["install"], { cwd: `./${project}` }); // 安装依赖
commandSpawn(command, ["run", "serve"], { cwd: `./${project}` }); // 启动项目
open("http://localhost:8080/"); // 打开浏览器
};
(2)addComponentAction:添加 Vue 组件
- 流程:
-
- 使用 EJS 编译
vue-component.ejs模板(传入组件名及小写组件名) - 将编译结果写入指定目录(默认
src/components)的.vue文件
- 使用 EJS 编译
ini
const addComponentAction = async (name, dest) => {
const result = await compile("vue-component.ejs", { name, lowerName: name.toLowerCase() });
const targetPath = path.resolve(dest, `${name}.vue`);
writeToFile(targetPath, result); // 写入文件
};
(3)addPageAndRouteAction:添加页面及路由
- 流程:
-
- 编译
vue-component.ejs(页面模板)和vue-router.ejs(路由模板) - 创建以页面名为目录的文件夹
- 写入页面文件(
.vue)和路由配置文件(router.js)
- 编译
(4)addStoreAction:添加 Store 配置
- 流程:
-
- 编译
vue-store.ejs(Store 模板)和vue-types.ejs(类型定义模板) - 创建以 Store 名为目录的文件夹
- 写入 Store 文件(
.js)和类型定义文件(types.js)
- 编译
4. 配置文件:lib/config/repo-config.js
- 作用:存储项目模板仓库地址,供
createProjectAction克隆使用 - 示例:
ini
const vueRepo = 'direct:https://gitee.com/leilei521/hy-vue-temp.git'; // Vue 项目模板仓库
module.exports = { vueRepo };
5. 工具函数
(1)lib/utils/terminal.js:终端命令执行
- 封装
child_process.spawn为 Promise 形式,方便异步执行终端命令(如npm install) - 核心函数
commandSpawn:将子进程的输出(stdout/stderr)管道到主进程,并在命令完成后 resolve
javascript
const commandSpawn = (...args) => {
return new Promise((resolve) => {
const childProcess = spawn(...args);
childProcess.stdout.pipe(process.stdout); // 输出子进程日志
childProcess.on("close", () => resolve()); // 命令完成后 resolve
});
};
(2)lib/utils/utils.js:通用工具
compile:使用 EJS 编译模板文件(从templates目录读取)createDirSync:递归创建目录(若父目录不存在则自动创建)writeToFile:将内容写入文件(基于 Promise 的异步操作)
6. 帮助配置:lib/core/help.js
- 作用:定义 CLI 的帮助选项和额外说明
- 自定义选项:
-
-l --llg:自定义标识-d --dest <dest>:指定目标目录(如组件/页面的生成路径)-f --framework <framework>:指定框架
- 额外帮助信息:通过
program.on("--help")添加补充说明
四、依赖说明(package.json)
commander:命令行解析库,用于定义和处理 CLI 指令download-git-repo:克隆 Git 仓库(用于拉取项目模板)ejs:模板引擎,用于编译组件/页面/路由等模板文件open:自动打开浏览器(项目启动后访问本地服务)- 可执行指令:通过
bin字段配置llg为入口指令,即全局安装后可直接通过llg命令调用
五、使用示例
- 创建项目:
perl
llg create my-vue-project # 克隆模板、安装依赖、启动项目并打开浏览器
- 添加组件:
css
llg addcpn Button -d src/components # 在 src/components 生成 Button.vue
- 添加页面及路由:
bash
llg addpage Home -d src/views # 在 src/views/Home 生成 Home.vue 和 router.js
- 添加 Store:
bash
llg addstore user -d src/store # 在 src/store/user 生成 user.js 和 types.js
- 查看帮助:
bash
llg --help # 查看所有命令和选项说明
六、核心技术点
- 命令行交互 :基于
commander实现指令定义和参数解析 - 异步流程控制 :使用
async/await处理克隆仓库、安装依赖等异步操作 - 模板引擎 :通过
ejs动态生成组件/页面/配置文件 - 终端命令执行 :封装
child_process.spawn执行 npm 命令 - 文件操作:递归创建目录、写入文件等文件系统操作
总结
该 CLI 工具通过封装常用的 Vue 项目开发流程(初始化、组件创建、路由配置等),提高了开发效率。核心逻辑是将重复的手动操作(如克隆模板、编写基础组件代码)通过命令行自动化,同时支持自定义路径,灵活适配不同项目结构。