看了就会的 Node.js 三大基础模块常用 API

技术漫谈 4月11日

以下文章来源于前端试炼 ,作者小炼

👆  点击上方卡片关注在日常使用 Node 进行开发的时候,会使用到一些文件系统、路径操作等基础 API,这里整理一下,方大家理解和直接使用。

这里只介绍最常用的那些,不是所有哈,想要看更全的,直接看官方文档[1]就 OK。

尽量不废话,多上代码。

Process 模块

先介绍 process 模块,它提供了当前 Node 进程相关的全局环境信息。在后面的 API 中被用到。

// 内置模块,直接使用const process = require('process');

process.cwd()

这是一个函数,返回当前 Node 进程执行的目录,举例一个常见的场景:

一个 Node 模块 A 通过 NPM 发布,项目 B 中使用了模块 A。在 A 中需要操作 B 项目下的文件时,就可以用 process.cwd() 来获取 B 项目的路径。

const cwd = process.cwd(); // 输出:/Users/xiaolian/Code/node-api-test

process.argv

在终端通过 Node 执行命令的时候,通过 process.argv 可以获取传入的命令行参数,返回值是一个数组:

  • 0: Node 路径(一般用不到,直接忽略)
  • 1: 被执行的 JS 文件路径(一般用不到,直接忽略)
  • 2~n: 真实传入命令的参数**

所以,我们只要从 process.argv[2] 开始获取就好了。一般都是这样用

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

直接获取我们想要的参数。

process.env

返回一个对象,存储当前环境相关的所有信息,一般很少直接用到。

一般我们会在 process.env 上挂载一些变量标识当前的环境。比如最常见的用 process.env.NODE_ENV 区分 development 和 production。在 vue-cli的源码中也经常会看到 process.env.VUE_CLI_DEBUG 标识当前是不是一DEBUG 模式。

这里提一个 webpack 的插件 DefinePlugin[2],在日常的构建流程中,我们经常会通过这个插件来注入不同的全局变量,从而执行不同的构建流程,并且代码中的 process.env.xxx 会被替换成具体的值,在 Terser 压缩阶段会将 deadCode 移除,优化代码体积。

process.platform

这个用的不多,返回当前系统信息,枚举值如下:

console.log(process.platform);

// 'aix'// 'darwin'  - macOS// 'freebsd'// 'linux' - linux// 'openbsd'// 'sunos'// 'win32' - windows

Path 模块

// 内置模块,直接使用const path = require('path');

Node 中几乎路径相关的操作都会使用这个模块。

这里就说 5 个最常用的:

path.join(...paths)

path.join 作用是将传入的多个路径拼成一个完整的路径。

const dPath = path.join('template', 'aaa', 'bbb', 'ccc', 'd.js');// 输出: template/aaa/bbb/ccc/d.js

来看一个非常常见的场景,我们需要获取当前项目的 package.json 文件,就可以这样获取它的路径:

const pkgPath = path.join(process.cwd(), './package.json');// 输出: /Users/xiaolian/Code/node-api-test/package.json

path.join 可以传入任意个路径,比如:

['package.json', 'README.md'].forEach(fileName => {  const templateFilePath = path.join(process.cwd(), 'template', fileName);  console.log(templateFilePath);});// 输出: /Users/xiaolian/Code/node-api-test/template/package.json// 输出: /Users/xiaolian/Code/node-api-test/template/README.md

path.resolve(...paths)

path.resovle 和 path.join 的区别在于它的作用是将传入的多个路径和当前执行路径拼接成一个完整的绝对路径。

假设我现在 index.js 在 scripts 目录下,然后我在根目录下执行 node scripts/index.js,它的代码如下:

const dPath = path.resolve('aaa', 'bbb', 'ccc', 'd.js');// 输出:  /Users/xiaolian/Code/node-api-test/aaa/bbb/ccc/d.js

一般情况下,当 path.resolve 的第一个参数为 ./ 时,可以直接理解和 path.join(processs.cwd(), '') 表现一致。

path.basename(path[, ext])

path.basename 返回指定 path 最后一个路径名,其中第二个参数 ext 可选,表示文件扩展名。比如:

console.log(path.basename('scripts/index.js'));  // index.jsconsole.log(path.basename('scripts/index.js', '.js'));  // 匹配到 .js,返回 indexconsole.log(path.basename('scripts/index.js', '.json'));  // 没匹配到,返回 index.js

path.dirname(path)

和 path.basename 对应,返回指定 path 最后一个路径名之前的路径。比如:

console.log(path.basename('scripts/index.js'));  // scriptsconsole.log(path.basename('scripts/hook/index.js'));  // scripts/hook

path.extname(path)

和 path.basename 对应,返回指定 path 最后一个路径名的文件扩展名(含小数点 .)。比如:

console.log(path.basename('scripts/index.js'));  // .jsconsole.log(path.basename('README.md'));  // .md

对比

最后再来对比一下各个路径相关的 API 的区别。

项目 A 的目录结构如下:

├── scripts│   └── index.js├── src│   └── index.js├── package.json├── README.md

scripts/index.js 的代码如下:

const path = require('path');

console.log(path.join('package.json'));console.log(path.resolve('package.json'));console.log(path.join('src', 'index.js'));console.log(path.resolve('src', 'index.js'));console.log(path.join(process.cwd(), 'package.json'));console.log(path.resolve('./', 'package.json'));console.log(__filename);console.log(__dirname);

然后,我们在项目 A 的根目录下执行 node scripts/index.js,结果如下:

-> node scripts/index.jspackage.json/Users/xiaolian/Code/A/package.jsonsrc/index.js/Users/xiaolian/Code/A/src/index.js/Users/xiaolian/Code/A/package.json/Users/xiaolian/Code/A/package.json/Users/xiaolian/Code/A/scripts/index.js/Users/xiaolian/Code/A/scripts

品,仔细品,它们有什么区别。

个人而言,一般还是习惯用 path.join(process.cwd(), 'xxx')

File System 模块

// 内置模块,直接使用const fs = require('fs');

文件系统相关操作的模块,除了 fs 之外,我们还经常用到 fs-extra,后面会介绍。

这个模块在平时的 Node 开发中会被大量使用,这里简单列几个,其它的还是看文档哈:https://nodejs.org/dist/latest-v14.x/docs/api/fs.html[3]

fs 模块的 API 默认都是异步回调的形式,如果你想使用同步的方法,有两种解决方法:

  1. 使用 Node 提供的同步 API:xxxSync,也就是在 API 的后面加一个 Sync 后缀,它就是一个同步方法了(具体还是需要查文档哈,是否有提供同步 API)
  2. 包装成一个 Promise 使用

fs.stat(path[, options], callback)

fs.stat() 返回一个文件或者目录的信息。

const fs = require('fs');

fs.stat('a.js', function(err, stats) {  console.log(stats);});

其中包含的参数有很多,介绍几个比较常用的:

export interface StatsBase<T> {  isFile(): boolean;                 // 判断是否是一个文件  isDirectory(): boolean;            // 判断是否一个目录

  size: T;                           // 大小(字节数)  atime: Date;                       // 访问时间  mtime: Date;                       // 上次文件内容修改时间  ctime: Date;                       // 上次文件状态改变时间  birthtime: Date;                   // 创建时间}

一般我们会使用 fs.stat 来取文件的大小,做一些判断逻辑,比如发布的时候可以检测文件大小是否符合规范。在 CLI 中,经常需要获取一个路径下的所有文件,这时候也需要使用 fs.stat 来判断是目录还是文件,如果是目录则继续递归。当然,现在也有更方便的 API 可以完成这个工作。

同步方法

const fs = require('fs');

try {  const stats = fs.statSync('a.js');} catch(e) {}

fs.readdir(path[, options], callback)

fs.readdir(path) 获取 path 目录下的文件和目录,返回值为一个包含 file 和 directory 的数组。

假设当前目录为:

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

执行以下代码:

const fs = require('fs');

fs.readdir(process.cwd(), function (error, files) {  if (!error) {    console.log(files);  }});

返回值为:

[ 'a',  'index.js',  'package.json' ]

可以看到这里只返回了根目录下的文件和目录,并没有去深度遍历。所以如果需要获取所有文件名,就需要自己实现递归。

同步方法

const fs = require('fs');

try {  const dirs = fs.readdirSync(process.cwd());} catch(e) {}

fs.readFile(path[, options], callback)

文件读取的 API,通过 fs.readFile 可以获取指定 path 的文件内容。

入参如下:

  • 第一个参数: 文件路径
  • 第二个参数: 配置对象,包括 encoding 和 flag,也可以直接传如 encoding 字符串
  • 第三个参数: 回调函数

使用方法如下:

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

fs.readFile(path.join(process.cwd(), 'package.json'), 'utf-8', function (  error,  content) {  if (!error) {    console.log(content);  }});

如果没传 encoding,则其默认值为 null,此时返回的文件内容为Buffer 格式。

同步方法

const fs = require('fs');

try {  fs.readFileSync(path.join(process.cwd(), 'package.json'), 'utf-8');} catch(e) {}

fs.writeFile(file, data[, options], callback)

对应着读文件 readFilefs 也提供了写文件的 API writeFile,接收四个参数:

  • 第一个参数: 待写入的文件路径
  • 第二个参数: 待写入的文件内容
  • 第三个参数: 配置对象,包括 encoding 和 flag,也可以直接传入 encoding 字符串
  • 第三个参数: 回调函数

使用方法如下:

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

fs.writeFile(  path.join(process.cwd(), 'result.js'),  'console.log("Hello World")',  function (error, content) {    console.log(error);  });

同步方法

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

try {  fs.writeFileSync(    path.join(process.cwd(), 'result.js'),    'console.log("Hello World")',    'utf-8'  );} catch (e) {}

本文主要是总结了一下在开发 Node 时常用的一些 API,后续的文章会带来 Node 常用的一些三方包。

参考资料

[1]

官方文档: https://nodejs.org/dist/latest-v14.x/docs/api/

[2]

DefinePlugin: https://webpack.js.org/plugins/define-plugin

[3]

https://nodejs.org/dist/latest-v14.x/docs/api/fs.html: https://nodejs.org/dist/latest-v14.x/docs/api/fs.html

(0)

相关推荐

  • 设计师编程指南之Sketch插件开发 10 - skpm & webview

    往期文章索引: 1 / 入门基本概念.page的相关操作 2 / artboard .NSFileManager 和 NSString 关于文件及文件夹的相关操作 3 / DIY一个Sketch插件, ...

  • PWA技术及其用户体验设计

    -服务器端渲染(SSR) 意味着网站每次都是在服务器上渲染,因此它提供了更快的首次加载,但是在页面之间跳转需要每次都下载所有内容,因而它的加载速度往往会比较慢.   -客户端渲染(CSR) 页面是在客 ...

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

    前端技术优选 2021-09-14 以下文章来源于前端试炼 ,作者小炼 前端试炼 每天一篇精心挑选的高质量文章,专注深度和最佳实践,希望打造一个高质量的公众号. 点击下方"前端技术优选&qu ...

  • 快上车!使用 Node.js 搭建一个 API 网关

    编程微刊 1周前 以下文章来源于程序员成长指北 ,作者koala 程序员成长指北专注 Node.js 技术栈分享,从 前端 到 Node.js 再到 后端数据库,祝您成为优秀的高级 Node.js 全 ...

  • 简析 Node.js 特点与应用场景(让你更了解它)

    前端技术优选 今天 以下文章来源于程序员成长指北 ,作者koala 如果你有一定的前端基础,比如 HTML.CSS.JavaScript.jQuery:那么,Node.js 能让你以最低的成本快速过渡 ...

  • JavaScript 事件循环:从起源到浏览器再到 Node.js

    冰森 前端技术优选 今天 很多文章都在讨论事件循环 (Event Loop) 是什么,而几乎没有人讨论为什么 JavaScript 中会有事件循环.博主认为这是为什么很多人都不能很好理解事件循环的一个 ...

  • 字节跳动最爱考的前端面试题:Node.js 基础

    前端技术优选 今天 前几天,跟我一朋友聊天,他现在是阿里的架构师,说:「他们根本不知道,现在的电商大促有多么依赖 Node.js.」 说真的,我倒并不意外.作为一个定位明确的高性能 Web 服务器,N ...

  • 成为自信的node.js开发者(一)

    原创 雾豹 前端技术优选 今天 作者:雾豹 原文地址:https://juejin.im/post/5c6a780451882561dd7b65d6 适合阅读的同学 想更进一步深入理解node的同学, ...

  • 看多“红五月”!券商认为三大主线收益或更高

    随着医药.半导体等成长板块回调,A股本周再度下跌,采掘.钢铁等顺周期板块继续走强.展望后市,这轮顺周期行情还能延续多久,此前机构看好的成长板块何时才能重拾涨势? 在券商看来,当前估值性价比突出,可以提 ...

  • 成为自信的node.js开发者(二)

    成为自信的node.js开发者(二) 原创 雾豹 前端技术优选 今天 前端技术优选 为你精选前端领域优质技术博文,欢迎关注. 60篇原创内容 公众号 点击上方关注 前端技术优选,一起学习,天天进步 作 ...

  • node.js 基于 STMP 协议和 EWS 协议发送邮件

    这篇文章主要介绍了node.js 基于 STMP 协议和 EWS 协议发送邮件的示例,帮助大家更好的理解和使用node.js,感兴趣的朋友可以了解下提到使用 node.js 发送邮件,基本都会提到大名 ...