像咱们熟悉的 vue-cli,taro-cli 等脚手架,只须要输入简单的命令 taro init project
,便可快速帮咱们生成一个初始项目。在平常开发中,有一个脚手架工具能够用来提升工做效率。vue
脚手架是怎么样进行构建的呢,我是借助了 taro-cli 的思路。node
npm 不仅仅用来管理你的应用和网页的依赖,你还能用它来封装和分发新的 shell 命令。git
$ mkdir lq-cli
$ npm init
复制代码
这时在咱们的 lq-cli
项目中有 package.json 文件,而后须要建立一个 JS 文件包含咱们的脚本就取名 index.js 吧。 package.json 内容以下github
{ "name": "lq-shell", "version": "1.0.0", "description": "脚手架搭建", "main": "index.js", "bin": { "lq": "./index.js" }, "scripts": { "test": "test" }, "keywords": [ "cli" ], "author": "prune", "license": "ISC" } 复制代码
index.js内容以下vue-cli
#!/usr/bin/env node console.log('Hello, cli!'); 复制代码
到这一步就能够简单运行一下这个命令shell
npm link
lq
复制代码
npm link 命令能够将一个任意位置的 npm 包连接到全局执行环境,从而在任意位置使用命令行均可以直接运行该 npm 包。 控制台会输出Hello, cli!
npm
前面的一个小节,能够跑一个命令行了,可是咱们看到的 taro-cli 中还有一些命令,init初始化项目之类。这个时候 commander
就须要利用起来了。 运行下面的这个命令将会把最新版的 commander 加入 package.jsonjson
npm install --save commander
复制代码
引入 commander 咱们将 index.js 作以下修改bash
#!/usr/bin/env node console.log('Hello, cli!') const program = require('commander') program .version(require('./package').version, '-v, --version') .command('init <name>') .action((name) => { console.log(name) }) program.parse(process.argv) 复制代码
能够经过 lq -v
来查看版本号 经过 lq init name
的操做,action里面会打印出namemarkdown
咱们看到taro init 命令里面会有一些颜色标识,就是由于引入了chalk这个包,一样和 commander 同样
npm install --save chalk
复制代码
console.log(chalk.green('init建立'))
这样会输出同样绿色的
download-git-repo 支持从 Github下载仓库,详细了解能够参考官方文档。
npm install --save download-git-repo
复制代码
download() 第一个参数就是仓库地址,详细了解能够看官方文档
命令行交互功能能够在用户执行 init 命令后,向用户提出问题,接收用户的输入并做出相应的处理。用 inquirer.js 来实现。
npm install --save inquirer
复制代码
index.js文件以下
#!/usr/bin/env node const chalk = require('chalk') console.log('Hello, cli!') console.log(chalk.green('init建立')) const program = require('commander') const download = require('download-git-repo') const inquirer = require('inquirer') program .version(require('./package').version, '-v, --version') .command('init <name>') .action((name) => { console.log(name) inquirer.prompt([ { type: 'input', name: 'author', message: '请输入你的名字' } ]).then((answers) => { console.log(answers.author) download('', name, {clone: true}, (err) => { console.log(err ? 'Error' : 'Success') }) }) }) program.parse(process.argv) 复制代码
npm install --save ora
复制代码
相关命令能够以下
const ora = require('ora') // 开始下载 const proce = ora('正在下载模板...') proce.start() // 下载失败调用 proce.fail() // 下载成功调用 proce.succeed() 复制代码
npm install --save log-symbols 复制代码
相关命令能够以下
const chalk = require('chalk') const symbols = require('log-symbols') console.log(symbols.success, chalk.green('SUCCESS')) console.log(symbols.error, chalk.red('FAIL')) 复制代码
#!/usr/bin/env node const chalk = require('chalk') console.log('Hello, cli!') console.log(chalk.green('init建立')) const fs = require('fs') const program = require('commander') const download = require('download-git-repo') const inquirer = require('inquirer') const ora = require('ora') const symbols = require('log-symbols') const handlebars = require('handlebars') program .version(require('./package').version, '-v, --version') .command('init <name>') .action(name => { console.log(name) inquirer .prompt([ { type: 'input', name: 'author', message: '请输入你的名字' } ]) .then(answers => { console.log(answers.author) const lqProcess = ora('正在建立...') lqProcess.start() download( 'direct:https://github.com/Chant-Lee/rick-cli-templates1.git', name, { clone: true }, err => { if (err) { lqProcess.fail() console.log(symbols.error, chalk.red(err)) } else { lqProcess.succeed() const fileName = `${name}/package.json` const meta = { name, author: answers.author } if (fs.existsSync(fileName)) { const content = fs.readFileSync(fileName).toString() const result = handlebars.compile(content)(meta) fs.writeFileSync(fileName, result) } console.log(symbols.success, chalk.green('建立成功')) } } ) }) }) program.parse(process.argv) 复制代码
经过上面的例子只是可以搭建出一个简单的脚手架工具,其实bash还能够作不少东西,好比 npm 包优雅地处理标准输入、管理并行任务、监听文件、管道流、压缩、ssh、git等,要想了解更多,就要深刻了解,这里只是打开一扇门,学海无涯。