当前位置:网站首页 > Node.js开发 > 正文

手把手教你编写Node.js模块_node编程

编写稍复杂的程序时,一般会先将代码模块化。

在Node.js中,一般会将代码合理拆分到不同的JavaScript文件中,每一个文件就是一个模块,而文件路径就是模块名。

在编写模块代码时要遵循CommonJS规范(新版Node.js已经支持ES Module规范,但不建议两种规范混用)。

同时,还要结合npm简单发布流程,让开发者体会到快速开发和快速发布功能的强大之处。

因为有如此强大的功能,npm生态始终繁荣。

通过npm安装的Node.js模块主要分为以下两种。

  • 普通模块:提供API调用。
  • 二进制模块:命令行工具,供CLI调用。

初始化模块

要想创建一个Node.js模块,需要想清楚它的名称、定位、功能。

首先,确认模块名称。如果在npm中没有找到对应的包,说明可以使用这个名称。

$ npm info xxxxxx

接下来要初始化模块。在GitHub上建立仓库,然后通过git clone命令将代码克隆到本地。

$ git clone xxx
$ npm init -y


package.json文件为模块的描述文件,非常重要。一般会通过执行npm init命令来创建package.json文件。它会读取Git配置信息,所以最好先建立Git项目,这样改动会比较少。

执行npm init -y,生成的默认package.json文件内容如下。

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


关于以上文件的内容要点,说明如下。

  • main是入口文件,即对外提供调用功能的API入口。
  • scripts是npm脚本在package.json文件中的配置内容。只要在package.json文件所在的目录下,执行npm test命令就会调用这里的test配置。
  • keywords是在npm中搜索时的关键字,要想进行推广必须精细处理。
  • author是作者信息。
  • license是开源协议。

普通模块

创建一个简单的函数,代码如下。这样一来,我们就拥有了一个简单的可发布模块。

module.exports = function (name) {
    console.log('hello ' + name)
}


当然,如果想完善内容,还需要在模块中添加测试、文档等,这里只是为了让大家简单体验,开发真正的开源项目时切不可这样随意。

在通过npm发布模块之前,需要注册npmjs账户。这里需要说明的是,npm中有registry概念,也就是说,npmjs.com是官方源,但registry之间是不互通账户的。由于分发操作以npmjs作为主镜像,所以发布模块都是在npmjs上进行的,很少有在其他源上直接发布的。

$ npm login   // 只需要登录一次
$ nrm use npm // 确保是官方源
$ npm publish // 将当前项目发布到官方源


每次都要注意registry的问题还是比较麻烦的。为了解决这个问题,著名的Node.js开发者Sindre Sorhus编写了np模块,安装命令如下。

$ npm install --global np
$ np


输入np命令后,可以根据选型来完成发布动作,这一点还是非常方便的,如图1所示。

图1

np模块的常见用法如下。

$ np --help


  Usage
    $ np <version>


    Version can be:
      patch | minor | major | prepatch | preminor | premajor | prerelease | 1.2.3


  Options
    --any-branch  Allow publishing from any branch
    --no-cleanup  Skips cleanup of node_modules
    --yolo        Skips cleanup and testing
    --no-publish  Skips publishing
    --tag         Publish under a given dist-tag
    --no-yarn     Don't use Yarn
    --contents    Subdirectory to publish


  Examples
    $ np
    $ np patch
    $ np 1.0.2
    $ np 1.0.2-beta.3 --tag=beta
    $ np 1.0.2-beta.3 --tag=beta --contents=dist


通过以上示例,我们不仅可以了解np的用法,还可以类比学习patch、minor、major的用法,由一个点延伸到另一个点,这对学习来说是极有帮助的。


二进制模块

工作中会接到各种项目开发需求,开发前需要先规划项目目录,然后一个个创建文件,搭建Sass编译环境,下载jQuery、React等类库,做完这些准备工作要花费不少时间。

那么问题来了,每做一个项目都要完成这些准备工作,难道要不断重复这个过程吗?当然不需要!使用np就能节省很多时间。

前端工程化的思想便是在解决上述问题的过程中产生的。根据具体的业务特点,将前端开发流程、技术、工具、经验等规范化和标准化,可以最大限度地提高前端开发工程师的开发效率,降低技术选型难度和前后端联合调试的沟通成本。

使用命令工具是开发者的必备技能,也是前端工程化落地的必要组成部分。

Node.js二进制模块中常用的CLI命令工具分类如下。

  • 命令行工具。
  • 脚手架:express-generator、koa-generator。
  • 与构建相关的工具:Webpack、Gulp、Grunt。
  • shell相关工具。
  • kp:用于根据端口“杀死”进程。
  • mongo-here:启动MongoDB的简化命令工具。
  • 本地服务器:je模块。

以上是笔者常用的CLI命令工具,无论哪一种都值得学一学,学会这些工具的使用方法对提高开发效率有很大帮助。

创建文件

下面我们具体看一下如何编写Node.js命令行模块,代码如下。

// 创建目录
$ mkdir bin  // 存放可执行文件目录
// 创建文件
$ touch bin/cli.js
$ touch index.js


在bin/cli.js中键入如下代码。

#!/usr/bin/env node


 console.log('hello node module')


一般情况下,index.js会作为普通模块对外提供API,bin/cli.js中提供的实现命令行功能的文件也会直接使用index.js里的API。

这样做的好处是,逻辑代码都在index.js里,模块既可以是普通模块,也可以是二进制模块,这是Node.js中非常常见的做法。

修改package.json文件

如果想把模块设定成二进制模块,需要在package.json文件里键入如下内容。

  "bin": {
    "hello": "bin/cli.js"
  }


此处是关键,通过bin字段可以确定当前模块是不是二进制模块。bin字段是用来配置CLI命令名称和具体执行逻辑的脚本文件,比如上面的hello就是模块需要提供的CLI命令名称,它对应的Node.js脚本文件是bin/cli.js。

在package.json文件中配置好bin字段后,就可以在本地进行测试了,方法如下。

// 通过npm link将hello命令放入本地环境变量
$ npm link  
// 执行hello命令
$ hello
hello node module


比如我们想执行hello -h(等同于hello -help)该怎么办呢?主要办法是解析process.argv文件,它会返回由命令行脚本的各个参数组成的数组,具体代码如下。

#!/usr/bin/env node




var argv = process.argv;
argv.shift();




var file_path = __dirname;
var current_path = process.cwd();




for(var i in argv){
  var _argv = argv[i];
  if(_argv == '-h'  || _argv == '--help'){
    console.log('this is help info')
  }
}


此时,执行hello -h命令会打印出帮助信息,结果如下。

$ node cli.js -h
this is help info


npm脚本

为了开发便利,一般我们会修改npm脚本,缩短执行命令的长度。另外,脚本也可以提供一些命令行工具所不具备的能力。还是以上面的代码为例,我们可以对scripts字段进行重写,代码如下。

"scripts": {
  "start": "npm publish .", // 发布
  "test": " node bin/cli -t js -n q " // 手动测试
},


以上代码中定义了两个命令,具体如下。

  • npm start:将当前npm发布到npmjs.org上。
  • npm test:测试代码,应避免重复输入。

无论从语义还是便利性上,重写常见命令都是不错的选择。

更多

手动解析process.argv还是有些麻烦的,这里推荐几个args库,可以更简单地对process.argv进行处理。

  • Clipanion:基于TypeScript类和装饰器风格,用起来更简单。
  • Commander.js:目前使用最多的库。
  • Yargs:小巧、功能强大、简单,是官方推荐的库。

下面给出基于Yargs库解析process.argv的代码。

#!/usr/bin/env node
require('yargs') // eslint-disable-line
  .command('serve [port]', 'start the server', (yargs) => {
    yargs
      .positional('port', {
        describe: 'port to bind on',
        default: 5000
      })
  }, (argv) => {
    if (argv.verbose) console.info(`start server on :${argv.port}`)
    serve(argv.port)
  })
  .option('verbose', {
    alias: 'v',
    default: false
  })
  .argv


在终端中执行上面的代码,结合help选项就可以查看当前应用的帮助文档,内容如下。

$ node cli.js --help
cli.js [命令]


命令:
  cli.js serve [port]  start the server


选项:
  --help          显示帮助信息                                             [布尔]
  --version       显示版本号                                               [布尔]
  --verbose, -v

笔者和很多朋友一样,非常介意模块的依赖和整体安装包的体积,一般推荐使用比较小巧的模块,实在没有合适的就自己编写。

DRY(Don't Repeat Yourself)是软件开发过程中非常有名的原则,字面意思是“不要重复自己”,实际是告诉开发者不要重复造轮子,强调在编程时不要重复写相同的代码。代码应当只写一次,需要重复使用时直接在其他地方引用即可。

因此,当别人写的代码或模块可用时,可以优先使用,没有可以满足需求的模块时再考虑自己开发。如此一来可以提高代码重用率,缩减代码量,同时也有助于提高代码的可读性和可维护性。

版权声明


相关文章:

  • 集成这7个库,让Node.js开发变得更简单_node集成环境2024-10-30 15:04:20
  • 为什么都在用Node.js?Node.js到底是什么?_node.js是干嘛用的2024-10-30 15:04:20
  • 盘点10个优秀的 node.js 开源项目_node.js 开发2024-10-30 15:04:20
  • 如何快速学习Node.js开发_怎么学node.js2024-10-30 15:04:20
  • 五个Node.js开发的优秀实践_node.js开发实战2024-10-30 15:04:20
  • 五个Node.js开发的优秀实践_node.js开发实战2024-10-30 15:04:20
  • 如何快速学习Node.js开发_怎么学node.js2024-10-30 15:04:20
  • 盘点10个优秀的 node.js 开源项目_node.js 开发2024-10-30 15:04:20
  • 为什么都在用Node.js?Node.js到底是什么?_node.js是干嘛用的2024-10-30 15:04:20
  • 集成这7个库,让Node.js开发变得更简单_node集成环境2024-10-30 15:04:20
  • 全屏图片