2026年,原生浏览器API将取代流行的npm包
解释了原生 JavaScript 和 CSS 的各种特性,如 Signals、管道运算符、Temporal 以及锚点定位,是如何逐渐取代常见的 npm 包的。
值得花点时间审视一下自己的 package.json:其中有多少条配置只是为了伪装浏览器早已能够自行实现的功能?
在过去的十年里,面对几乎所有前端问题,人们的默认解决方案都是“找个插件”。需要状态管理?就用 Redux、Zustand 或 MobX。需要处理日期?用 Moment 或 dayjs。需要实用工具函数?用 lodash。需要动画效果?用 GSAP 或 Framer Motion。每个框架都积累了大量用于填补平台漏洞的辅助代码。
到2026年,这一趋势的变化速度将超过大多数团队的预期。TC39及各大浏览器厂商在过去几年里一直在为各类第三方工具开发原生替代方案。以下是五款您现在就可以考虑从依赖项中移除的包,还有另外两款仅处于半过时状态。
1. 状态管理库——原生Signals现已推出
替代方案:Redux、Zustand、MobX、Recoil、Jotai,以及框架自带的响应式机制如Vue的响应式引用
被替代为:标准化的Signal原语(State、Computed以及sub订阅辅助函数)
很少有问题能像状态管理方式的选择那样严重地分裂前端开发领域。React的生态系统先后经历了Redux、Zustand、Jotai和Recoil的发展。Vue则构建了自己的响应式原语,后来又在之上添加了Pinia层。而Solid和Svelte从一开始就是围绕信号机制设计的。每个框架都发明了自己的响应式原语版本,这意味着在不同框架之间重用状态逻辑几乎是不可能的。
2026年,当TC39的原生信号提案得以实现后,这一限制有所缓解。现在的响应式原语直接存在于JavaScript引擎内部:
// No library. This runs in the browser as-is.
const counter = new Signal.State(0);
const doubled = new Signal.Computed(() => counter.get() * 2);
Signal.sub(() => {
console.log(`count: ${counter.get()}, doubled: ${doubled.get()}`);
});
counter.set(1); // triggers the subscription automatically
这种转变实际上能带来以下好处:
- 你的状态逻辑可以只需编写一次即可到处重用——React、Vue、Solid和Svelte都可以从同一个底层原语中读取数据
一些工程师将此视为前端框架之间长达十年的对立关系的终结。一旦反应式核心在各个生态系统中实现共享,不同框架之间的差异就仅剩下模板语法和组件结构——而非状态更新传播的机制。
2. lodash —— 管道操作符终结“回调地狱的近亲”
替代:lodash、ramda以及大多数_.chain()的使用场景
被替代为:管道操作符|>
你很可能曾经写过类似这样的代码:
const result = fn3(fn2(fn1(data)));
那种需要从内到外阅读才能弄清实际执行顺序的嵌套函数调用方式,长期以来一直是影响 JavaScript 可读性的最严重问题之一。lodash 的 _.chain() 曾试图解决这一问题,但为此却不得不引入整个库才能让调用顺序更清晰。
截至 2026 年,管道操作符已在 ES2026 中进入第 4 阶段。 现在同样的表达式可以按照自上而下的自然顺序来阅读:
const result = data
|> fn1
|> fn2
|> fn3;
结合原生的 await 支持,异步管道的代码结构几乎就像 shell 脚本一样易读:
const user = userId
|> fetchUser
|> await
|> extractProfile
|> await
|> formatOutput;
管道操作符解决了可读性问题,而 lodash 主要是为了解决早期语言中缺乏函数式工具的难题。如今管道操作已内置,Array.prototype 的方法也更加成熟,且 structuredClone 已广泛可用,lodash 存在的必要性已大大降低。如果在 2026 年它仍存在于你的依赖列表中,移除它很可能是最简单有效的减小包体积的方法。
3. dayjs 和 moment — Temporal API 的浏览器支持率已达 98%
替代方案:在大多数使用场景下可替代 moment.js、dayjs 和 date-fns
被替代为: Temporal API
这条目是列表中争议最少的。moment.js 多年来一直处于仅维护模式,即便是所谓的“轻量级”库 dayjs 也会为你的代码包增加超过2KB的体积。而Temporal API 的浏览器支持率已达到98%。
// dayjs
const d = dayjs('2026-09-11').add(1, 'month').format('YYYY-MM-DD');
// Temporal
const d = Temporal.PlainDate.from('2026-09-11').add({ months: 1 }).toString();
Temporal 不仅拥有更简洁的语法,还能解决日期处理库多年来一直存在的实际问题:
- 时区处理是内置功能,无需额外的时区插件
- 日历系统支持也是内置的,包括非公历体系
- 实例是不可变的,避免了 moment.js 中常见的误改本以为未被修改的对象的问题
- 代码包体积可减少10到50KB
对于以移动端用户为主的项目而言,10–50KB的体积缩减并非可有可无——它直接有助于提升LCP得分。
4. Popper.js与Floating UI——锚点定位现已成为原生CSS功能
被替代的组件: Popper.js、Floating UI、Tippy.js
替代方案: CSS锚点定位
只要曾经开发过工具提示,就明白其中的流程:需要在按钮正下方显示下拉内容。传统做法是使用position: absolute,手动计算top和left值,再添加scroll和resize监听器以防止内容位置偏移。或者借助Popper.js或Floating UI,仅为了实现定位功能就要额外增加十几KB的加载量。
到2026年,CSS锚点定位将在平台层面解决这一问题:
/* Step 1: name the anchor element */
.button {
anchor-name: --my-trigger;
}
/* Step 2: pin the floating element to it */
.tooltip {
position: anchor(--my-trigger);
inset-area: bottom; /* below the anchor */
}
就是这样——整个解决方案。无需JavaScript,无需手动计算绝对定位值,也无需外部库。可以把锚点定位视为浮动UI元素的GPS定位器:将其指向触发按钮,无论页面如何滚动或视口如何调整大小,该元素都会始终固定在原位。
5. Sass与PostCSS——原生嵌套、@layer和@scope
替代:Sass、Less、PostCSS及其插件生态系统
被替代为:原生CSS嵌套、@layer和@scope
曾经有一段时间,Sass和Less似乎是必不可少的工具。变量、嵌套、混合函数、可重用函数——纯CSS根本无法提供这些功能。但在2026年,情况已不再如此。
原生嵌套:
.card {
background: white;
& .title { font-weight: 600; }
&:hover { box-shadow: 0 4px 12px rgba(0,0,0,0.1); }
}
@layer 用于控制层叠顺序:
@layer reset, base, components, utilities;
@scope 用于实现轻量级的样式隔离:
@scope (.card) to (.card__content) {
:scope { border-radius: 8px; }
}
OKLCH 已成为标准颜色格式:
:root {
--color-primary: oklch(0.65 0.2 250);
--color-hover: oklch(from var(--color-primary) calc(l - 0.1) c h);
}
再加上容器查询、通过 text-box 实现精确的文本对齐、利用 sibling-index() 进行基于兄弟元素的定位,以及由滚动触发的动画——这些功能到2026年已在所有浏览器中得到稳定支持——因此Sass已从大多数项目中的必备工具转变为可选工具。如果它仍被自动添加到你的技术栈中,不妨看看你使用它的那些功能中有多少现在已能由浏览器原生实现。
仅部分被替代的两个工具包
此列表中的并非所有项目都已有完整的原生替代品。有两个项目已非常接近,但相关平台尚未完全跟上。
动画库——GSAP与Framer Motion与原生View Transitions的对比。随着React 19.3的发布,View Transitions API已趋于稳定,其<ViewTransition>组件能够自动实现元素在出现、消失、移动或大小变化时的动画效果。通过animation-timeline: scroll()实现的滚动驱动动画,无需任何JavaScript即可提供进度指示、视差效果以及淡入效果。不过,对于那些复杂且需要手动精心设计的动画序列——也就是GSAP擅长的那种——原生工具仍然无法完全替代它。
AI推理——ONNX Runtime Web与WebNN的对比。在基于浏览器的模型推理中,WebNN API可以直接利用系统级的NPU加速功能,从而无需加载数十兆字节的ONNX运行时代码。
const context = await navigator.ml.createContext();
const builder = new MLGraphBuilder(context);
// build the inference graph...
const output = await context.compute(graph, inputs);
局限性在于:WebNN目前仍缺乏全面的浏览器支持,因此现阶段ONNX Runtime Web仍是更可靠的选择。
从中型前端代码库中移除这五类组件,可减少100到300KB的依赖体积。在网络速度较慢的移动设备上,这一优化能让页面首次渲染的时间缩短1到2秒。
核心要点
2026年的前端开发正经历原生平台的复兴。TC39及各类浏览器引擎正在逐步接管原本仅属于npm生态系统的功能——状态管理、函数辅助工具、日期处理、浮动元素定位以及CSS预处理等。那些过去需要引入外部包才能解决的问题,现在都已内建在浏览器中得到了解决。
JavaScript 正逐渐成为一种真正具备自给自足能力的平台语言。值得培养的技能并非对某一个框架或库的深入精通,而是能够判断何时平台功能已足够,何时仍需依赖其他组件来发挥作用。
那么请查看一下你的 package.json:今天你能删除多少行代码呢?
相关阅读
- 解决搜索界面中无法通过防抖处理的竞态条件问题 — 了解为何仅靠防抖无法防止过时的 API 响应覆盖最新的界面状态,并探索四种确保请求按顺序处理的实用方法。