自动化开发工作流
使开发者能够将更多的精力和时间放在业务逻辑之上,通常会使用webpack
gulp
browser-sync
等CLI工具,而自动化的实现则离不开脚本的编写;对于前端开发工程师而言,能够制作nodejs
命令行脚本工具也成为必须掌握的技能之一。
准备工作
- 首先我们创建一个新的项目目录
mkdir iconfont-cli
,并使用npm init
进行初始化,一路回车即可。 - 创建脚本入口文件
index.js
, 并在package.json设置bin
参数, 定义脚本命令名称及入口文件,如下:
在package.json中添加命令入口文件
{
"name":'iconfont-cli'
...
"bin": {
"iconfont": "index.js"
}
...
}
创建index.js,文件顶部声明脚本解释程序并指定为nodejs
#!/usr/bin/env node
// 代码...
console.log('iconfont cli start');
- 执行
npm link
,将npm包链接到全局执行环境,从而在任意位置使用命令行都可以直接运行,开发期间可以实时调试,该命令主要做两件事情: 一是为npm包目录创建软链接,将其链到{prefix}/lib/node_modules/<package>
,二为可执行文件(bin)创建软链接,将其链到{prefix}/bin/{name}
- 控制台输入
iconfont
, 如打印iconfont cli start
, 那么恭喜,此时项目初始化完成😊
命令交互
基本
命令行交互最核心的两大部分: 输入
与输出
。在准备工作部分,我们已经通过执行iconfont
简单命令成功运行脚本并输出log。而通常,我们在执行命令时会传入一些参数供用户进行配置,类似iconfont --dest xxxx
的形式。命令携带的参数可以在node脚本中通过process.argv
进行访问,然后解析出参数内容。所幸,目前有很多nodejs插件提供了控制台命令参数的解析,比较流行的是commander.js
库, 可以使我们方便快捷的实现参数的解析及帮助文档的输出
- 安装
npm install commander --save
- 使用方法
#!/usr/bin/env node
var program = require('commander');
program
.version('0.0.1') // 设置版本号
.option('-d, --dest <path>', '设置目标文件夹') // 设置dest参数
.action(function (cmd) {
console.log(cmd.dest) // 打印用户输入的dest参数
// ...执行后续的功能
})
program.parse(process.argv); // 解析命令行参数
执行iconfont -d ./
,控制台输出./
- commander默认提供了帮助命令,可以直接通过执行
iconfont --help
或者iconfont -h
输出
进阶
有时候我们希望通过问答的形式使用户进行一些选择、输入或确认操作,以便可以传达和接收更多的信息

Inquirer.js
库进行实现,例如我们在上文的commander中配置了dest文件夹后,希望用户进行二次确认操作,因此我们可以有如下做法:
// 此处略去....
var inquirer = require('inquirer');
program
.version('0.0.1') // 设置版本号
.option('-d, --dest <path>', '设置目标文件夹') // 设置dest参数
.action(function (cmd) {
console.log(cmd.dest) // 打印用户输入的dest参数
inquirer.prompt([
{
type:'confirm',
name:'destOk',
message:'确认使用目标文件夹:' + cmd.dest
}
]).then(function(answers){
console.log(answers.destOk) // true或false
// ...执行后续的功能
})
})
// 此处略去...
执行iconfont -d ./
,效果如下:

集成webfonts-generator
webfonts-generator
支持通过svg文件制作出css字体图标
- 安装
npm install webfonts-generator --save
- 结合上文的交互命令,完整的iconfont-cli工具代码如下
#!/usr/bin/env node
var program = require('commander');
var inquirer = require('inquirer');
var webfontsGenerator = require('webfonts-generator');
var path = require('path');
var fs = require('fs');
// 遍历查询SVG文件
function findSvgs(folder, list){
list = list || [];
try {
var files = fs.readdirSync(folder);
for(var i=0; i<files.length; i++){
(function(){
var fileName = files[i],
filePath = path.join(folder, fileName),
stats = fs.statSync(filePath);
if(!stats.isFile()){
return findSvgs(filePath, list);
} else if(path.extname(filePath) === '.svg'){
list.push(filePath);
}
})(i);
}
} catch (error) {
console.error(error);
}
return list;
}
program
.version('0.0.1') // 设置版本号
.option('-d, --dest <path>', '设置目标文件夹') // 设置dest参数
.action(function (cmd) {
var currentFolder = process.cwd(); // 当前命令执行的目录
var destFolder = path.isAbsolute(cmd.dest) ? cmd.dest : path.join(currentFolder,cmd.dest); // 目标目录, 需区分是否为绝对路径
inquirer.prompt([
{
type: 'confirm',
name: 'destOk',
message: '确认使用目标文件夹:' + destFolder
}
]).then(function(answers){
// 用户确认后执行后续的功能
if(answers.destOk){
webfontsGenerator({
files: findSvgs(currentFolder),
dest: cmd.dest,
html: true
}, function(error) {
if (error) {
console.log('Fail!', error);
} else {
console.log('Done!');
}
})
}
})
})
program.parse(process.argv);
- 进入svg文件所在的文件夹,执行命令
iconfont -d ./iconfont
,即可生成图标相关的各类文件以及html预览
发布与使用
至此我们成功完成了一个简单的命令行工具iconfont-cli
,接下来我们可以将其发布的npm仓库供其他开发者下载使用,具体步骤如下:
- 首先我们需要在www.npmjs.com/注册账户,之后使用
npm adduser
进行登录,需填写Username、Password、Email相关信息. - 检查package.json设置,如author、license、version、homepage等相关信息,参考package.json属性详解
- 发布
npm publish
,此时我们可能会遇到下面截图的问题,说明iconfont-cli已经被其他人发布过了,所以要换个名字进行发布,直接修改package.json中的name即可.

npm install -g iconfont-cli
全局安装使用