简介
前端有各种各样的脚手架工具, 比如我们常用的vue-cli, create-react-app等工具. 为我们前端早期工程的开发, 带来极大的便利.
这么便利的node cli, 是不是特别想知道是如何开发的? 接下来, 为大家介绍一下怎样开发一个脚手架工具.
课程计划
本系列, 将分为三节: 上中下
- (上):主要介绍开发Node工具, 需要常用的工具库.
- (中):手把手开发一个Node工具, 实现的功能是: 类似create-react-app, 通过这个工具, 可以创建基本的react编程结构.
- (下): 如何发布自己的私包到npmjs上.
现在开始第一节内容的介绍.
常见的一个cli工具, 一般会实现什么功能呢? 看看我们属性的命令: 我们以npm init, npm install为例:
- init是一条命令. 用来创建一个package.json文件.
- init命令执行后, 要你输入一些配置比如: "package name:", "author"等信息.
- 最后还有一个确认的信息: "Is this OK(yes)"
- 另外我也可以加一些参数, 比如npm init -y, 这样创建过程就使用默认配置.
- 使用npm install来安装包时, 也可以看到进度条和简单的loading动画
- 最后能看到控制台里部分信息是高亮显示, 比如红色, 绿色, 加粗等.
现在我们一一介绍, 要实现这些功能. 我们可用的武器有哪些?
常见的工具库
- commander
- inquirer
- ora
- chalk
- which
commander
是一个工具包,其作用是让node命令行程序的制作更加简单,封装后的node命令行接口, 简单易用.
安装:
npm install commander -D
输入-v或--version时, 显示cli的版本好.
const program = require('commander');
// 处理-v, --version时的输出.
program.version(require('../package.json').version, '-v, --version');
// 解析输入参数. 记得放在最后即可.
program.parse(process.argv);
创建一条命令
- 命令为: create
- 描述为: Create a new project.
- 支持一个参数name, 表示项目名称.
const program = require('commander');
program
.version(require('../package.json').version, '-v, --version')
.command('create <name>')
.description('Create a new project')
.action(name => {
console.log(name);
})
program.parse(process.argv);
当执行create命令后, 没有提供参数时, 会提示缺少参数name. 提供后, 控制台就输出我们提供的name值.
inquirer
使用它很容易的完成用户和命令行的交互. 比如npm init时, 要我们输入package name, author等等信息. 最后还要我们输入yes确认等交互.
具体的用法,基于上面的代码. 我们添加和命令行的交互. 输入一个author信息和最后确认.
#!/usr/bin/env node
const program = require('commander');
const inquirer = require('inquirer');
program
.version(require('../package.json').version, '-v, --version')
.command('create <name>')
.description('Create a new project')
.action(name => {
inquirer.prompt([
// 输入类型
{
type: 'input',
name: 'author',
message: 'Please input the author name.'
},
// 确认类型.
{
type: 'confirm',
name: 'continune',
message: 'Is that ok?'
}
]).then(result => {
// 输出: {author, continune}的实际的值.
console.log(result);
})
})
program.parse(process.argv);
ora
输出进度条, loading等信息
const p = ora('创建中...')
p.start();
setTimeout(() => {
p.stop();
}, 3000);
控制台中, |一直在转, 3s后停止.
chalk
用来在控制台中输出不同样式的信息. 比如文字颜色, 文字背景等.
const chalk = require('chalk')
console.log(chalk.red('some error'))
which
通过PATH环境变量到该路径内查找可执行文件,所以基本的功能是寻找可执行. 比如查找是否安装了npm。
const which = require('which');
const chalk = require('chalk');
// 查找系统中用于安装依赖包的命令
function findNpm() {
const npms = ['tnpm', 'cnpm', 'npm'];
for (let i = 0; i < npms.length; i++) {
try {
// 查找环境变量下指定的可执行文件的第一个实例
which.sync(npms[i]);
return npms[i]
} catch (e) {
}
}
throw new Error(chalk.red('请安装npm'));
}
一份完整的代码:
bin/cli文件
#!/usr/bin/env node
const program = require('commander');
const inquirer = require('inquirer');
const chalk = require('chalk');
const ora = require('ora');
program
.version(require('../package.json').version, '-v, --version')
.command('create <name>')
.description('Create a new project')
.action(name => {
console.log(name);
inquirer.prompt([
{
type: 'input',
name: 'author',
message: 'Please input the author name.'
},
{
type: 'confirm',
name: 'continune',
message: 'Is that ok?'
}
]).then(result => {
console.log(result);
console.log(chalk.red('some error'))
const p = ora('创建中...')
p.start();
setTimeout(() => {
p.stop();
}, 3000);
})
})
program.parse(process.argv);
package.json文件
{
"name": "cli-demo",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"bin": {
"xcli": "./bin/cli"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"chalk": "^2.4.2",
"commander": "^3.0.1",
"download-git-repo": "^2.0.0",
"inquirer": "^7.0.0",
"ora": "^3.4.0",
"which": "^1.3.1"
}
}
项目代码
把命令行安装到node_module下
// 进入项目文件夹
npm link
安装成功后. xcli工具就可以在任意地方使用了.
xcli create xxx
有了这些武器, 我们开发一个node命令就非常的容易了. 这些工具的完整用法. 可以直接在github上查看官方使用说明即可.
接下来, 我们要使用这些工具, 开发一个实际的工具. 实现的功能是: 类似create-react-app, 通过这个工具, 可以创建基本的react编程结构。
详情请查看: 创建Node脚手架工具(中)