聊天讨论 Node.js 原生功能狂飙,15 个热门 npm 包要失业了

Immerse(沉浸式趣谈) · December 22, 2025 · 18 hits

大家好,我是 Immerse,一名独立开发者、内容创作者、AGI 实践者。

关注公众号:沉浸式趣谈,获取最新文章(更多内容只在公众号更新)

个人网站:https://yaolifeng.com 也同步更新。

转载请在文章开头注明出处和版权信息。

我会在这里分享关于编程独立开发AI干货开源个人思考等内容。

如果本文对您有所帮助,欢迎动动小手指一键三连 (点赞评论转发),给我一些支持和鼓励,谢谢!


之前装个 Node.js 项目,npm 包能装一大堆。

现在发现很多包其实不用装了,Node.js 自己就支持。

这次整理了 15 个已经被 Node.js 原生功能替代的热门 npm 包。

有些已经稳定了,有些还在实验阶段,但都能用起来了。

fetch 终于成全局函数了

以前在 Node.js 里用 fetch,必须装 node-fetch。

现在 Node.js 18 开始,fetch 已经是全局函数了,和浏览器里的用法完全一样。

const res = await fetch("https://api.github.com/repos/nodejs/node");
const data = await res.json();
console.log(data.full_name);

直接就能用,不用装任何包。

Node.js 17.5 开始实验性支持,到 18 就稳定了。

如果你的项目还在用 Node.js 18 之前的版本,那还是得装 node-fetch。

WebSocket 也原生支持了

之前做 WebSocket 客户端,基本都用 ws 这个包。

现在 Node.js 有了全局的 WebSocket 类。

const ws = new WebSocket("wss://echo.websocket.org");

ws.onopen = () => ws.send("Hello!");
ws.onmessage = (event) => console.log("Received:", event.data);

Node.js 21 加的,不过还是实验性的。

要注意的是,这只是客户端支持。

如果要做 WebSocket 服务端,还是得用 ws 或者其他库。

测试框架不用装了

以前写测试,要装 mocha、jest 这些框架。

现在 Node.js 自带测试模块 node:test。

import test from "node:test";
import assert from "node:assert";

test("addition works", () => {
  assert.strictEqual(2 + 2, 4);
});

Node.js 18 加的实验性功能,到 20 就稳定了。

如果需要快照测试、mock 这些高级功能,第三方框架还是更强。

不过对于模块级别的测试,node:test 完全够用了。

SQLite 也要原生支持了

之前用 SQLite,要装 sqlite3 或 better-sqlite3。

这俩包都需要编译原生模块,升级 Node.js 版本经常出问题。

现在 Node.js 在开发 node:sqlite 模块。

import { open } from "node:sqlite";

const db = await open(":memory:");
await db.exec("CREATE TABLE users (id INTEGER, name TEXT)");

不过还是实验性的,等稳定了就能彻底告别编译问题了。

控制台彩色输出不用装 chalk 了

给控制台输出加颜色,以前都用 chalk 或 kleur。

现在 Node.js 有 util.styleText 函数。

import { styleText } from "node:util";

console.log(styleText("red", "Error!"));
console.log(styleText(["bold", "green"], "Success!"));

Node.js 20.12 加的,到 22.17 就稳定了。

如果需要复杂的主题配置或链式调用,chalk 还是更好用。

但简单的颜色输出,原生的就够了。

清理 ANSI 码也不用装包了

以前要去掉日志里的 ANSI 转义码,得装 strip-ansi。

现在有 util.stripVTControlCharacters 函数。

import { stripVTControlCharacters } from "node:util";

const text = "\u001B[4mUnderlined\u001B[0m";
console.log(stripVTControlCharacters(text));

原生处理,稳定可靠。

基本不需要再装第三方包了。

glob 匹配文件也原生了

匹配文件路径,以前必须用 glob 包。

Node.js 22 开始有 fs.glob 函数了。

import fs from "node:fs/promises";

const files = await fs.glob("**/*.js");
console.log(files);

22 版本就稳定了,可以放心用。

老项目还在用旧版本 Node.js 的话,还是得继续用 glob 包。

递归删除目录不用 rimraf 了

删除整个目录树,以前都用 rimraf。

现在 fs.rm 直接支持递归删除。

import fs from "node:fs/promises";

await fs.rm("dist", { recursive: true, force: true });

Node.js 12.10 就有了,现在所有 LTS 版本都稳定支持。

递归创建目录也不用 mkdir 了

创建多级目录,以前要装 mkdir。

现在 fs.mkdir 原生支持。

await fs.mkdir("logs/app", { recursive: true });

Node.js 10.12 就加了,早就稳定了。

UUID 生成不用装包了

生成 UUID v4,以前要装 uuid 包。

现在 crypto 模块自带 randomUUID 函数。

import { randomUUID } from "node:crypto";

console.log(randomUUID());

Node.js 14.17 就有了,稳定版本。

Base64 编解码也原生支持了

以前要 polyfill atob 和 btoa 函数。

现在这俩已经是全局函数了。

const encoded = btoa("hello");
console.log(encoded);
console.log(atob(encoded));

Buffer 一直都有,现在加上 atob 和 btoa,浏览器和 Node.js 的代码终于统一了。

Node.js 20 左右加的,现在 LTS 版本都有。

URL 路由匹配有了 URLPattern

做路由匹配,以前要装 url-pattern。

现在有全局的 URLPattern API。

const pattern = new URLPattern({ pathname: "/users/:id" });
const match = pattern.exec("/users/42");
console.log(match.pathname.groups.id);

Node.js 20 加的,不过还是实验性的。

但已经能用了,而且和浏览器的 URLPattern 完全一样。

加载 .env 文件不一定要 dotenv 了

之前加载环境变量文件,必须装 dotenv。

现在可以用 --env-file 参数。

node --env-file=.env app.js

Node.js 20.10 加的实验性功能。

如果需要变量展开或多文件支持,dotenv 还是更强。

但简单场景下,原生的就够了。

EventTarget 也是全局的了

以前 Node.js 只有 EventEmitter,要用 Web 标准的 EventTarget 得装 event-target-shim。

现在 EventTarget 已经是全局的了。

const target = new EventTarget();
target.addEventListener("ping", () => console.log("pong"));
target.dispatchEvent(new Event("ping"));

Node.js 15 加的,15.4 就稳定了。

浏览器和 Node.js 终于可以用同样的事件 API 了。

运行 TypeScript 不一定要 tsc 了

以前运行 .ts 文件,要装 TypeScript 编译器或 ts-node。

现在 Node.js 有实验性的 TypeScript 支持。

node --experimental-strip-types app.ts

Node.js 21 加的实验性功能。

不过这只是去掉类型标注,不做类型检查。

生产环境还是得用完整的 TypeScript 工具链。

为啥 Node.js 要把这些功能内置

看这些变化,能发现一个趋势。

以前需要外部依赖的功能,现在越来越多变成了核心功能。

这样做有几个好处。

减少依赖数量,项目更轻量。

降低供应链攻击风险,不用担心某个包被投毒。

代码在浏览器和服务端之间更容易移植。

能用就用起来

这些原生功能,浏览器支持好的就可以直接用了。

实验性的功能可以在开发环境先试试。

No Reply at the moment.
You need to Sign in before reply, if you don't have an account, please Sign up first.