在构建 Node.js 应用程序时,了解 Node.js 开箱即用的实用程序和 API 有助于满足常见用例和开发需求。在文中《Node.js实用的内置API(一)》介绍了两个,本文继续介绍其他实用内置API。
util
:提供了各种有用的 JavaScript 方法,其中最有用的是util.promisify(function)
,它采用错误优先的回调样式函数并返回基于Promise
的函数。URL
:另一个全局对象,安全地创建、解析和修改 Web URL。它对于从 URL 中快速提取协议、端口、参数和hash
非常有用,而无需借助正则表达式。- 文件系统:可以创建、读取、更新和删除文件、目录和权限。
Util
util
模块提供了各种有用的 JavaScript 方法,其中最有用的是 util.promisify(function)
,它采用错误优先的回调样式函数并返回基于 Promise
的函数。Util 模块还可以帮助处理常见模式,例如解码文本、类型检查和检查对象。
util.callbackify(function)
:接受一个返回承诺的函数并返回一个基于回调的函数。util.isDeepStrictEqual(object1, object2)
:当两个对象之间存在深度相等时返回true
(所有子属性必须匹配)。util.format(format, [args])
:使用类似 printf-like-format 返回一个字符串util.inspect(object, options)
:返回用于调试的对象的字符串表示形式,类似于使用console.dir(object, { depth: null, color: true });
util.stripVTControlCharacters(str)
:从字符串中去除 ANSI 转义符util.types
:为常见的 JavaScript 和 Node.js 值提供类型检查,如下:
import util from "util"; util.types.isDate(new Date()); // true util.types.isMap(new Map()); // true util.types.isRegExp(/abc/); // true util.types.isAsyncFunction(async () => {}); // true
URL
URL 是另一个全局对象,安全地创建、解析和修改 Web URL。它对于从 URL 中快速提取协议、端口、参数和 hash
非常有用,而无需借助正则表达式。如下:
{ href: "https: //example.org:8000/path/?abc=123#target", origin: "https: //example.org:8000", protocol: "https:", username: "", password: "", host: "example.org: 8000", hostname: "example.org", port: "8000", pathname: "/path/", search: "?abc=123", hash: "#target", }
可以查看和更改任何属性,如下:
const myUrl = "https://example.org:8001/path/?abc=123#target"; myURL.port = 8001; console.log(myURL.href); // https://example.org:8001/path/?abc=123#target
然后,可以使用 URLSearchParams
API 修改查询字符串值,如下:
myURL.searchParams.delete("abc"); myURL.searchParams.append("xyz", 987); console.log(myURL.search); // ?xyz=987
dns 模块提供名称解析功能,可以查找 IP 地址、名称服务器、TXT 记录和其他域信息。
文件系统 API
文件系统 APIfs
可以创建、读取、更新和删除文件、目录和权限。 Node.js 运行时的最新版本在 fs/promises
中提供了基于 Promise 的函数,这使得管理异步文件操作变得更加容易。
经常将 fs
与 path
结合使用来解析不同操作系统上的文件名。
以下代码模块使用 stat
和 access
方法返回有关文件系统对象的信息:
import { constants as fsConstants } from "fs"; import { access, stat } from "fs/promises"; export async function getFileInfo(file) { const fileInfo = {}; try { const info = await stat(file); fileInfo.isFile = info.isFile(); fileInfo.isDir = info.isDirectory(); } catch (e) { return { new: true }; } try { await access(file, fsConstants.R_OK); fileInfo.canRead = true; } catch (e) {} try { await access(file, fsConstants.W_OK); fileInfo.canWrite = true; } catch (e) {} return fileInfo; }
当传递一个文件名时,该函数返回一个包含该文件信息的对象,如下:
{ isFile: true, isDir: false, canRead: true, canWrite: true }
主程序 filecompress.js
脚本使用 path.resolve()
将命令行上传递的输入和输出文件名解析为绝对文件路径,然后使用 getFileInfo()
获取信息:
#!/usr/bin/env node import path from "path"; import { readFile, writeFile } from "fs/promises"; import { getFileInfo } from "./lib/fileinfo.js"; // check files const input = path.resolve(process.argv[2] || ""); const output = path.resolve(process.argv[3] || ""); const [inputInfo, outputInfo] = await Promise.all([ getFileInfo(input), getFileInfo(output), ]); const error = [];
该代码验证路径并在必要时以错误消息终止:
if (outputInfo.isDir && outputInfo.canWrite && inputInfo.isFile) { output = path.resolve(output, path.basename(input)); } if (!inputInfo.isFile || !inputInfo.canRead) error.push(`cannot read input file ${input}`); if (input === output) error.push("input and output files cannot be the same"); if (error.length) { console.log("Usage: ./filecompress.js [input file] [output file|dir]"); console.error("\n " + error.join("\n ")); process.exit(1); }
使用 readFile()
将整个文件读入名为 content
的字符串:
console.log(`processing ${input}`); let content; try { content = await readFile(input, { encoding: "utf8" }); } catch (e) { console.log(e); process.exit(1); } const lengthOrig = content.length; console.log(`file size ${lengthOrig}`);
JavaScript 正则表达式然后删除注释和空格:
content = content .replace(/\n\s+/g, "\n") // 移除行前置空格 .replace(/\/\/.*?\n/g, "") // 移除单行注释 .replace(/\s+/g, " ") // 移除空格 .replace(/\/\*.*?\*\//g, "") // 移除块注释 /* 注释 */ .replace(/<!--.*?-->/g, "") // 移除HTML注释 <!-- 注释 --> .replace(/\s*([<>(){}}[\]])\s*/g, "$1") // 移除括号周围的空格 .trim(); const lengthNew = content.length;
使用 writeFile()
将生成的字符串输出到文件中,并且状态消息会显示保存:
const lengthNew = content.length; // write file console.log(`outputting ${output}`); console.log( `file size ${lengthNew} - saved ${Math.round( ((lengthOrig - lengthNew) / lengthOrig) * 100 )}%` ); try { content = await writeFile(output, content); } catch (e) { console.log(e); process.exit(1); }
使用示例 HTML 文件运行项目代码:
node filecompress.js ./test/example.html ./test/output.html