创建自己的脚手架
脚手架基本框架
使用pnpm init 创建环境
取一个自己喜欢的名字 这里叫gucli
生成 package.json文件的内容
{
"name": "gucli",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
新建lib文件夹 lib文件夹下新建index.js入口文件
写入主要程序
注意:第一行是固定的 自动调用node运行文件
#!/usr/bin/env node
console.log("gu cli code");
在package.json中设置bin 是一个对象类型 键名就是脚手架的名字 键值是入口文件路径
{
"name": "gucli",
"version": "1.0.0",
"description": "",
"main": "index.js",
"bin":{
"gucli":"./lib/index.js"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
终端中建立软连接 npm link
此时就可以使用自己创建的脚手架了
目前文件目录
添加查看版本功能
安装commander
pnpm add commander
修改index.js文件
#!/usr/bin/env node
const { program } = require("commander");
//处理-v --version操作
const version = require('../package.json').version
program.version(version, "-v --version");
//让commander解析process.argv参数
program.parse(process.argv);
此时终端就可以使用-v 与–version查看版本
增加options选项
使用program.option添加其他的选项 第一个参数是 选项的名称 第二个参数是–help时的描述
可以在第一个参数中填上<> 代表额外参数
program自带–help选项 我们也可以对其进行补充
使用program.on对–help选项进行补充说明
为了方便 把所有的选项抽出来一个新的文件help-options,js
具体实例如下
help-options,js
const { program } = require("commander");
function helpOptions() {
//处理--version操作
const version = require("../../package.json").version;
program.version(version, "-v --version");
//增加其他option操作
program.option("-w", "描述");
program.option("-d --dest <dest>", "a destination folder,例如 -d src/components");
program.on("--help", () => {
console.log("");
console.log("others:");
console.log(" xxx");
console.log(" yyy");
});
}
module.exports = helpOptions;
index.js
program.opts().dest可以获取额外传递的参数
#!/usr/bin/env node
const { program } = require("commander");
const helpOptions = require("./core/help-options");
//1.配置所有的options
helpOptions()
//让commander解析process.argv参数
program.parse(process.argv);
//获取额外传递的参数
console.log(program.opts().dest);
增加create功能 创建vue项目模板
使用program.command 创建功能
program.description 功能描述
program.action 功能的具体行为
#!/usr/bin/env node
const { program } = require("commander");
const helpOptions = require("./core/help-options");
//1.配置所有的options
helpOptions();
//2.增加具体的一些功能
program
.command("create <project> [...others]")
.description("Create vue project into a folder 比如gucli create xxxx")
.action(function (project) {
// 具体实施行为
console.log("创建出来一个项目:", project);
});
//让commander解析process.argv参数
program.parse(process.argv);
//获取额外传递的参数
console.log(program.opts().dest);
对其进行改进 使其可以进行创建vue项目模板
下载download-git-repo包 可以从github上克隆文件
pnpm add download-git-repo
抽出actions.js文件
//promisify将普通函数转换为promise形式
const { promisify } = require("util");
const download = promisify(require("download-git-repo"));
const { VUE_REPO } = require("../config/repo");
async function createProjectAction(project) {
try {
await download(VUE_REPO, project, { clone: true })
} catch (error) {
console.log('github连接失败')
}
}
module.exports = {
createProjectAction,
};
新建常量repo.js
const VUE_REPO = "direct:项目模板的路径";
module.exports = {
VUE_REPO,
};
#!/usr/bin/env node
const { program } = require("commander");
const helpOptions = require("./core/help-options");
//1.配置所有的options
helpOptions();
//2.增加具体的一些功能
program
.command("create <project> [...others]")
.description("Create vue project into a folder 比如gucli create xxxx")
.action(createProjectAction);
//让commander解析process.argv参数
program.parse(process.argv);
//获取额外传递的参数
console.log(program.opts().dest);
脚手架执行安装与运行命令
exec-command.js
pnpm add child_process
const { spawn } = require("child_process");
function execCommand(...args) {
return new Promise((resolve) => {
//npm install/npm run dev
//开启子进程执行命令
const childProcess = spawn(...args);
//获取子进程的输出和错误信息
childProcess.stdout.pipe(process.stdout);
childProcess.stderr.pipe(process.stderr);
//监听子进程执行结果 关闭
childProcess.on("close", () => {
resolve()
});
});
}
module.exports = execCommand;
actions.js
pnpm add download-git-repo
//promisify将普通函数转换为promise形式
const { promisify } = require("util");
const download = promisify(require("download-git-repo"));
const { VUE_REPO } = require("../config/repo");
const execCommand = require("../utils/exec-command");
async function createProjectAction(project) {
try {
await download(VUE_REPO, project, { clone: true });
//很多的脚手架 都是在这里提示
//帮助执行npm install
const commandName = process.platform === "win32" ? "npm.cmd" : "npm";
await execCommand(commandName, ["install"], { cwd: `./${project}` });
//帮助执行npm run dev
await execCommand(commandName, ["run", "dev"], { cwd: `./${project}` });
} catch (error) {
console.log("github连接失败");
}
}
module.exports = {
createProjectAction,
};