0搭建前准备环境
0.1创建项目
nodejs环境是必备的,这里不多说了,首先需要 npm init -y初始化一个项目。
然后创建一个index.js,整个项目结构如下
.
之后我们需要写的部分都在index.js中。
0.2配置项目
这里注意下为了系统能识别为node脚本,需要在index首行声明如下
#!/usr/bin/env node
配置package.json
在末尾加上这段配置“license”: “ISC”,
“bin”: {
“cli”: “index.js”
},说明一下cli即为我们的命令,可以理解为vue-cli
index则为我们需要执行的脚本0.3生成全局命令
在index.js的目录下输入
npm link
这样就生成了全局变量,在任何地方只要输入cli就会执行index.js中的脚本。可以写一个console.log试试
1命令包安装commander.js
1.1commander说明
commander是一个轻巧的nodejs模块,提供了用户命令行输入和参数解析强大功能
可以在github上直接搜索这个项目传送门
下载npm install commander -s
引用
const program = require(‘commander’);
1.2commander配置
直接复制Examples下的代码到index中1
2
3
4
5
6
7
8
9
10
11
12
13
14program
.command('exec <cmd>')
.alias('ex')
.description('execute the given remote cmd')
.option("-e, --exec_mode <mode>", "Which exec mode to use")
.action(function(cmd, options){
console.log('exec "%s" using %s mode', cmd, options.exec_mode);
}).on('--help', function() {
console.log('');
console.log('Examples:');
console.log('');
console.log(' $ deploy exec sequential');
console.log(' $ deploy exec async');
});
这些就是一个命令全部内容
命令名称为:
.command(‘exec [env]’)
list代表命令名称 [env]代表参数
其中[]内的参数为可选参数
其中<>内的参数为必填参数
命令说明为:
.description(‘execute the given remote cmd’)
操作方法为:
.action(function(template, project){}
输入–help操作为:
.on(‘–help’, function() {})
其中 –help命令不需要额外配置,它会根据配置自动生成
1.3commander错误命令提示
错误配置代码如下:1
2
3
4
5program
.command('*')
.action(function(env){
console.log('deploying "%s"', env);
});
1.4commander配置版本号
版本号配置代码如下1
2program
.version('0.1.0') //调用-v或者 --version的时候输出该版本号
2下载包download-git-repo.js
2.1准备模板
这里我准备了三个模板供下载,在github上创建三个空项目,自动生成README.md出来如图所示:
.
创建项目这里就不多说了。
2.2下载download-git-repo.js
用npm下载
npm install download-git-repo -s
引用
const download = require(‘download-git-repo’)
1 | download(downloadUrl,project,{clone:true},(err)=>{ |
- downloadUrl 为仓库地址路径
- project 为创建项目的名称,即我本地想叫什么名
- {clone:true} 进行克隆
- err=>{}错误原因并在下载结束后执行方法
2.3完成下载
我们希望输入命令 cli vue new_vue 生成一个new_vue的项目并应用我们的vue_template模板,同理其他模板也用相应命令进行创建
- 首先我们创建一个对象来放我们的模板名称和路径和简介
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17templates={
'vue':{
url:"https://github.com/linjiad/vue_template.git",
description:"vue模板",
downloadUrl:"direct:https://github.com:linjiad/vue_template#master"
},
'react':{
url:"https://github.com/linjiad/react_template.git",
description:"react模板",
downloadUrl:"direct:https://github.com:linjiad/react_template#master"
},
'angular':{
url:"https://github.com/linjiad/angular_template.git",
description:"angular模板",
downloadUrl:"direct:https://github.com:linjiad/angular_template#master"
}
}
这里开始写program命令1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16program
.command('init <template> <project>') //命令
.description('初始化项目模板')
.action(function(template, project){
const {downloadUrl} = templates[template];
//根据模板名(template)下载对应模板,并命名为(project)
//第一个参数:仓库地址
//第二个参数:下载路径,下载到哪
download(downloadUrl,project,{clone:true},(err)=>{
if(err){
return console.log('下载失败:'+err);
} else{
return console.log('下载成功');
}
})
});
这样简单的模板下载就成功了
3交互handlebars和inquirer
3.1配置模板中的package.json
在模板中创建package.json,同时把需要客户填写的地方配置成可变的,代码如下1
2
3
4
5
6
7
8
9
10
11
12{
"name": "{{ name }}",
"version": "1.0.0",
"description": "{{ description }}",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "{{ author }}",
"license": "ISC"
}
- 其中”name”: ““为用户输入的项目名
- “description”: ““,为项目说明
- “author”: “linjiad“,为作者姓名
3.2下载handlebars和inquirer
- handlebars:模板引擎传送门
npm install handlebars -s
引用
const handlebars = require(‘handlebars’);
- inquirer:向导传送门
npm install inquirer -s
引用
const handlebars = require(‘inquirer’);
3.2修改program命令
我们的思路分为以下几部
- 把项目下的 package.json 文件读取出来
- 使用想到的方式采集用户输入的值
- 使用模板引擎把用户输入的数据解析到package.json中
- 解析完毕,把解析之后的结果重新写入package.json中
在此之前我们要用的nodejs中的读写fs模块const fs = require(‘fs’);
修改后代码如下1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43program
.command('init <template> <project>') //命令
.description('初始化项目模板')
.action(function(template, project){
const {downloadUrl} = templates[template];
//根据模板名(template)下载对应模板,并命名为(project)
//第一个参数:仓库地址
//第二个参数:下载路径,下载到哪
download(downloadUrl,project,{clone:true},(err)=>{
if(err){
return console.log('下载失败:'+err);
} else{
// 把项目下的package.json读取
// 采取向导方式采集用户输入的值
// 使用模板引擎把用户输入的数据解析到package.json
// 解析之后的结果从新写入package.json
inquirer.prompt([
{
typ: 'input',
name: 'name',
message: '请输入项目名称'
},
{
typ: 'input',
name: 'description',
message: '请输入项目简介'
},
{
typ: 'input',
name: 'author',
message: '请输入作者姓名'
},
]).then((answers)=>{
const packagePath = `${project}/package.json`;
//把数据替换到package.json中
const packageContent = fs.readFileSync(packagePath,'utf8');
const packageResult = handlebars.compile(packageContent)(answers);
fs.writeFileSync(packagePath,packageResult)
console.log(logSymbols.success,chalk.green("初始化模板成功"))
})
}
})
});
这样整个cli脚本就更加人性化了
4美化脚本
4.1添加loading效果 ora.js
ora:loading美化传送门
下载
npm install ora -s
引用
var ora = require(‘ora’);
使用:
const spinner = ora(‘正在下载模板…’).start();
spinner.fail(‘下载失败’);//下载失败提示
spinner.succeed(‘下载成功’); //下载成功提示
4.2添加字体颜色 ora.js
chalk:字体美化传送门
下载
npm install chalk -s
引用
var chalk = require(‘chalk’);
使用:
chalk.red(“错误”)
chalk.green(“成功”)
4.3特殊符号 log-symbols.js
log-symbols:特殊符号,如对号错号传送门
下载
npm install log-symbols -s
引用
var logSymbols = require(‘log-symbols’);
使用:
console.log(logSymbols.erro);
console.log(logSymbols.success);
4.4修改program命令
修改后的代码如下(既全部代码):1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
//命令包
const program = require('commander');
//下载包
const download = require('download-git-repo')
//模板引擎
const handlebars = require('handlebars');
//向导
const inquirer = require('inquirer');
const fs = require('fs');
//loading美化
var ora = require('ora');
//字体美化
const chalk = require('chalk');
//符号
const logSymbols = require('log-symbols')
program
.version('0.1.0') //调用-v或者 --version的时候输出该版本号
const templates={
'vue':{
url:"https://github.com/linjiad/vue_template.git",
description:"vue模板",
downloadUrl:"direct:https://github.com:linjiad/vue_template#master"
},
'react':{
url:"https://github.com/linjiad/react_template.git",
description:"react模板",
downloadUrl:"direct:https://github.com:linjiad/react_template#master"
},
'angular':{
url:"https://github.com/linjiad/angular_template.git",
description:"angular模板",
downloadUrl:"direct:https://github.com:linjiad/angular_template#master"
}
}
program
.command('init <template> <project>') //命令
.description('初始化项目模板')
.action(function(template, project){
//下载之前做loading提示
const spinner = ora('正在下载模板...').start();
const {downloadUrl} = templates[template];
//根据模板名下载对应模板,并命名为project
//第一个参数:仓库地址
//第二个参数:下载路径,下载到哪
download(downloadUrl,project,{clone:true},(err)=>{
if(err){
spinner.fail('下载失败');//下载失败提示
return console.log(logSymbols.error,chalk.red(err))
}
spinner.succeed('下载成功'); //下载成功提示
// 把项目下的package.json读取
// 采取向导方式采集用户输入的值
// 使用模板引擎把用户输入的数据解析到package.json
// 解析之后的结果从新写入package.json
inquirer.prompt([
{
typ: 'input',
name: 'name',
message: '请输入项目名称'
},
{
typ: 'input',
name: 'description',
message: '请输入项目简介'
},
{
typ: 'input',
name: 'author',
message: '请输入作者姓名'
},
]).then((answers)=>{
const packagePath = `${project}/package.json`;
//把数据替换到package.json中
const packageContent = fs.readFileSync(packagePath,'utf8');
const packageResult = handlebars.compile(packageContent)(answers);
fs.writeFileSync(packagePath,packageResult)
console.log(logSymbols.success,chalk.green("初始化模板成功"))
})
})
});
program
.command('list') //命令
.description('查看所有可用模板')
.action(()=>{
for(const key in templates){
console.log(`${key}:${templates[key].description}.`)
}
});
program
.command('setup [env]') //命令
.description('run setup commands for all envs')
.option("-s, --setup_mode [mode]", "Which setup mode to use")
.action(function(env, options){
var mode = options.setup_mode || "normal";
env = env || 'all';
console.log('setup for %s env(s) with %s mode', env, mode);
});
program
.command('exec <cmd>')
.alias('ex')
.description('execute the given remote cmd')
.option("-e, --exec_mode <mode>", "Which exec mode to use")
.action(function(cmd, options){
console.log('exec "%s" using %s mode', cmd, options.exec_mode);
}).on('--help', function() {
console.log('');
console.log('Examples:');
console.log('');
console.log(' $ deploy exec sequential');
console.log(' $ deploy exec async');
});
program
.command('*') //其他的命令
.action(function(env){
console.log('不存在 "%s"命令', env);
});
program.parse(process.argv);
5npm发布包
- 打开npm官网
- 注册一个npm账号
- 在npm官网上搜索是否有重名
4.讲package.json中的那么修改为发布到npm上的名和本地项目名称没有关系
5.打开控制台,执行npm login,在控制台输入登录
6.登陆成功后,在项目下执行npm publish进行发布
7 在其他电脑上就可以安装成全局变量了
这样一个脚手架就搭建完毕了
最后更新: 2018年11月25日 17:24