来源 | https://juejin.cn/post/6899446879487180808

作者 | 隐冬

基本上,使用任何成熟的语言都可以开发 cli 工具,作为一个前端小白,还是 JavaScript 比较顺手,因此我们选用nodejs作为开发语言,开发一款node-cli工具。

类似于脚手架工具,Node工具会自动去询问你一些预设的问题,然后将你回答的结果结合一些模板文件,给你生成一个项目结构。

那接下来我们以一个小型的脚手架工具为例,通过Nodejs完成一个Node工具,再来去深入体会一下Node工具的工作过程。

那我们知道脚手架工具实际上就是一个node-cli应用,那创建脚手架就是创建一个node-cli应用,那这里我们具体来操作一下,我们首先进入到命令行,通过mkdir去创建一个工具目录。

mkdir samlpe-clicd sample-cli

在这个目录下面我们通过yarn init 方式去初始化一个package.json文件

yarn init

有了这个文件之后通过编辑器打开这个目录,紧接着我们需要在package.json中添加一个bin字段,用于去指定一下我们cli应用的入口文件, 我们这里叫cli.js

{  "name": "sample-cli",  "bin": "cli.js",  ...}

再然后我们添加这个cli.js文件,跟以往我们在Node中书写的文件有所不同,cli的入口文件必须要有一个特定的文件头, 也就是在这个文件顶部写上这样一句话 #! /usr/bin/env node 我们在这个文件中console.log一句话。

#! /usr/bin/env node
console.log('cli working')

如果说你的操作系统是linux或者mac系统你还还需要去修改这个文件的读写权限,把他修改成755,这样才可以作为一个cli的入口文件。

我们回到命令行,我们通过yarn link 将这个模块映射到全局

yarn link

这时候我们就可以在命令行使用sample这样一个命令, 通过执行这个命令我们的console.log成功打印出来,表示代码执行了。也就意味着我们这个cli基础就已经ok了。

sample-cli

接下来我们实现一下脚手架的具体业务,也就是我们脚手架的工作过程。

首先我们需要通过命令行交互的的方式去询问用户的一些信息,然后紧接着呢根据用户反馈回来的结果我们去生成文件,

  1. 通过命令行交互的方式询问用户信息

  2. 根据用户反馈回来的结果生成文件

在Node当中去发起命令行交互询问我们使用inquirer这样一个模块,那我们需要通过npm安装一下这个模块,我这里使用yarn,安装在依赖文件当中。

yarn add inquirer --dev

那有了这个模块过后就可以在代码中去载入, inquirer这个模块提供一个叫做prompt的方法用于发起一个命令行的询问。

他可以接收一个数组参数,数组中每一个成员就是一个问题,可以通过type指定问题输入方式,然后name指定返回值的键,message去指定屏幕上给用户的一个提示,在promise的then里面拿到这个问题接收到用户的答案。

我们这里不着急往下写,我们先通过console.log去打印一下。

const inquirer = require('inquirer');
inquirer.prompt([    {        type: 'input',        name: 'name',        message: 'Project name'    }]).then(answer => {    console.log(answer);})

回到控制台,我们命令行执行sample-cli, 此时就会提示我们需要输入项目的名称。

sample-cli

这样就可以看到问题和返回的结果。这也就证明inquirer确实可以帮我们发起命令行交互询问。

那有了inquirer之后接下来我们要考虑的就是动态的去生成我们的项目文件。

我们一般会根据模板去生成,所以我们在项目的跟目录下新建一个templates目录,在这个目录下我们去新建一些模板。

由于我们这里是讨论脚手架的工作过程,所以我们也不去关心模板里面有什么,我们就随便写点什么。我们可以通过 <%%>去替换询问过程中得到的答案。

index.html

<head>    <title><%= name %></title></head>

我们还可以添加一些其他的模板文件,比如style.css

style.css

body {    margin: 0;    background-color: red;}

回到cli.js文件, 这时候我们可以在得到问题答案的位置,根据用户回答的问题去生成文件。不过在生成前我们一般会先将模板路径和目标目录确定下来。

模板的目录应该是项目当前目录的templates,我们可以通过path获取。

const path = require('path');
// 工具当前目录const tmplDir = path.join(__dirname, 'templates');

输出的目标目录一般是我们命令行在哪个目录去执行就应该是哪个路径,也就是cwd目录

const path = require('path');
// 工具当前目录const tmplDir = path.join(__dirname, 'templates');// 命令行所在目录const destDir = process.cwd();

明确这两个目录,我们就可以通过fs模块去读取一下模板目录下一共有哪些文件。把这些文件全部输入到我们的目标目录,我们通过fs的readDir方法,这个方法会自动扫描目录下的所有文件

fs.readdir(tmplDir, (err, files) => {    if (err) {        throw err;    }    files.forEach(file => {        console.log(file); // 得到每个文件的相对路径    })})

我们可以通过模板引擎去渲染路径对应的文件,先去安装一款模板引擎,这里我们使用ejs

yarn add ejs --dev

安装过后,回到代码中引入这个模板引擎, 通过模板引擎提供的renderFile去渲染这个路径对应的文件。

第一个参数是文件的绝对路径,第二个参数是模板引擎在工作的时候的数据上下文,第三个参数是回调函数,也就是我们在渲染成功过后的回调函数,当然如果你在渲染过程中出现了意外那你可以通过throw err的方式把这个错误抛出去。

我们可以先把result通过打印的方式打印出来看一下。

const fs = require('fs');const path = require('path');const inquirer = require('inquirer');const ejs = require('ejs');
// 工具当前目录const tmplDir = path.join(__dirname, 'templates');// 命令行所在目录const destDir = process.cwd();
inquirer.prompt([    {        type: 'input',        name: 'name',        message: 'Project name'    }]).then(answer => {    fs.readdir(tmplDir, (err, files) => {        if (err) {            throw err;        }        files.forEach(file => {            ejs.renderFile(path.join(tmplDir, file), answer, (err, result) => {                if (err) {                    throw err;                }                console.log(result);            })        })    })})

编辑完成之后我们运行一下脚手架工具。

sample-cli

此时打印出来的这个结果其实是已经经过模板引擎工作过后的结果,我们只需要将这个结果通过文件写入的方式写入到目标目录就可以了,那目标目录应该是通过path.join把我们destDir以及我们的file做一个拼接。内容就是我们这里的result。

files.forEach(file => {    ejs.renderFile(path.join(tmplDir, file), answer, (err, result) => {        if (err) {            throw err;        }        fs.writeFileSync(path.join(destDir, file), result);    })})

完成过后我们找到一个新的目录,使用一下这个脚手架

sample-cli

我们输入项目名称过后,就会发现他会自动把我们模板里面的文件自动生成到对应的目录里面,至此我们就已经完成了一个非常简单,非常小型的一个脚手架应用。

那我们也回顾了一下脚手架的工作过程,其实脚手架的工作原理并不复杂,但是他的意义却是很大的,因为他确实在创建项目环节大大提高了我们的效率。

我们可以将自己的工具发布至npm上,提供给更多的人使用。

至于发布npm也非常的简单,首先我们需要注册npm账号,有两种方式可以注册,一种是登录npm官网https://www.npmjs.com/, 另一种是使用命令npm adduser。

npm adduser

会提示你输入用户名,密码,以及邮箱。

注册好后登录npm账号。

npm login

依次输入第二步中第一种方法注册的用户名、密码和邮箱。

登录成功后执行npm发布命令。

npm publish

注意:如果报错:'You do not have permission to publish "samlpe-cli". Are you logged in as the correct user?'

表示包samlpe-cli名字已经在包管理器已经存在被别人用了,需要更该包名称,我们可以前往package.json中的name中换一个名字。

{  "name": "sample-cli1",  "version": "1.0.0",  "bin": "cli.js",  ...}

再次执行publish命令。出现 +sample-cli1@1.0.0即表示发布成功。

如果发布时报错:no_perms Private mode enable, only admin can publish this module:

表示当前不是原始镜像,要切换回原始的npm镜像

npm config set registry https://registry.npmjs.org/

至此你的node工具就可以提供给其他人使用了。

如果需要更新你的工具,只要继续执行npm publish就可以更新发布了,不过需要注意,每次发布都需要修改版本号version的值,同一个版本不允许发布两次。

{  "name": "sample-cli1",  "version": "1.0.1",  "bin": "cli.js",  ...}

如果想要撤销本次发布可以执行

npm unpublish

不过需要注意,只有在发包的24小时内才允许撤销发布的包,超过24小时,就无法撤回了。

本文完〜

如何开发一款前端工具相关推荐

  1. 利用Python3开发一款小工具(界面的设计)

    前面在<利用Python3开发一款小工具(引言)>文章中,对我们的需求进行了分析.为了能够让用户运行该工具,因此我们需要一个ui界面,而python中常用的工具就是pyqt,本文将使用py ...

  2. Linux开发5款实用工具推荐

    今天安利给大家5款实用的Linux开发工具,希望对大家工作效率的提升有所帮助. 容器 放眼于现实,现在已经是容器的时代了.容器既及其容易部署,又可以方便地构建开发环境.如果你针对的是特定的平台的开发, ...

  3. 利用Python3开发一款小工具(环境配置)

    前面一篇文章对开发的小工具的需求进行了分析,已经大致清楚了我们需要使用的工具,本文将逐个工具进行安装配置,主要包括: 1.python36安装 2.pycharm安装 3.pyqt5与pyqt5-to ...

  4. 这50款前端热门工具简直不要太好用了!

    来源 | IT智云编程 19年,又是新的一年,"前端届",又出了哪些新的"玩意",今天向你推荐目前比较热门新鲜度靠前的50款前端工具,希望在新的一年里,对你有所 ...

  5. 50个好用的前端工具,建议收藏!

    来源 | https://www.jianshu.com/p/182b69e54fe8 今天跟你分享一些目前比较热门新鲜度靠前的50款前端工具,希望对你有所帮助. 一.构建工具 1. Parcel 地 ...

  6. 他开发了汉语编程工具

    <电脑报>文章 作者:陈嘉颂  发表时间:2005年1月5日 他曾经和朱崇君一起开发CCED--       如今,他想自己挑战VB.Delphi--       编程一定要记住那许多英文 ...

  7. 174款前端开发工具汇总,学习,开发,事半功倍!

    我们与企业内部的Web开发团队进行了很多次交流,研究了很长时间,最后将Debug工具与Web前端开发工具整理汇总在了一起,这些工具对每个Web开发人员都非常有用. 这些工具将使您的工作更加轻松,特别是 ...

  8. 【 Apifox】一款前端开发、后端开发、测试人员连连叫好的开发工具

    Apifox官网地址:http://apifox.cn/a103abcc 前言 作为一名程序员,除了开发之外最重要的事就是测试了,谈到测试我们避免不了的事就是如何选择测试工具. 在后端开发我们经常配置 ...

  9. 加速 Web 开发的 23 款前端开发工具

    市面上有许多前端开发工具可以加速 Web 开发工作.本文是对 2019 年顶级 Web 开发工具的一次精选汇总,分别介绍了每款工具的关键特性,并已附上下载链接. Novi Builder Novi B ...

最新文章

  1. vue-typescript-toast (一款适用于pc平台的简单toast)
  2. 各厂商服务器存储设备默认密码大全
  3. java 今天 昨天_js获取当前时间(昨天、今天、明天)
  4. JavaScript语言特性
  5. OpenJudge/Poj 1915 Knight Moves
  6. 企业实战_21_MyCat_keepalived 安装配置验证
  7. splay学习小记[未完结]
  8. 尽量不要在viewWillDisappear:方法中移除通知
  9. 图解!24 张图彻底弄懂九大常见数据结构!
  10. java性能调试命令_性能测试必备监控技能jvm之jdk命令行工具篇16
  11. 【CS229】向量化
  12. ECSHOP首页调用指定分类推荐商品/热卖商品/新品商品
  13. cad面积累计lisp怎么用_CAD连续面积标注lisp插件
  14. 蚂蚁算法matlab
  15. EJB开发web service
  16. php得到当前时间戳,php获取当前时间戳的方法
  17. 发一些乙醇原创的资料
  18. 乘法和绝对值的C语言,关于C语言的函数调用与绝对值用法!
  19. Android自定义控件(一)
  20. 如何使用docker容器中的redis

热门文章

  1. POI列子:替换文本框值
  2. 基于STM32 Cortex-M3内核F103制作的智能小车项目
  3. 3dsMax2022插件开发-对齐样条线中顶点的插件(英)
  4. python多个strip_python 中strip方法
  5. 使用容量时间证明和类Casper确定性装置带来快速确定和抗长程攻击
  6. class AdamWeightDecayOptimizer(tf.train.Optimizer): AttributeError: module ‘tensorflow._api.v2.tra
  7. CSS使用彩色字体图标(Vue/Uni)
  8. TX2 刷机 安装 jetpack 卡在determining IP adress问题
  9. 李航《统计学习方法》学习日记【1】
  10. 4.17 使用阴影/高光命令解决图像曝光不足问题 [原创Ps教程]