详解用node编写自己的cli工具


Posted in Javascript onMay 23, 2017

工作中接到新项目,开发前都需要先规划项目目录,然后一个个创建文件,搭建sass编译环境,下载jquery,Swiper等类库... 这些准备工作都要花上不少时间。每做一个项目,都会遇到同样的问题,再重复一遍吗?
是时候做点改变了:编写自己的cli工具,一行命令,3秒钟进入coding状态!

本文以自己的my-cli为例,将开发到发布过程完整记录下来,看完本文,你将学会如何从零开发一个cli项目,如何上传到github库,以及如何使用npm发布自己的包。

准备

开发一个cli工具前首先要想好它能做什么。以我自己为例,我需要一个工具,让我能只输入一行命令就帮我快速搭建好项目结构,就像这样:

详解用node编写自己的cli工具

是不是很炫酷?放心,很简单。

开始

首先创建你的cli项目,并使用npm init创建一个package.json。

$ mkdir my-cli && cd my-cli
$ npm init

根据提示一步步创建好package.json。name属性就是你发布到npm上的名字,这个是不能与npm上现有项目重名的,一个小技巧是使用npm install下载你想要起的包名字,如果报错404,那么你的包名是可用的。最后创建好的package.json文件像这样子:

{
 "name": "my-cli",
 "version": "0.0.1",
 "description": "Auto generate project template",
 "main": "index.js",
 "bin": {
  "my-cli": "./index.js"
 },
 "repository": {
  "type": "git",
  "url": "git+https://github.com/hlme/my-cli.git"
 },
 "keywords": [
  "cli"
 ],
 "author": "798400626@qq.com",
 "license": "MIT",
 "bugs": {
  "url": "https://github.com/hlme/my-cli/issues"
 },
 "homepage": "https://github.com/hlme/my-cli#readme"
}

编写可执行文件

package.json中有一个"bin"字段,配置后才可以在控制台使用你的命令。

"bin": {
 "my-cli": "./index.js"
}

我们配置了"my-cli"命令来执行index.js文件。用你喜欢的编辑器,在项目主目录下创建一个index.js文件。

详解用node编写自己的cli工具

注意第一行的"#! node"很重要,表示用node来执行这个文件。如果没有这句声明,就会在记事本中打开index.js文件。

全局安装你的包

使用 npm install -g 将你当前的项目安装到全局环境,现在你可以在命令行使用"my-cli"命令了。

详解用node编写自己的cli工具

用fs模块快速生成项目模板

我们自定义的指令可以执行了,接下来编写代码实现功能。my-cli的主要功能就是生成项目模板,一个思路是用一个templates文件夹保存项目模板,然后通过fs.mkdir()来创建项目目录,最后把文件从templates文件夹拷贝到项目中去。

var fs = require('fs');
var path = require('path');

function copyTemplate (from, to) {
 from = path.join(__dirname, 'templates', from);
 write(to, fs.readFileSync(from, 'utf-8'))
}
function write (path, str, mode) {
 fs.writeFileSync(path, str)
}
function mkdir (path, fn) {
 fs.mkdir(path, function (err) {
  fn && fn()
 })
}

核心代码就这么点,是不是非常简单?

整个项目文件结构差不多就这个样子,把你需要的文件放到templates文件夹,然后用copyTemplate方法将文件拷贝到项目目录下。

详解用node编写自己的cli工具

创建文件目录和拷贝文件的过程,代码看着比较丑陋

详解用node编写自己的cli工具

接收命令行参数

平常我们使用命令行工具时都会用到参数,如 webpack -p, express -e 等,现在我们来为自己的cli添加接收命令行参数的功能。为my-cli设计四个参数,用来向项目中添加类库。

$ my-cli -j -s -v -b
//-j :添加jQuery
//-s :添加Swiper
//-v :添加Vue
//-b :添加Bootstrap

使用commander包可以简化解析参数过程,但是本项目比较简单,我也不想额外引入其他的包了,处理一些简单的参数其实并不难。

node中我们可以使用process.argv来获取命令行参数,process.argv是一个参数数组,第一项为node.exe的绝对路径,第二项为执行该js的绝对路径,使用process.argv.slice(2)即可获取输入的参数数组。

详解用node编写自己的cli工具

通过遍历参数数组来检查命令中输入了哪些参数。如果输入了预设的参数,就为config对象添加对应的属性,在生成文件时根据onfig判断是否将模板文件拷贝到项目中。继续丑陋的代码:

详解用node编写自己的cli工具

本地运行

至此我们的项目已经基本完成了,使用 npm install -g 将项目安装到全局环境,然后新建一个项目文件夹,使用my-cli命令来生成项目模板。

详解用node编写自己的cli工具

发布到npm仓库

要想将自己的包发布到npm上,首先得有一个npm账号,创建账号非常简单,输入npm adduser,简单三步即可完成创建。

详解用node编写自己的cli工具

创建好user后,使用npm publish即可将当前项目发布到npm上了,以后就可以使用npm install -g my-cli 来安装你的cli工具。

详解用node编写自己的cli工具

结束语

相信大家看完本文后知道如何根据自己的需求制作cli工具了。本文中的my-cli比较简单,权当做抛砖引玉。如果想查看完整源码或者使用这个工具,可以戳这里:github地址。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
Prototype使用指南之range.js
Jan 10 Javascript
Javascript YUI 读码日记之 YAHOO.util.Dom - Part.2 0
Mar 22 Javascript
jquery 元素相对定位代码
Oct 15 Javascript
JS 表单验证大全
Nov 23 Javascript
JavaScript基础知识之数据类型
Aug 06 Javascript
Jquery插件写法笔记整理
Sep 06 Javascript
js插件方式打开pdf文件(浏览器pdf插件分享)
Dec 20 Javascript
Active控件问题小结(附解决办法)
Jun 09 Javascript
JS验证input输入框(字母,数字,符号,中文)
Mar 23 Javascript
浅谈FastClick 填坑及源码解析
Mar 02 Javascript
微信web端后退强制刷新功能的实现代码
Mar 04 Javascript
vue iview实现动态新增和删除
Jun 17 Javascript
JavaScript 巧学巧用
May 23 #Javascript
JS获取短信验证码倒计时的实现代码
May 22 #Javascript
原生JS实现不断变化的标签
May 22 #Javascript
jQuery实现简单的滑动导航代码(移动端)
May 22 #jQuery
vue2.0 与 bootstrap datetimepicker的结合使用实例
May 22 #Javascript
Vue实现动态显示textarea剩余字数
May 22 #Javascript
bootstrap栅格系统示例代码分享
May 22 #Javascript
You might like
星际争霸任务指南——虫族
2020/03/04 星际争霸
DISCUZ在win2003环境下 Unable to access ./include/common.inc.php in... 的问题终极解决方案
2011/11/21 PHP
解析php中的escape函数
2013/06/29 PHP
PHP简单数据库操作类实例【支持增删改查及链式操作】
2016/10/10 PHP
PHP基于回溯算法解决n皇后问题的方法示例
2017/11/07 PHP
针对thinkPHP5框架存储过程bug重写的存储过程扩展类完整实例
2018/06/16 PHP
JQERY limittext 插件0.2版(长内容限制显示)
2010/08/27 Javascript
jQuery cdn使用介绍
2013/05/08 Javascript
jquery制作居中遮罩层效果分享
2014/02/21 Javascript
图解JavaScript中的this关键字
2020/05/28 Javascript
jQuery实现返回顶部功能
2016/02/23 Javascript
JS基础随笔(菜鸟必看篇)
2016/07/13 Javascript
js封装成插件的步骤方法
2017/09/11 Javascript
nodejs实现的连接MySQL数据库功能示例
2018/01/25 NodeJs
完美解决axios在ie下的兼容性问题
2018/03/05 Javascript
webpack4 处理CSS的方法示例
2018/09/03 Javascript
微信小程序遍历Echarts图表实现多个饼图
2019/04/25 Javascript
vue实现列表拖拽排序的功能
2020/11/02 Javascript
[11:27]《一刀刀一天》之DOTA全时刻20:TI4总奖金突破920W TS赛事分析
2014/06/18 DOTA
[03:32]2014DOTA2西雅图邀请赛 CIS外卡赛赛前black专访
2014/07/09 DOTA
[06:01]刀塔次级联赛top10第一期
2014/11/07 DOTA
[01:26]神话结束了,却也刚刚开始——DOTA2新英雄玛尔斯驾临战场
2019/03/10 DOTA
python实现随机密码字典生成器示例
2014/04/09 Python
Python中的FTP通信模块ftplib的用法整理
2016/07/08 Python
python使用pil进行图像处理(等比例压缩、裁剪)实例代码
2017/12/11 Python
详解Python3 中hasattr()、getattr()、setattr()、delattr()函数及示例代码数
2018/04/18 Python
python tornado微信开发入门代码
2018/08/24 Python
python3.6实现学生信息管理系统
2019/02/21 Python
python模拟鼠标点击和键盘输入的操作
2019/08/04 Python
如何利用Python matplotlib绘制雷达图
2020/12/21 Python
css3实现多个元素依次显示效果
2017/12/12 HTML / CSS
日本无添加化妆品:HABA
2016/08/18 全球购物
美国一家运动专业鞋类零售商:Warehouse Shoe Sale(WSS)
2018/03/28 全球购物
图书室标语
2014/06/21 职场文书
有限公司股东合作协议书
2014/10/29 职场文书
毕业设计论文致谢词
2015/05/14 职场文书