搭建一个nodejs脚手架的方法步骤


Posted in NodeJs onJune 28, 2019

1 前言

1.1

像我们熟悉的 vue-cli,taro-cli 等脚手架,只需要输入简单的命令 taro init project ,即可快速帮我们生成一个初始项目。在日常开发中,有一个脚手架工具可以用来提高工作效率。

1.2 为什么需要脚手架

  1. 减少重复性的工作,从零创建一个项目和文件。
  2. 根据交互动态生成项目结构和配置文件等。
  3. 多人协作更为方便,不需要把文件传来传去。

1.3 怎样来搭建呢?

脚手架是怎么样进行构建的呢,我是借助了 taro-cli 的思路。

1.4 本文的目标读者

1 想要学习更多和了解更多的人
2 对技术充满热情

2 搭建前准备

2.1 第三方工具

commander.js ,可以自动的解析命令和参数,用于处理用户输入的命令。
download-git-repo ,下载并提取 git 仓库,用于下载项目模板。
Inquirer.js ,通用的命令行用户界面集合,用于和用户进行交互。
handlebars.js ,模板引擎,将用户提交的信息动态填充到文件中。
ora ,下载过程久的话,可以用于显示下载中的动画效果。
chalk ,可以给终端的字体加上颜色。
log-symbols ,可以在终端上显示出 √ 或 × 等的图标

2.2 上手

2.2.1 新建一个文件夹,然后npm init初始化

npm 不单单用来管理你的应用和网页的依赖,你还能用它来封装和分发新的 shell 命令。

$ mkdir lq-cli
$ npm init

这时在我们的 lq-cli 项目中有 package.json 文件,然后需要创建一个 JS 文件包含我们的脚本就取名 index.js 吧。 package.json 内容如下

{
 "name": "lq-shell",
 "version": "1.0.0",
 "description": "脚手架搭建",
 "main": "index.js",
 "bin": {
  "lq": "./index.js"
 },
 "scripts": {
  "test": "test"
 },
 "keywords": [
  "cli"
 ],
 "author": "prune",
 "license": "ISC"
}

index.js内容如下

#!/usr/bin/env node

console.log('Hello, cli!');

到这一步就可以简单运行一下这个命令

npm link
lq

npm link 命令可以将一个任意位置的 npm 包链接到全局执行环境,从而在任意位置使用命令行都可以直接运行该 npm 包。 控制台会输出 Hello, cli!

2.2.2 捕获init之类的命令

前面的一个小节,可以跑一个命令行了,但是我们看到的 taro-cli 中还有一些命令,init初始化项目之类。这个时候 commander 就需要利用起来了。 运行下面的这个命令将会把最新版的 commander 加入 package.json

npm install --save commander

引入 commander 我们将 index.js 做如下修改

#!/usr/bin/env node

console.log('Hello, cli!')

const program = require('commander')
program
 .version(require('./package').version, '-v, --version')  
 .command('init <name>')
 .action((name) => {
   console.log(name)
 })
 
program.parse(process.argv)

可以通过 lq -v 来查看版本号 通过 lq init name 的操作,action里面会打印出name

2.2.3 对console的美工

我们看到taro init 命令里面会有一些颜色标识,就是因为引入了chalk这个包,同样和 commander 一样

npm install --save chalk

console.log(chalk.green('init创建'))

这样会输出一样绿色的

2.2.4 模板下载

download-git-repo 支持从 Github下载仓库,详细了解可以参考官方文档。

npm install --save download-git-repo

download() 第一个参数就是仓库地址,详细了解可以看官方文档

2.2.5 命令行的交互

命令行交互功能可以在用户执行 init 命令后,向用户提出问题,接收用户的输入并作出相应的处理。用 inquirer.js 来实现。

npm install --save inquirer

index.js文件如下

#!/usr/bin/env node
const chalk = require('chalk')
console.log('Hello, cli!')
console.log(chalk.green('init创建'))
const program = require('commander')
const download = require('download-git-repo')
const inquirer = require('inquirer')
program
 .version(require('./package').version, '-v, --version')  
 .command('init <name>')
 .action((name) => {
   console.log(name)
   inquirer.prompt([
    {
      type: 'input',
      name: 'author',
      message: '请输入你的名字'
    }
   ]).then((answers) => {
    console.log(answers.author)
    download('',
     name, {clone: true}, (err) => {
     console.log(err ? 'Error' : 'Success')
    })
   })
   
 })
program.parse(process.argv)

2.2.6 ora进度显示

npm install --save ora

相关命令可以如下

const ora = require('ora')
// 开始下载
const proce = ora('正在下载模板...')
proce.start()

// 下载失败调用
proce.fail()

// 下载成功调用
proce.succeed()

2.2.6 log-symbols 在信息前面加上 √ 或 × 等的图标

npm install --save log-symbols

相关命令可以如下

const chalk = require('chalk')
const symbols = require('log-symbols')
console.log(symbols.success, chalk.green('SUCCESS'))
console.log(symbols.error, chalk.red('FAIL'))

2.2.7 完整文件如下

#!/usr/bin/env node
const chalk = require('chalk')
console.log('Hello, cli!')
console.log(chalk.green('init创建'))
const fs = require('fs')
const program = require('commander')
const download = require('download-git-repo')
const inquirer = require('inquirer')
const ora = require('ora')
const symbols = require('log-symbols')
program
 .version(require('./package').version, '-v, --version')  
 .command('init <name>')
 .action((name) => {
   console.log(name)
   inquirer.prompt([
    {
      type: 'input',
      name: 'author',
      message: '请输入你的名字'
    }
   ]).then((answers) => {
    console.log(answers.author)
    const lqProcess = ora('正在创建...')
    lqProcess.start()
    download('github:/Mr-Prune/learn/mongodb-koa',
     name, {clone: true}, (err) => {
     if (err) {
      lqProcess.fail()
      console.log(symbols.error, chalk.red(err))
     } else {
      lqProcess.succeed()
      const fileName = `${name}/package.json`
      const meta = {
       name,
       author: answers.author
      }
      if(fs.existsSync(fileName)){
       const content = fs.readFileSync(fileName).toString();
       const result = handlebars.compile(content)(meta);
       fs.writeFileSync(fileName, result);
     }
     console.log(symbols.success, chalk.green('创建成gong'))
     }
    })
   })
   
 })
program.parse(process.argv)

总结

通过上面的例子只是能够搭建出一个简单的脚手架工具,其实bash还可以做很多东西,比如 npm 包优雅地处理标准输入、管理并行任务、监听文件、管道流、压缩、ssh、git等,要想了解更多,就要深入了解,这里只是打开一扇门,学海无涯。

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

NodeJs 相关文章推荐
golang、python、php、c++、c、java、Nodejs性能对比
Mar 12 NodeJs
轻松创建nodejs服务器(7):阻塞操作的实现
Dec 18 NodeJs
Nodejs实现短信验证码功能
Feb 09 NodeJs
深入理解nodejs中Express的中间件
May 19 NodeJs
nodejs socket实现的服务端和客户端功能示例
Jun 02 NodeJs
nodejs 搭建简易服务器的图文教程(推荐)
Jul 18 NodeJs
在Debian(Raspberry Pi)树莓派上安装NodeJS的教程详解
Sep 19 NodeJs
Nodejs Express 通过log4js写日志到Logstash(ELK)
Aug 30 NodeJs
深入理解nodejs搭建静态服务器(实现命令行)
Feb 05 NodeJs
详解nodejs http请求相关总结
Mar 31 NodeJs
nodejs如何在package.json中设置多条启动命令
Mar 16 NodeJs
分享node.js实现简单登录注册的具体代码
Apr 26 NodeJs
独立部署小程序基于nodejs的服务器过程详解
Jun 24 #NodeJs
nodejs实现获取本地文件夹下图片信息功能示例
Jun 22 #NodeJs
NodeJs 模仿SIP话机注册的方法
Jun 21 #NodeJs
通过Nodejs搭建网站简单实现注册登录流程
Jun 14 #NodeJs
NodeJs生成sitemap站点地图的方法示例
Jun 11 #NodeJs
nodejs提示:cross-device link not permitted, rename错误的解决方法
Jun 10 #NodeJs
Nodejs异步流程框架async的方法
Jun 07 #NodeJs
You might like
php中全局变量global的使用演示代码
2011/05/18 PHP
php利用腾讯ip分享计划获取地理位置示例分享
2014/01/20 PHP
PHP随机生成唯一HASH值自定义函数
2015/04/20 PHP
Java中final关键字详解
2015/08/10 PHP
支持汉转拼和拼音分词的PHP中文工具类ChineseUtil
2018/02/23 PHP
php模式设计之观察者模式应用实例分析
2019/09/25 PHP
javascript 放大镜效果js组件 qsoft.PopBigImage.v0.35 加入了chrome支持
2009/04/07 Javascript
JavaScript Memoization 让函数也有记忆功能
2011/10/27 Javascript
js函数调用常用方法详解
2012/12/03 Javascript
Javascript学习笔记之 对象篇(三) : hasOwnProperty
2014/06/24 Javascript
JavaScript字符串对象的concat方法实例(用于连接两个或多个字符串)
2014/10/16 Javascript
javascript结合Canvas 实现简易的圆形时钟
2015/03/11 Javascript
复杂的javascript窗口分帧解析
2016/02/19 Javascript
jQuery插入节点和移动节点用法示例(insertAfter、insertBefore方法)
2016/09/08 Javascript
js实现3D图片展示效果
2017/03/09 Javascript
angularJs提交文本框数据到后台的方法
2018/10/08 Javascript
详解nodejs 开发企业微信第三方应用入门教程
2019/03/12 NodeJs
vue本地打开build后生成的dist文件夹index.html问题
2019/09/04 Javascript
node 解析图片二维码的内容代码实例
2019/09/11 Javascript
layer 关闭指定弹出层的例子
2019/09/25 Javascript
Vue组件模板及组件互相引用代码实例
2020/03/11 Javascript
[08:07]DOTA2每周TOP10 精彩击杀集锦vol.8
2014/06/25 DOTA
[02:09:59]火猫TV国士无双dota2 6.82版本详解(下)
2014/09/29 DOTA
Python使用smtplib模块发送电子邮件的流程详解
2016/06/27 Python
在python中只选取列表中某一纵列的方法
2018/11/28 Python
python pytest进阶之xunit fixture详解
2019/06/27 Python
Python如何操作docker redis过程解析
2020/08/10 Python
统计员岗位职责
2013/11/14 职场文书
行政部总经理岗位职责
2014/01/04 职场文书
助人为乐表扬信范文
2014/01/14 职场文书
党员对十八届四中全会的期盼思想汇报范文
2014/10/17 职场文书
礼仪培训心得体会
2016/01/22 职场文书
2019毕业论文致谢词
2019/06/24 职场文书
使用Django实现商城验证码模块的方法
2021/06/01 Python
centos7安装mysql5.7经验记录
2022/05/02 Servers
Hive常用日期格式转换语法
2022/06/25 数据库