还记得我们在写vue 项目的时候用脚手架vue-init的主要作用是根据指定模板生成项目原型嘛?那么vue-init怎么实现的呢? 其实就是在vue-cli package.json中增加下面的代码
{
"bin": {
"vue": "bin/vue",
"vue-init": "bin/vue-init", //执行vue-init 的时候下载项目原型
"vue-list": "bin/vue-list",
"vue-build": "bin/vue-build"
}
}
复制代码
具体实现请看下面:
本篇的主要内容是:实现可以在命令行中,直接运行代码(下面的名字可以自己取)。
xl-cli install (安装)
复制代码
在实现自己的命令行运行代码前,你需要对命令行,npm(包管理器)的基本用法有些了解。 下面进入正题:
//创建一个 xl-cli文件夹 mkdir xl-cli
// cd xl-cli
// npm init 初始化
复制代码
完成上面几个步骤之后 我们能看到生成了一个xl-cli文件夹 文件中包含一个package.json文件。
{
"name": "xl-cli",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}
复制代码
我们知道在npm run xxx的时候其实就是执行的package.json中的scripts,比如上面 你看看npm run test就会输出Error: no test specified,我们的代码用的es6需要编译成es5,先创建一个npm run compile,(test没用,同时给test删掉)
{
"name": "xl-cli",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"compile": "babel src -d dist"
},
"author": "",
"license": "ISC"
}
复制代码
我们需要安装babel 创建 (安装babel-cli babel-env)
src
--main.js
复制代码
这个时候我们执行 npm run compile其实就是相当于在命令行中输入了 babel src -d dist 然后我们看到了生成了一个这样的目录:
dist
--main.js
复制代码
我们经常会有这样的需求就是在更改src 里面的内容的时候 同步更改dist里面的内容,可以这样做:在package.json的scripts增加一个 watch命令:
{
"name": "xl-cli",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"compile": "babel src -d dist",
"watch":"npm run compile -- --watch"
},
"author": "",
"license": "ISC"
}
复制代码
然后运行 npm run watch命令 就实现了同步更新了!
下面实现 xl-cli命令行
创建 ./bin/www目录, 要实现在命令行中使用 类似vue-cli这样的命令 需要在package.json中增加
"bin": {
"xl-cli": "./bin/www"
},
复制代码
./bin/www中的内容:
#! /usr/bin/env node
require('../dist/main.js');
复制代码
第一行 最后的node是表示node环境 前面参数写死的,第二行表示执行的代码 ,创建完成后执行npm link,相当于在本地添加环境变量。 至此,你已经可以执行xl-cli命令了,其实就是执行了dist/main.js。
实现像其他命令行中的xl-cli --help 先引入一个包 commander ,这个包可以帮助我们设置和解析命令参数。 src/main.js
//main.js
import program from 'commander';
import {VERSION} from './utils/constants';
program.command('install') //加命令
.description('install template')
.alias('i')
.action(() => {
console.log('用户install了')
})
program.version(VERSION,'-v --version').parse(process.argv); //加 option
复制代码
我们可以看到在命令窗口输入 xl-cli install 会打印出:
用户install了
复制代码
好了 到现在我们就剩下执行下载模板任务了,这样我们新建一个install.js来执行下载任务
//install.js
import ora from 'ora'; //ora 一个命令行loading效果
import inquirer from 'inquirer' //命令行交互
import downLoadGit from 'download-git-repo'; //github api用来下载github的模板
let install = async () => {
// 下载模板
let loading = ora('fetching template......');
let answer = await inquirer.prompt([
{
type: 'input', //你可以输入你自己的名称
name: 'projectName',
message:'项目名称',
default:'xlDemo' //默认名
}
]);
// 项目名字
let project = answer.projectName;
loading.start();
//我在github上面上传了一个非常简单的模板 xlei1123/xl-cli downLoadGit(src, dest) 从哪拉 拉到那 process.cwd()+'/'+project这是拉到了当前目录下的你刚刚命名的文件中
downLoadGit('xlei1123/xl-cli',process.cwd()+'/'+project,(err) => {
if(err) {
console.log(err)
return;
}
console.log(process.cwd()+'/'+project)
loading.succeed();
});
}
export default install;
复制代码
这样在上面的action中执行 install()就好了!
//main.js
import program from 'commander';
import {VERSION} from './utils/constants';
import install from './install'
program.command('install') //加命令
.description('install template')
.alias('i')
.action(() => {
install()
})
program.version(VERSION,'-v --version').parse(process.argv); //加 option
复制代码
这样我们就完成了自己cli了,可以执行下面几个简单的命令看一下效果:
xl-cli --help
xl-cli -v
xl-cli install
复制代码
一句话总结:我们发布了一个npm包 这个包的package.json中有bin可以全局执行,判断参数有install,就从github上面拉取模板。
当然这篇实现的是简单的命令行工具主要是理解其中大致原理,肯定会存在很多不足的地方,欢迎各位提出宝贵的意见或建议,也希望能帮助到你从中获得一些知识!