查看原文
其他

看了就会的 Node.js 常用三方工具包

小炼 前端试炼 2022-05-12
爆肝日更  前端面试  前端工程化

👆  点击上方卡片关注

前言

之前一篇文章介绍了 Node.js 的三个模块的基础 API,面对文档时不那么抓瞎,基础 API 用习惯了也差不多找到感觉,之后想用啥就可以自己照着文档找就好了。

除了 Node 提供的基础模块之外,我们在开发中必不可少地会用到第三方模块,也就是我们最常见的社区 NPM 包。这篇文章主要就是介绍一些在开发 Node 的时候,常用的一些基础工具包。

两篇文章配合使用,应该可以帮助你上手 Node 开发。

文件系统

这些工具包的功能就是在 Node 本身的 fs 模块基础上提供更加方便的文件系统操作 API。

glob

一句话介绍

glob 是一种文件匹配模式,起源于 Unix,比如我们常见 *.js 匹配所有 js 文件就是使用了 glob 模式。

GitHub 地址:https://github.com/isaacs/node-glob[1]

使用方法

glob(pattern, [options], callback)glob 方法接收三个参数:

  • pattern: 匹配规则字符串
  • options: 配置项(可选)
  • callback: 回调函数 (error, files) => {}
    • error: 错误信息,如果不存在则为成功
    • matches: 匹配文件数组

其中 options 是可选项:文档[2],可以不传,直接将回调函数放在第二个参数。

如果不想使用回调的方式,可以使用同步方法 glob.sync(pattern, options),用法一致,返回值即是匹配文件数组。

举例

当前文件目录如下:

.
├── a
│   ├── a.css
│   ├── a.js
    ├── .eslintrc.js
│   └── b
│       ├── b.css
│       └── b.js
├── index.js
├── package.json

index.js 代码如下:

const glob = require("glob")

glob("a/**/*.js", (error, matches) => {
  if (!error) {
    console.log(matches);
  }
});

try {
  const files = glob.sync("a/**/*.js");
  console.log(files);
catch (e) {}

输出如下:

'a/a.js''a/b/b.js' ]

是不是发现 .eslintrc.js 文件并没有被匹配到。默认情况下,glob 不会匹配以 . 开头的文件,需要我们在配置项中打开:

const glob = require("glob")

glob("a/**/*.js", { dottrue }, (error, matches) => {
  if (!error) {
    console.log(matches);
  }
});
// [ 'a/.eslintrc.js', 'a/a.js', 'a/b/b.js' ]

globby

一句话介绍

globby 是增强型的 glob,提供了 Promise 的封装。最终要的是它支持多模式匹配,相比于 glob 只能传入一个 pattern 字符串,globby 支持传入一个 pattern 数组。

GitHub 地址:https://github.com/sindresorhus/globby[3]

使用方法

globby(patterns, options?)globby 接收两个参数,返回 Promise

  • patterns: 匹配规则数组
  • options: 配置项

举例

当前文件目录如下:

.
├── a
│   ├── a.css
│   ├── a.js
    ├── .eslintrc.js
│   └── b
│       ├── b.css
│       └── b.js
├── index.js
├── package.json

index.js 代码如下:

const globby = require('globby');

(async () => {
  const files = await globby(['a/**/*.js''a/**/*.css'], { dottrue });
  console.log(files);
})();

输出如下:

'a/.eslintrc.js''a/a.js''a/b/b.js''a/a.css''a/b/b.css' ]

fs-extra

一句话介绍

Node 内置了 fs 模块供开发者和文件系统交互,但是用过的同学都知道,它的能力还是挺有限的。所以,在 fs 的基础上,社区提供了 fs-extra 工具包增强文件系统交互,并且提供了 Promise 的调用方式。

GitHub 地址:https://github.com/jprichardson/node-fs-extra[4]

举例

这里介绍几个最常见的:

const fse = require('fs-extra');

(async () => {
  // 确认目录是否存在,如果不存在会创建目录
  await fse.ensureDir('./a');

  // 复制文件
  await fse.copy('./a/a.js''./a/aa.js');

  // 读 JSON 文件
  const aJSON = await fse.readJSON('./a/a.json');
  console.log(typeof aJSON, aJSON);

  // 写 JSON 文件
  await fse.writeJSON('./a/aa.json', { a1 }, { spaces2 });

  // 写 JSON 文件,如果目录不存在会创建
  await fse.outputJson('./c/aa.json', { a1 }, { spaces2 });

  // 删文件
  await fse.remove('./a/aa.json');
})();

执行命令

这几个 NPM 包的功能主要就是会用于执行一些系统命令,比如 npm installgit clone 等等。

shelljs

一句话介绍

这个包的作用就和它的名字一样,用 js 来实现 shell 命令。

GitHub 地址:https://github.com/shelljs/shelljs[5]

使用方法

可以通过 shelljs 提供的 exec 命令同步地执行任意的 shell 命令,返回值中的 code 标识是否成功执行,比如:

const shell = require('shelljs');

if (shell.exec('git init .').code === 0) {
  console.log('Git 初始化成功');
}

除了 exec 之外,shelljs 也提供了一些常用 shell 命令的包装,比如 whichecho 等,比如:

const shell = require('shelljs');

shell.echo('Hello Shelljs');

举例

来看两个 shelljs 的常见用法。

const shell = require('shelljs');

// 判断是否有相关开发环境
function hasGitNpm() {
  if (!shell.which('git')) {
    console.log('Sorry, this script requires git');
    shell.exit(1);
  }

  if (!shell.which('npm')) {
    console.log('Sorry, this script requires npm');
    shell.exit(1);
  }
}

hasGitNpm();

// 安装 npm 包
function installPkg(pkg, type) {
  const npm = shell.which('npm');
  if (!npm) {
    console.log('请先安装 npm');
    return;
  }
  const { code } = shell.exec(
    `${npm.stdout} install ${pkg} ${type || '--save'}`
  );
  if (code) {
    console.log(`安装 ${pkg} 失败,请手动安装`);
  }
}

installPkg('lodash');

cross-spawn

一句话介绍

在 Node 中,可以通过 child_process 模块来创建子进程,并且通过 child_process.spawn 方法来使用指定的命令行参数创建新进程,执行完之后返回执行结果。而 cross-spawn 包就是提供了关于 spawn 函数的跨平台写法,不用开发者处理跨平台的逻辑。

GitHub 地址:https://github.com/moxystudio/node-cross-spawn[6]

使用方法

用法和 child_process.spawn(command[, args][, options]) 保持一致:

const spawn = require('cross-spawn');

const child = spawn('npm', ['install'], { stdio'inherit' });

举例

看一个比较常见的 cross-spawn 用法:

const spawn = require('cross-spawn');

// 安装全部依赖
spawn.sync('npm', ['install'], { stdio'inherit' });

// 安装指定依赖
spawn.sync('npm', ['install''lodash''--save'], { stdio'inherit' });

rimraf

一句话介绍

相当于在命令行中执行了 rm -rf,咳咳,是不是有点危险啊。

GitHub 地址:hhttps://github.com/isaacs/rimraf[7]

使用方法

rimraf(f, [opts], callback)rimraf 方法接收三个参数:

  • f: glob 匹配规则
  • opts: 配置项,可选
  • callback: 回调函数

当然,也可以使用 rimraf.sync 同步方法。

const rimraf = require('rimraf');

rimraf('./a/aa.js', error => {
  if (!error) {
    console.log('删除成功');
  }
});

除了在 Node 中用,在 package.jsonscripts 中也会经常看到这个工具,比如:

{
  "scripts": {
    "build""rimraf build && npm run build"
  }
}

网络请求

这里主要列了两个目前正在用的网络请求的包。

node-fetch

一句话介绍

相当于在 Node 上使用 Fetch。

GitHub 地址:https://github.com/node-fetch/node-fetch[8]

使用方法

就举个简单例子,其它的看文档就好了:

const fetch = require('node-fetch');

const response = await fetch('https://api.github.com/users/github');
const data = await response.json();

console.log(data);

axios

一句话介绍

axios 就不用介绍了,写前端的同学都知道,用起来也很方便。

GitHub 地址:https://github.com/axios/axios[9]

使用方法

const axios = require('axios');

axios({
  method'post',
  url'/user/12345',
  data: {
    firstName'Fred',
    lastName'Flintstone'
  }
});

小工具

这里就列一堆用得上的小工具吧,按需用。

open

一句话介绍

open 包可以让你在代码中打开网页、图片等等。比如你经常 npm start 启动项目的时候,是不是会自动唤起浏览器打开一个 localhost 的页面,就是通过 open 包实现的。

GitHub 地址:https://github.com/sindresorhus/open[10]

使用方法

const open = require('open');

await open('http://localhost:8080');

http-server

一句话介绍

http-server 包一般安装在全局使用,可以在本地任意目录 0 配置启动一个 HTTP 服务,一般在本地开发和测试的时候会经常用到。比如,使用 npm build 打包构建出构建产物之后,可以本地执行 http-server build 启动一个服务。

GitHub 地址:https://github.com/http-party/http-server[11]

path-to-regexp

一句话介绍

顾名思义,path-to-regexp 是将指定 path 转换成一个正则表达式的工具,一般在接口路径匹配的时候会用到。

GitHub 地址:https://github.com/pillarjs/path-to-regexp[12]

使用方法

比如我们的 API 的路径有很多,其中有一部分是对外开放的 API,它的路径是 /openapi/* 的,可以这样匹配:

const { pathToRegexp } = require('path-to-regexp');

console.log(pathToRegexp('/openapi/:key'));

输出结果为:

/^\/openapi(?:\/([^\/#\?]+?))[\/#\?]?$/i

url-join

一句话介绍

url-join 包可以非常方便地操作一个 url,拼接任意参数。

GitHub 地址:https://github.com/jfromaniello/url-join[13]

使用方法

假设我们需要动态地拼接参数,可以这样:

const urlJoin = require('url-join');

console.log(urlJoin('http://www.google.com''a''/b/cd''?foo=123'));

输出结果为:

http://www.google.com/a/b/cd?foo=123

semver

一句话介绍

NPMsemver 规范相关的工具包,判断版本啥的。

GitHub 地址:https://github.com/npm/node-semver[14]

使用方法

const semver = require('semver')

// 判断是否符合规范
semver.valid('1.2.3'// '1.2.3'
semver.valid('a.b.c'// null
// 判断 a 版本是否比 b 版本高
semver.gt('1.2.3''9.8.7'// false
// 判断 a 版本是否比 b 版本低
semver.lt('1.2.3''9.8.7'// true
// 判断符合某个版本范围的最低版本
semver.minVersion('>=1.0.0'// '1.0.0'

CLI 相关

见之前的文章:实现 CLI 常用工具包 - 终端交互相关(问卷、彩色文字、loading、进度条)

总结

这篇文章到这里就结束了,本文整理了一些在 Node 开发时常用的 NPM 包,希望能够帮到你。但是社区之大,功能强大的 NPM 包远不止这些,可以自行探索。

需要使用某个功能的 NPM 包时,可以在 NPM 官网或者 GitHub 上搜索:

NPM 官网https://www.npmjs.com/[15]

参考资料

[1]

https://github.com/isaacs/node-glob: https://github.com/isaacs/node-glob

[2]

文档: https://github.com/isaacs/node-glob#options

[3]

https://github.com/sindresorhus/globby: https://github.com/sindresorhus/globby

[4]

https://github.com/jprichardson/node-fs-extra: https://github.com/jprichardson/node-fs-extra

[5]

https://github.com/shelljs/shelljs: https://github.com/shelljs/shelljs

[6]

https://github.com/moxystudio/node-cross-spawn: https://github.com/moxystudio/node-cross-spawn

[7]

hhttps://github.com/isaacs/rimraf: https://github.com/isaacs/rimraf

[8]

https://github.com/node-fetch/node-fetch: https://github.com/node-fetch/node-fetch

[9]

https://github.com/axios/axios: https://github.com/axios/axios

[10]

https://github.com/sindresorhus/open: https://github.com/sindresorhus/open

[11]

https://github.com/http-party/http-server: https://github.com/http-party/http-server

[12]

https://github.com/pillarjs/path-to-regexp: https://github.com/pillarjs/path-to-regexp

[13]

https://github.com/jfromaniello/url-join: https://github.com/jfromaniello/url-join

[14]

https://github.com/npm/node-semver: https://github.com/npm/node-semver

[15]

https://www.npmjs.com/: https://www.npmjs.com/

交流讨论

欢迎关注公众号「前端试炼」,公众号平时会分享一些实用或者有意思的东西,发现代码之美。专注深度和最佳实践,希望打造一个高质量的公众号。

❤️ 

公众号后台回复【小炼】

邀请你加入纯净技术交流群(上班划水摸鱼群)

🙏

如果觉得这篇文章还不错

来个【分享、点赞、在看】三连吧

让更多的人也看到


您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存