# 常见npm包
本文是vue-cli的学习blog
首先说一下常用的npm包,这样更方便之后的学习。
# commander
commander (opens new window)是一款重量轻,表现力和强大的命令行框架,提供了用户命令行输入和参数解析强大功能。
推荐使用
minimist
替代,源代码更小。
# Inquirer
Inquirer (opens new window) 为交互式命令行工具,比如执行 vue create 命令会有以下的命令行交互:
# execa
execa (opens new window) 是可以调用 shell 和本地外部程序的 javascript 封装。会启动子进程执行,支持多操作系统,包括 windows,如果父进程退出,则生成的全部子进程都被杀死。它是在 Node.js 内置的 child_process.exec 基础上进行了提升,比如更好地支持 windows 平台,以及提供 Promise 的接口等等。
# handlebars
handlebars (opens new window) 是一个 javascript 语义模版库,而且与 Mustache 模板 是兼容的,通过一个 demo 来感受下:
var source = "<p>Hello, my name is {{name}}. I am from {{hometown}}. I have " +
"{{kids.length}} kids:</p>" +
"<ul>{{#kids}}<li>{{name}} is {{age}}</li>{{/kids}}</ul>";
var template = Handlebars.compile(source);
var data = { "name": "Alan", "hometown": "Somewhere, TX",
"kids": [{"name": "Jimmy", "age": "12"}, {"name": "Sally", "age": "4"}]};
var result = template(data);
// Would render:
// <p>Hello, my name is Alan. I am from Somewhere, TX. I have 2 kids:</p>
// <ul>
// <li>Jimmy is 12</li>
// <li>Sally is 4</li>
// </ul>
# metalsmith
metalsmith (opens new window) 一个静态网站生成器,可以用在批量处理模板的场景,和 hexo 类似。它最大的特点就是所有的逻辑都是由插件处理,你只需要将这些插件用 metalsmith 连接起来使用即可
# chalk
chalk (opens new window) 是用于修改控制台字符串的样式,包括字体样式(加粗),颜色以及背景颜色等。 使用比较简单:
const chalk = require('chalk');
console.log(chalk.blue('Hello world!'));
# download-git-repo
download-git-repo (opens new window) 是用于 从 GitHub, GitLab, Bitbucket 下载一个 git 仓库,API 如下:
download(repository, destination, options, callback)
- repository:仓库地址。
- destination:存放下载 git 仓库的路径。
- options:选项,clone。是以 http download 的形式还是 git clone 的形式下载。其中 git clone 的形式支持下载 private 仓库。
- callback:下载完成地回调。
# consolidate
consolidate (opens new window) 是一个模版引擎整合库,它的作用是把一些著名的模板引擎适配成 Express 兼容的接口
# SAO
# 介绍
通过配置文件快速生成脚手架工具,基于cac、chalk、enquirer、cross-spawn、ejs、fs-extra、ora
等包。文档不完整,社区使用少,太长时间不维护。
#
# cac
# 介绍
类似commander
,完整的命令行解决方案
# command
接收命令,参数(name,description,config?)
, name中[]
表示可选参数。<>
表示必填参数。
const cli = require('cac')()
cli.command('deploy <folder>', 'Deploy a folder to AWS')
cli
.command('build [...otherFiles]', 'Build your app') // command支持多个参数
command执行完毕后实例带有option、action、alias、allowUnknownOptions、example、usage
方法可执行。
# 默认command
只需要省略name,就可以创建一个默认command,这会在没有匹配到command时执行该命令。
cli
.command('[...files]', 'Build files')
.action((files, options) => {
console.log(files)
})
# command.option
设置命令的参数,参数:(name,description,config?)
,name中使用时[]
表示该值可以为true,<>
表示值为字符串或数字。括号内的内容可以随便写,不会影响接参和解析参数。
const cli = require('cac')()
cli
.command('build [project]', 'Build a project')
.option('--out <dir>', 'Output directory')
# 对象格式option
也叫做点嵌套option
yy create --env.a 123 // 会被解析成:{ '--': [], env: { a: 123 } }
# 数组格式option
输入多个相同的option时,解析到的参数就是数组形式
node cli.js --include project-a --include project-b // { include: ['project-a', 'project-b'] }
# command.example
在输入commad时,输入-h
,会提示相关示例。不会在命令行的顶级-h
中显示。
const cli = require('cac')()
cli.command('create [file]').example("yy create -f")
在命令行输入yy create -h
,会展示如下信息:
index.js/0.0.0
Usage:
$ index.js create [file]
Examples:
yy create -f
# command.acition
接收用户命令的回调函数,参数:(...args,options)
args如果是可变参数则为数组,
# help
在输入-h
或者--help
的时候,显示帮助信息。需要注册:cli.help()
# version
输入-v
或者--version
的时候显示版本信息,需要自定义:cli.version("0.0.1")
# Events
监听命令
// Listen to the `foo` command
cli.on('command:foo', () => {
// Do something
})
// Listen to the default command
cli.on('command:!', () => {
// Do something
})
// Listen to unknown commands
cli.on('command:*', () => {
console.error('Invalid command: %s', cli.args.join(' '))
process.exit(1)
})
# parse
只有在该方法调用时,cli.rawArgs
cli.args
cli.options
cli.matchedCommand
才会生效
# prompts
# 介绍
命令行中进行询问
const prompts = require('prompts');
(async () => {
const response = await prompts({
type: 'text',
name: 'meaning',
message: 'What is the meaning of life?'
});
console.log(response.meaning);
})();
还支持多个询问
const prompts = require('prompts');
const questions = [
{
type: 'text',
name: 'username',
message: 'What is your GitHub username?'
},
{
type: 'number',
name: 'age',
message: 'How old are you?'
},
{
type: 'text',
name: 'about',
message: 'Tell something about yourself',
initial: 'Why should I?'
}
];
(async () => {
const response = await prompts(questions);
// => response => { username, age, about }
})();
# Prompt Objects
询问对象,除了stdin和stdout其他key都可以为函数,当值为函数时,提供3个参数(prev,values,prompt)
,prev是上一个询问的值,values是所有询问的值,prompt是上一个询问对象
{
type: String | Function,
name: String | Function,
message: String | Function,
initial: String | Function | Async Function
format: Function | Async Function,
onRender: Function
onState: Function
stdin: Readable
stdout: Writeable
}
# type
当type值为falsy
时,跳过该问题。type的所有类型如下:
text
password
invisible
number
confirm
list
toggle
select
multiselect
autocompleteMultiselect
autocomplete
date
# Options
# onSubmit
(async () => {
const questions = [{ ... }];
const onSubmit = (prompt, answer) => console.log(`Thanks I got ${answer} from ${prompt.name}`);
const response = await prompts(questions, { onSubmit });
})();
# onCancel
(async () => {
const questions = [{ ... }];
const onCancel = prompt => {
console.log('Never stop prompting!');
return true;
}
const response = await prompts(questions, { onCancel });
})();
# override
从命令行解析参数提前回答问题
const prompts = require('prompts');
prompts.override(require('yargs').argv);
(async () => {
const response = await prompts([
{
type: 'text',
name: 'twitter',
message: `What's your twitter handle?`
},
{
type: 'multiselect',
name: 'color',
message: 'Pick colors',
choices: [
{ title: 'Red', value: '#ff0000' },
{ title: 'Green', value: '#00ff00' },
{ title: 'Blue', value: '#0000ff' }
],
}
]);
console.log(response);
})();
# inject
提前提供问题答案,此功能只用于测试
const prompts = require('prompts');
prompts.inject([ '@terkelg', ['#ff0000', '#0000ff'] ]);
(async () => {
const response = await prompts([
{
type: 'text',
name: 'twitter',
message: `What's your twitter handle?`
},
{
type: 'multiselect',
name: 'color',
message: 'Pick colors',
choices: [
{ title: 'Red', value: '#ff0000' },
{ title: 'Green', value: '#00ff00' },
{ title: 'Blue', value: '#0000ff' }
],
}
]);
// => { twitter: 'terkelg', color: [ '#ff0000', '#0000ff' ] }
})();