自定义脚手架工具解决问题
- 1.可以自定义需要导入的文件;
- 2.自定义框架选择;
- 3.减少自己的一些重复性的工作。
脚手架的整体流程
- 1.根据用户输入来生成不同的框架配置文件;
- 2.下载指定后的模板;
- 3.根据用户信息的不同,生成不同package.json;
- 4.生成新的工程文件。
脚手架需要用到的依赖
- 1.commander:参数解析工具。用它来读取用户输入的数据,并且根据用户输入的数据来进行一定的操作。
- 2.inquirer:交互式的命令行工具。用它通过选择、读取、判断的方式读取用户的数据。
- 3.download-git-repo:下载远程模板的工具。用它来下载在git上配置好的模板。
- 4.ora:用户显示加载中的效果。显示一个loading的效果,提升用户交互友好度。
- 5.chalk:将console.log打印的内容颜色进行修改。
开发步骤
一、初始化
-
1.创建项目文件夹;
-
2.npm init –y初始化项目;
-
3.创建入口文件;
-
4.并在package.json中追加’bin’的链接的入口文件地址;
-
5.用npm link链接到全局。
package.json
{
"name": "wangjian-cli",
"version": "2.0.0",
"description": "",
"main": "index.js",
"bin": {
"wangjian-cli": "./bin/app.js"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"axios": "^0.21.1",
"chalk": "^4.1.2",
"commander": "^8.1.0",
"download-git-repo": "^3.0.2",
"inquirer": "^8.1.2",
"ora": "^5.4.1"
},
"devDependencies": {
"eslint": "^7.32.0"
}
}
#! /usr/bin/env node //告诉该脚本由node来执行
// 该文件作为cli的入口文件
require('../src/main.js');
二、使用commander处理参数
- 1.npm install commander;
- 2.const program=require(‘commander’)
program
.command(action) // 配置命令的名字
.alias(alias) // 配置命令的简写
.description(description) //配置命令的描述
.action(() => {
if (action === '*') return console.log(chalk.red(description));
const param = process.argv.slice(3);
require(`./command/${action}`)(...param);
});
三、在git上创建模板仓库
- 1.可以在git上建立组织,然后只下载这个组织内的模板;
- 2.在cli create的时候,遍历这个组织的仓库以及tags,用inquirer 进行命令行问答,达到一种动态配置的效果。
// 获取项目列表
const getRepoList = async () => {
const { data } = await axios.get('https://api.github.com/orgs/wangjian-cli/repos');
const resultArr = data.map(item => item.name);
return resultArr;
};
// 获取版本号
const getTagList = async repo => {
const { data } = await axios.get(`https://api.github.com/repos/wangjian-cli/${repo}/tags`);
const resultArr = data.map(item => item.name);
return resultArr;
};
四、使用download-git-repo从git上下载模板
- 1.npm install download-git-repo ;
- 2.const downloadGitRepo=require(‘download-git-repo’)
// download-git-repo下载模板
const download = async (repo, tag, projectName) => {
let api = `wangjian-cli/${repo}/`;
if (tag) api += `#${tag}`;
// process.cwd()代表下载到当前打开的node的这个文件夹
const dest = path.resolve(process.cwd(), projectName);
await downloadGitRepo(api, dest);
};
- 3.tips:download-git-repo不是promise对象,可以用util来对异步promise化,然后就可以愉快的使用async、await了
const { promisify } = require('util');
let downloadGitRepo = require('download-git-repo');
// 转为promise对象
downloadGitRepo = promisify(downloadGitRepo);
五、收集用户数据,生成package.json
const path = require('path');
const tools = require('./tools.js');
const fs = require('fs');
const { setChoices } = tools;
const setObj = async (param, projectName) => {
const optionObj = {
version: '1.0.0',
name: projectName,
};
const defaultVal = optionObj[param] || '';
const tempObj = {
type: 'input',
name: param,
message: param,
default: defaultVal,
};
const tempResult = await setChoices(tempObj);
return tempResult;
};
const result = async projectName => {
const file = path.resolve(process.cwd(), projectName + '/package.json');
let data = fs.readFileSync(file, 'utf-8');
const dataObj = JSON.parse(data);
dataObj.version = await setObj('version');
dataObj.author = await setObj('author');
dataObj.name = await setObj('name', projectName);
data = JSON.stringify(dataObj);
fs.writeFileSync(file, data);
};
module.exports = result;
六、发布到npm库
- 1.完成之后,npm login登录npm;
- 2.npm publish发布到npm库。
- 注意:
- 1.发布前查是否已存在同名包;
- 2.有淘宝镜像的切换回官方。
- 3.每回发布需要更改version
- tips:
- 可以下载nrm来管理自己的npm源