Node.js 核心 API 速通(一)
这节开始整体过一遍 Node.js 的 api。
其实前面用到了很多的 api,但是没有整体梳理一遍,这节开始,整体过一遍。
只学习核心的 api,其余的用到查文档就行。
创建个项目:
mkdir node-api-test
cd node-api-test
npm init -yevents
首先是 events 模块:
创建 events.js
const EventEmitter = require('node:events');
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
myEmitter.on('aaa', (data) => {
console.log('aaa 事件触发', data);
});
myEmitter.once('bbb', (data) => {
console.log('bbb 事件触发', data);
});
myEmitter.emit('aaa', 1);
myEmitter.emit('aaa', 2);
myEmitter.emit('bbb', 3);
myEmitter.emit('bbb', 4);创建一个 class 继承 EventEmitter,之后 new 一个实例。
on 注册的事件可以多次触发,而 once 注册的只会触发一次。
跑一下:
node ./events.js可以看到 aaa 事件触发了两次,而 bbb 事件只触发了一次。
EventEmiiter 虽然比较简单,但是用的很多。
你可以安装下 @types/node,会有 node api 的类型提示:
npm install --save-dev @types/nodepath
然后是 path 模块,它是用来做文件路径处理的:
创建 path.js
const path = require('node:path');
const filePath = __filename;
console.log(filePath)
console.log(path.dirname(filePath));
console.log(path.basename(filePath));
console.log(path.extname(filePath));这里用 __filename 拿到当前文件路径,然后用 dirname、basename、extname 拿到目录名、文件名、后缀名。
跑一下:
node ./path.js当然,__dirname、__filename 只在 commonjs 的模块里有,如果是 es module 就要用 import.meta.url
改下文件后缀名为 path.mjs
import path from 'node:path';
import { fileURLToPath } from 'node:url'
const filePath = fileURLToPath(import.meta.url)
console.log(filePath)
console.log(path.dirname(filePath));
console.log(path.basename(filePath));
console.log(path.extname(filePath));再跑下:
node ./path.mjs可以通过改 package.json 里的 type 为 module 或者 commonjs 来告诉 node 这些 js 文件是什么模块规范:
或者也可以通过后缀名改为 mjs 告诉 node 这个文件是 es module 的模块规范。
继续来测试其他 api:
path2.js
const path = require('node:path');
const filePath = path.join('../', 'node-api-test', './', 'path2.js');
console.log(filePath);
const filePath2 = path.resolve('../', 'node-api-test', './', 'path2.js');
console.log(filePath2);
console.log(path.relative('/a/b/c', '/a/d'));
console.log(path.parse(__filename));path.join 可以把多个路径连接起来,解析其中的 ../ ./,合并成一个路径。
path.resolve 也是连接多个路径,但最后会返回一个绝对路径。
path.relaive 是 a 路径到 b 路径的相对路径。
path.parse 是解析路径。
跑一下:
node path2.jsimport.meta
刚才用到了 import.meta.url,其实还有别的属性、方法可以用。
创建 meta.js
console.log(__dirname);
console.log(__filename);首先,在 commonjs 模块里,可以用 __dirname、__filename 来拿到目录名、文件名。
而在 es module 模块里,是用 import.meta
创建 meta2.mjs
import url from 'node:url';
console.log(import.meta.url);
console.log(import.meta.resolve('./a.js'))
console.log(import.meta.dirname);
console.log(import.meta.filename);
console.log(url.fileURLToPath(import.meta.url))import.meta.url 是拿到当前文件以 file:// 开头的路径。
import.meta.resolve 是基于当前目录和传入的路径来解析路径。
这里的 import.meta.dirname 要 node 版本 20.11 以上才有:
文档里也写了,和 url.fileURLToPath(import.meta.url) 等价。
跑一下:
url
刚才用到了 url.fileURLToPath,再来过一下其他 api:
创建 url.mjs
import url from 'node:url';
const myURL =
new url.URL('https://user:pass@sub.example.com:8080/xxx/yyy?a=1&b=2#hash');
console.log(myURL.hash, myURL.host, myURL.searchParams);
console.log(myURL.searchParams.get('a'));
myURL.searchParams.set('b', 222);
myURL.searchParams.append('c', 333);
console.log(myURL.searchParams.toString())创建一个 URL 实例,传入 url 字符串。
它会解析出 url 中各部分的内容,并且会把 query string 封装成 URLSearchParams 的实例。
URLSearchParams 有 get、set、append、toString 等方法。
跑一下:
当然,你也可以直接 new URLSearhParams
const params = new url.URLSearchParams('?aa=1&bb=2');
console.log(params);
for (const [name, value] of params) {
console.log(name, value);
}还有一个 api 也比较常用,就是 url.urlToHttpOptions
console.log(url.urlToHttpOptions(myURL));当你使用 http.request 或者 https.reqeust 的时候,需要传递对象形式的 options。
这时候就可以用 url.urlToHttpOptions 来解析 url 字符串来生成:
创建 url2.mjs
import http from 'node:http';
import url from 'node:url';
const options = {
method: 'GET',
host: 'www.baidu.com',
port: 80,
path: '/'
};
const req = http.request(options, res => {
res.on('data', (chunk) => {
console.log(chunk.toString());
});
res.on('end', () => {
console.log('done');
});
});
req.end();调用 http.request 发请求,返回的 res 是个可读流,监听 data 事件,打印返回的内容。
跑一下:
node url2.mjs当然,你也可以用刚才的 url.urlToHttpOptions 方法来写:
const options = url.urlToHttpOptions(new URL('http://www.baidu.com:80/'));
console.log(options);os
os 模块可以拿到很多系统的信息,比如 cpu、内存、home 目录等。
创建 os.mjs
import os from 'node:os';
console.log('aaa' + os.EOL + 'bbb' + os.EOL);跑一下:
node os.mjsos.EOL 是换行符,在 windows 上是 \r ,在其他系统上是 ,所以直接用 os.EOL 更好
os.cpus() 返回的是 cpu 内核的信息:
model 是型号。
speed 是频率。
timers.user 是在用户模式下运行的毫秒数,timers.sys 是在 sys 模式下运行的毫秒数,idle 是空闲的毫秒数
具体是啥意思用到的时候再看就行。
其它的常用 api 也都比较简单,快速过一遍:
console.log(os.type());
console.log(os.userInfo())
console.log(os.freemem(), os.totalmem());
console.log(os.homedir());
console.log(os.networkInterfaces())os.type() 是系统类型,有 Darwin(也就是 mac)、Windows_NT、Linux 等值。
os.userInfo() 是拿到当前用户相关的信息,比如 homedir、username 等。
os.freemem() 是可用内存、os.totalmem() 是总内存
os.homedir() 是 home 目录
os.networkInterfaces() 是网卡信息。
当然,你要是想拿到更丰富的系统信息,可以用 systeminformation这个包,在写 cli 仪表盘的时候用过。
代码上传了文档仓库
总结
这节过了一些 node 常用的 api。
有这些模块:
- events:提供了 EventEmitter 类,可以用 on、once 注册监听器,用 emit 触发事件
- path:用来处理文件路径的,dirname、basename、extname 方法分别拿到目录名、文件名、后缀名,而 join、resolve、relative、parse 等方法是用来连接、解析路径的
- import.meta:在 commonjs 里用 __dirname、__filename 等变量来拿到当前文件名、当前目录,而在 es module 里是用 import.meta.dirname、import.meta.filename,这要 node 20 以上才有,低版本可以用 url.fileURLToPath(import.meta.url)
- url:用来解析 URL 的,可以 new URL 来拿到各部分的内容,还可以 new URLSearchParams 来处理 query string
- os:拿到系统信息,比如 cpu、内存、homedir、网卡信息、EOL 等。
这些 api 虽然简单,但都是很常用到的。