最近突然想做一套脚手架和配套工具,想想能直接一个命令配置出自己的代码初始化,多帅哦。 首先看下我们需要什么工具库,下面是比较基本的一些:
"chalk": "4.1.2", // 控制console的样式颜色
"commander": "^4.0.1", // 设置一些node命令,如包的help、usage、version、parse输入的参数
"download-git-repo": "^3.0.2", // 下载git上的模板,并存到本地
"inquirer": "^8.2.0", // 类似于promt,产生命令交互,获得输入结果
"ora": "5.4.1", // 产生loading的图标
"open": "^8.4.0", // 打开浏览器
"clear": "^0.1.0", // 清空输出
"rimraf": "^3.0.2" // 删除文件功能
细心的朋友应该已经发现了,chalk和ora这里的版本有些控制,这是因为他们的最新版本都已经转成了esm,在node中不太好使用,但是也是可以的,类似的方法有比较多,如加babel等,不建议因为这两个esm而改动整个文件的性质或者整个项目的性质。目前为了保持统一的个性,我还是决定直接先回退版本。
首先我们看下目录结构
上面的template是本地文件,但是现在大部分人会把架构放在git上,看自己喜欢把。
开始配置。
在一个空目录下执行 npm init,然后生成package.json,按照我们上面要的依赖装上。
这时候,我更建议大家先直接link起来(就npm link或者yarn link就完事了),因为带着调试进行开发,体验上会比较好,而且会有些成就感(个人而言),这样就激发了动力。
然后我们需要在package.json中配置一个命令入口"bin"
"bin": {
"tolin-cli": "./bin/tolin-cli" // 执行路径,不一定非要在bin下面,但是大多数开发者是这样的,语义也畅通
}
然后在我们这边当然是按照我们配置的路径创建好文件夹和文件了,下面是文件例子: (之后的一些工具库的使用文档基本都在npm找对应包就能找得到)
#! /usr/bin/env node
// 注意这个必不可少,告诉系统我们需要node的执行环境
const path = require("path");
const program = require("commander");
program.version(require("../package.json").version);
const p = path.resolve(__dirname, `../lib`); // 获取到相对应的模板路径
const gen = require(p + "/gen");
program.command("gen").description("新建一个项目吧").action(gen);
if (!process.argv[2]) {
program.help()
}
program.parse(process.argv);
下面是lib下gen.js
#! /usr/bin/env node
// 生成模板的地方
const clear = require("clear");
const questions = [
{
type: "input",
name: "appName",
message: "输入您的项目名",
validate: (v) => v && typeof v === "string",
},
{
type: "checkbox",
name: "plugins",
message: "看看下面哪些你需要集成",
choices: [
{ value: "react-router", name: "react-router" },
{ value: "redux", name: "redux" },
],
},
{
type: "list",
name: "reduxType",
message: "你想要的redux方案",
when: (v) => v.plugins.includes("redux"),
choices: [
{ value: "dva", name: "dva" },
{ value: "rematch", name: "rematch+redux" },
],
},
{
type: "confirm",
name: "confirm",
message: "这些信息ok吗",
default: false,
validate: (v) => !!v,
transformer: (v) => {
console.log("v", v);
},
},
];
/**
* 生成方法
*/
const genFunction = () => {
clear();
const inquirer = require("inquirer");
inquirer.prompt(questions).then((res) => {
console.log("res", res);
const download = require("./download");
download(res);
});
};
module.exports = genFunction;
lib下download
#! /usr/bin/env node
const download = async (obj) => {
const dl = require("download-git-repo");
const ora = require("ora");
const process = ora(`正在下载....`);
process.start();
dl(
"direct:https://github.com/lmhtolin/tolin-cli-template.git",
"/lib",
{},// 注意这个配置,如果一直出现timeout问题的话,可以加上clone: true试试
(err) => {
console.log("err", err);
process.succeed();
}
);
};
module.exports = download;
好了,基本完成了,比较粗略,后续改版更新上去 最后贴上完整的package.json文件
{
"name": "tolin-cli",
"version": "1.0.1",
"description": "react-cli工具",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"bin": {
"tolin-cli": "./bin/tolin-cli.js"
},
"keywords": [
"react",
"react-cli",
"tolin-cli",
"react 项目初始化工具"
],
"directories": {
"lib": "lib"
},
"author": "lmh",
"license": "MIT",
"dependencies": {
"chalk": "4.1.2",
"clear": "^0.1.0",
"commander": "^4.0.1",
"download-git-repo": "^3.0.2",
"inquirer": "^8.2.0",
"open": "^8.4.0",
"ora": "5.4.1",
"rimraf": "^3.0.2"
},
"devDependencies": {
"eslint": "^6.8.0",
"eslint-config-standard": "^14.1.0",
"eslint-plugin-import": "^2.19.1",
"eslint-plugin-node": "^11.0.0",
"eslint-plugin-promise": "^4.2.1",
"eslint-plugin-standard": "^4.0.1"
}
}