在第 42 期的文章:从零开始使用JavaScript制作自己的命令行(CLI工具) 中我们介绍如何从零开始制作CLI,算是一个入门前传,知道了怎么制作CLI后今天更进一步。

在这篇文章中,我们将构建一个简单的CLI,允许用户生成HTML页面。我们首先要生成一个标准的空白页面,然后让用户输入参数,比如文件名和标题,先通过选项,然后通过提示问题让用户输入参数。

创建 Hello World CLI

创建用于编写CLI的文件夹。我将其命名为 html-generator-cli。打开一个终端,然后在此文件夹中运行:

npm init

该命令会有几个问题要问你,顺便说一下,这正是我们最终希望在空白HTML页面生成器中包含的内容。这将在文件夹中生成 package.json 文件:


我们需要创建包的 index.js 文件作为入口在package.json中引入。在这个文件中,写入下面代码:

console.log('Hello World!');

现在我们需要创建运行这段代码的命令。

{"name": "html-generator-cli","version": "1.0.0","description": "","main": "index.js","scripts": {"test": "echo \"Error: no test specified\" && exit 1"  },"keywords": [],"author": "","license": "ISC","bin": "index.js"}

将最后一行添加到package.json中。现在,我们可以测试我们非常简单的CLI。在项目文件夹中局安装我们新创建的包到本机:

npm install -g ../html-generator-cli

打开一个新终端并运行:

html-generator-cli

如果您使用Windows,现在应该会看到“Hello World!”。在您的终端中。如果您使用的是基于UNIX的操作系统,则应该得到一个错误,可能与语法错误和意外的token有关。我本人用的是Mac,结果人如下


这是因为与Windows不同,基于UNIX的系统不关心文件的扩展名(此处为“.js”),因此不知道使用哪种语言。我们必须告诉系统使用Node运行脚本。为此,我们在文件的开头添加一条注释行:

#!/usr/bin/env node

console.log('Hello World!');

创建一个空白的HTML页面

我们要创建一个CLI来生成HTML文件,为此,我们将使用Node.js文件系统模块。该模块是Node内置模块,提供与文件系统交互的API,也就是说可以创建、读取、修改和删除文件。我们只需要使用文件系统模块的 writeFile 方法即可,该方法允许你创建文件。

#!/usr/bin/env node

const fs = require('fs');

const html = `Title`;

fs.writeFile('index.html', html, error => {if (error) {console.log(error);  }});

如果您再次在终端中保存并运行 html-generator-cli,现在应该在文件夹中看到一个 index.html 文件。

将参数传递给代码

现在我们生产的文件名和HTML中的 title 标签内容是写死的,我们应该可以将文件名和标题作为参数传递给CLI。要传递参数,你只需在命令之后写上参数,然后这些参数就可以在一个名为 argv 的变量中提供给进程。

在代码中编写如下代码:

const args = process.argv;console.log(args);

并在终端中运行它:

html-generator-cli hello haha

然后,你应该在控制台中看到一个包含参数作为字符串的数组:


传递的参数在数组的最后两项,我们只需要使用数组的 slice(2) 方法即可拿到。我们决定第一个输入参数是文件名(不带HTML扩展名),第二个参数将是HTML页面的标题。这些参数都不是必需的,如果没有提供名称和标题,则我们将文件称为index.html,标题为“Title”。

#!/usr/bin/env node

const fs = require('fs');

const args = process.argv.slice(2);

let fileName = args[0] ? `${args[0]}.html` : 'index.html';let title = args[1] || 'Title';

const html = `${title}`;

fs.writeFile(fileName, html, error => {if (error) {console.log(error);  }});

我们保持简单,不验证用户输入的情况,用户可能会给该文件指定了无效的名称,这是你在实际工作中必须验证的内容。

现在,你可以在终端中尝试以下操作:

html-generator-cli page "new generator"

结果


使用参数选项

先前的方法易于实现,但有一些缺点:用户必须知道期望哪些参数以及以什么顺序。如果他不想给出文件名,他也没有办法给出标题,我们可以通过创建选项来改善这一点。

与其一个接一个地写参数,我们可以构建我们的CLI,让用户输入类似于这样的文件名和/或标题。

html-generator-cli --file-name page --html-title "new generator"

写起来有点长,但是用户更清楚他给出的参数是什么,顺序不再起作用,你可以给出一个标题,即使你没有给出任何文件名。

const args = process.argv;

const FILE_NAME_OPTION = '--file-name';const HTML_TITLE_OPTION = '--html-title';

const fileNameOptionIndex = args.findIndex(arg => arg === FILE_NAME_OPTION);const htmlTitleOptionIndex = args.findIndex(arg => arg === HTML_TITLE_OPTION);

const fileNameOption = fileNameOptionIndex > -1 && args[fileNameOptionIndex + 1];const titleOption = htmlTitleOptionIndex > -1 && args[htmlTitleOptionIndex + 1];

let fileName = fileNameOption ? `${fileNameOption}.html` : 'index.html';let title = titleOption || 'Title';

现在,我们在参数数组 args 中获得选项 --file-name--html-title 的索引。如果存在一个选项,那么要给文件名或标题的值就是参数数组中 --file-name--html-file 之后的元素。如果不存在选项,则其索引将为 -1。如果此索引为 -1 或参数数组中该选项之后没有任何值,我们分别为文件名或标题提供默认值。其余代码未更改。

你可以运行新的CLI,如果没有选择,它将创建标题为“Title”的index.html文件。如果你编写一个选项但忘记提供一个值,它将也提供默认值。如果你正确地使用给定的选项编写命令,那么它应该创建一个具有正确名称和正确HTML标题的文件。

html-generator-cli --file-name hello --html-title "CLI helloworld!"

效果


同样,在实际的CLI中,你会希望多检查一些输入,首先要确保用户输入的值是有效的,但也要在缺失值或选项出现两次的情况下警告他们。

向用户询问参数

使用选项已经是一种改进了,但是它仍然需要用户知道他可以传递什么参数以及使用哪个标记。当你初始化你的npm项目时,你可以通过很多东西作为选项。CLI会直接问您一些问题,因此您无需阅读文档即可了解如何提供项目名称,版本等信息。

要从控制台读取用户输入,我们需要Node(自版本7)提供的模块 readline。你可以使用以下代码在终端中对其进行测试:

const readline = require('readline');

const interface = readline.createInterface({input: process.stdin,output: process.stdout});

interface.question('你叫什么名字?', answer => {console.log(`Hello ${answer}`);  interface.close();});

效果如下


为了生成我们的HTML页面,我们首先要询问文件名,然后询问标题。如果用户没有输入任何内容,我们将获得默认值。我们向用户显示默认值是什么,以便在默认值正确的情况下可以跳过该问题。

#!/usr/bin/env node

const fs = require('fs');const readline = require('readline');

let fileName = 'index.html';let title = 'Title';

const interface = readline.createInterface({input: process.stdin,output: process.stdout});

interface.question(`File name (${fileName}): `, answer => {if (answer && answer.length) {    fileName = `${answer}.html`;  }

  interface.question(`HTML title (${title}): `, answer => {if (answer && answer.length) {      title = answer;    }    interface.close();

const html = `${title}      `;

    fs.writeFile(fileName, html, error => {if (error) {console.log(error);      }    });  });});

如果你在终端中运行它,将会询问两个问题。


用户不必了解您的CLI选项,所有重要的事情都可以直接询问。但是,你应该只以这种方式询问主要配置问题,并让用户阅读文档以了解不太常见的选项。

结束

我们使用Node和npm创建了一个简单的CLI,允许用户生成一个空白的HTML文件,是不是非常简单?你可以通过添加新选项并验证用户输入来改进此示例。


推荐阅读CSS中的间距,前端开发中各种设置间距的优点缺点及实例

你不知道的CSS国际化

React.js和Vue.js的语法并列比较老板知道会点赞,前端开发人员的10个安全建议Web中的图像技术总结与实践温故知新 | Vue.js进阶必会,编写你的第一个Vue.js插件从零开始使用JavaScript制作自己的命令行(CLI工具)Vue.js中编写更好的v-for循环的6种技巧

感谢您的阅读和关注,看完三件事:如果对你有帮助,帮忙文章右下角点个在看如果有什么问题欢迎留言交流,还可以转发,这是对作者最大的帮助。

生成html_HTML页面生成器:使用JavaScript和Node创建CLI相关推荐

  1. html页面生成器使用教程,实战 | HTML页面生成器:使用JavaScript和Node创建CLI

    上一篇文章:实战 | 从零开始使用JavaScript制作自己的命令行(CLI工具) 中介绍了如何从零开始制作CLI,只是一个简单的示例,今天更进一步,来制作一个实际的程序,生成HTML模板. 在这篇 ...

  2. node.js htttp文件服务器 遇到目录时搜索目录内默认html页面 廖雪峰javascript教程node.js中http部分练习题

    廖雪峰javascript教程node.js中http部分最后的练习题: https://www.liaoxuefeng.com/wiki/1022910821149312/1023025830950 ...

  3. mongodb索引生成HTML页面,mongodb高阶:索引创建、聚合查询、复制集、分片、创建备份和部署...

    先前我们讨论了mongodb的进阶查询:投影查询.分页查询以及对查询结果进行排序,从本节起我们开始学习mongodb相关的高级技术,首先我们会讨论mongodb如何创建索引,索引是数据库中最重要的东西 ...

  4. java 生成静态页面——Freemarker实例教程

    转载地址:http://blog.csdn.net/wangliqiang1014/article/details/20048629 版权声明:本文为博主原创文章,未经博主允许不得转载. 一.Free ...

  5. 学习小技巧---javascript中获取服务器端控件生成的页面ID

    刚刚看了BlogEngine中的一段代码,发现如下一段代码: function PreviewTheme() {  var theme=document.getElementById('<%=d ...

  6. 页面生成器实现及源码下载

    关注公众号 前端开发博客,回复"加群" 加入我们一起学习,天天进步 作者:muwoo 链接:https://zhuanlan.zhihu.com/p/48347377 最近更新: ...

  7. 制作生成静态页面的新闻系统

    利用PHP生成静态HTML页面的好处很多: 1.静态页面不需要Web服务器解释执行,用户打开网页的速度会快些: 2.打开静态页面时,Web服务器不需要访问数据库,减轻了对数据库访问的压力: 3.静态H ...

  8. 使用 AjaxManager 生成调用服务器端方法的 javascript 函数

    通过 AjaxManager, 我们可以方便的生成调用 WebService 或者一般处理程序的 javascript 函数, 这样就可以方便的在客户端调用. 本文更新: 2011-12-12: 去掉 ...

  9. 从Sun离职后,我“抛弃”了Java,拥抱JavaScript和Node

    我是前Sun公司Java SE团队的一名成员,在工作了10多年之后--2009年1月--也就是在甲骨文收购Sun公司之前,我离开了公司,然后迷上了Node.js. 我对Node.js的痴迷到了怎样的程 ...

最新文章

  1. wxWidgets:wxBitmap类用法
  2. UI-UIScrollView
  3. Jfinal 显示欢迎页 index.jsp
  4. 通信接口主要的5种类型_5种常见的住宅建筑结构类型,你真的了解吗?
  5. [置顶] android 自定义圆角ImageView以及锯齿的处理
  6. Java基础学习教程,eclipse简单使用教程(Java集成开发工具)
  7. oracle去除字段值的所有英文
  8. Inspection工具窗口
  9. php tp5生成条形码,TP5条形码
  10. 链表上手代码---表头插入
  11. Tafel 曲线绘制
  12. 寻找NOD32升级服务器不求人
  13. layui laydate设置最小时间为当前时间
  14. JAVA中的arraylist集合,Java ArrayList集合
  15. 处理txt文件下载下来以后,排版格式不对的问题
  16. MySql ocp认证之备份与恢复(四)
  17. 实验记录 | 8/14
  18. 50台同样配置的计算机装系统,几十台PC如何同时安装系统
  19. Linux的软件包封装格式有,RED HAT LINUX所提供的安装软件包,默认的打包格式为( )。...
  20. 白鲸优化(BWO)算法(含MATLAB代码)

热门文章

  1. 从Uber微服务看最佳实践如何炼成?
  2. nanodet onnx踩坑记录
  3. torch 归一化,momentum用法详解
  4. eccv2020 目标检测笔记
  5. float16/32/64对神经网络计算的影响
  6. C++ 32位和64位
  7. PaddlePaddle yolov3
  8. Python3中使用map()结果出错的解决方法
  9. pyhton object is not subscriptable 解决
  10. fast-rcnn练习资料整理