Moment.js logo

Moment.js

曾经最流行的 JavaScript 日期处理库,现已进入维护模式(legacy),官方不再推荐用于新项目。

日期时间JavaScriptLegacy遗留项目

Moment.js 曾是最广泛使用的 JavaScript 日期时间库,以流畅链式 API 著称。由于可变对象设计、72KB 体积和无法 tree-shaking 等缺陷,2020 年官方宣布进入维护模式,推荐迁移至 Luxon、Day.js 或 date-fns。

Moment.js

曾经最流行的 JavaScript 日期处理库,现已进入维护模式(legacy),官方不再推荐用于新项目。

技术简介说明

Moment.js 曾是 JavaScript 生态中最广泛使用的日期时间处理库,以其流畅的链式 API 和丰富的功能赢得了开发者的青睐。在最辉煌的时期,Moment.js 的 npm 周下载量超过 1,700 万次,几乎是所有 JavaScript 项目的"标配"。

然而,随着前端工程化的发展,Moment.js 的设计缺陷逐渐暴露:可变对象导致的难以预料的副作用、~72KB 的臃肿体积(无法 tree-shaking)、以及对现代 Web API(如 Intl)的缺失利用。2020 年,Moment.js 团队正式宣布项目进入维护模式,不再添加新功能。

截至 2026 年,Moment.js 仍然拥有约 1,400 万周下载量——这主要来自于存量项目和遗留代码,而非新增选择。官方团队明确建议新项目使用 Luxon、Day.js、date-fns 或原生 Temporal API 替代。

基本信息

项目详情
官网https://momentjs.com/
GitHubhttps://github.com/moment/moment
LicenseMIT
最新版本v2.30.1(最终版本)
主要维护者Moment.js 团队(Tim Wood 创建)
npm 周下载量~1,400 万(存量项目为主)
GitHub Stars48,000+
项目状态⚠️ 维护模式 / Legacy

快速上手

安装

# npm
npm install moment
 
# yarn
yarn add moment
 
# pnpm
pnpm add moment
 
# CDN
<script src="https://cdn.jsdelivr.net/npm/[email protected]/moment.min.js"></script>
<!-- 中文 locale -->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/locale/zh-cn.js"></script>

基础配置

import moment from 'moment'
import 'moment/locale/zh-cn'
 
moment.locale('zh-cn') // 全局设置中文

最小示例

import moment from 'moment'
 
// 当前时间
const now = moment()
 
// 格式化
console.log(now.format('YYYY-MM-DD HH:mm:ss')) // '2026-07-07 14:30:00'
 
// 日期计算
const tomorrow = moment().add(1, 'days')
const lastWeek = moment().subtract(1, 'weeks')
 
// 相对时间
console.log(moment().subtract(3, 'hours').fromNow()) // '3 小时前'
 
// 解析
const date = moment('2026-07-07', 'YYYY-MM-DD')

核心概念与架构

可变对象设计

Moment.js 的核心设计是可变的——大多数操作会修改原始对象:

const a = moment('2026-01-01')
const b = a.add(1, 'day')
// ⚠️ a 也被修改了!a 和 b 指向同一个对象
console.log(a.format('YYYY-MM-DD')) // '2026-01-02'(已被修改)
console.log(b === a) // true

这是 Moment.js 最受诟病的设计缺陷。要获取不可变行为,需要先克隆:

const a = moment('2026-01-01')
const b = a.clone().add(1, 'day')
// a 保持不变

全局状态

Moment.js 使用全局状态管理 locale 和时区设置:

moment.locale('zh-cn') // 影响所有 moment 实例

这在多语言应用中可能导致意外的全局副作用。

打包问题

Moment.js 会将所有 locale 文件打包在一起,导致最终产物非常臃肿。Webpack 需要使用 IgnorePlugin 排除不需要的 locale:

// webpack.config.js
const webpack = require('webpack')
module.exports = {
  plugins: [
    new webpack.IgnorePlugin({
      resourceRegExp: /^\.\/locale$/,
      contextRegExp: /moment$/,
    }),
  ],
}

核心特性

  • 流畅的链式 APImoment().add(1, 'day').format('YYYY-MM-DD')
  • 丰富的格式化选项:支持数十种格式化 token
  • Locale 支持:130+ 种语言
  • 时区插件moment-timezone 提供 IANA 时区支持
  • 相对时间fromNow()toNow() 等方法
  • Duration 支持:时间跨度处理
  • 日历格式化:"Yesterday"、"Tomorrow" 等人性化输出
  • 多语言解析:支持用不同语言解析日期字符串
  • 浏览器 + Node.js:双环境支持
  • 成熟的生态:10 年以上历史,大量教程和问答资源

生态图

核心扩展

扩展功能
moment-timezoneIANA 时区支持(~180KB 数据文件)
moment-range日期范围操作
moment-precise-range-plugin精确日期差计算

社区生态(历史积累)

  • react-moment:React 组件封装
  • vue-moment:Vue 过滤器
  • angular-moment:Angular 集成
  • moment-parseformat:自动检测日期格式
  • react-dates(Airbnb):基于 Moment.js 的日期选择器

关键依赖

  • moment-timezone 依赖 Moment.js 核心 + IANA 时区数据(~180KB)
  • 部分 UI 库依赖 Moment.js(如旧版 react-dates、ant-design v3 等),但这些正在迁移

适用场景

⚠️ 不推荐用于新项目

Moment.js 团队官方声明:"We now generally consider Moment to be a legacy project in maintenance mode. It is not dead, but it is indeed done."

仅推荐在以下场景继续使用:

  • 遗留项目维护:已有大量 Moment.js 代码的存量项目,迁移成本高于维护成本
  • 遗留 UI 组件:依赖 Moment.js 的第三方组件(如旧版 ant-design、react-dates)
  • 快速脚本/原型:不考虑长期维护的一次性脚本

官方推荐替代方案

替代方案特点
LuxonMoment.js 团队官方推荐,由 Moment 核心贡献者开发
Day.js轻量(2KB),API 与 Moment.js 高度兼容
date-fns函数式设计,tree-shakeable
js-JodaJava 时间 API 的 JavaScript 移植
Temporal APIJavaScript 原生日期 API(ES2026)

开发与工程化

项目状态

Moment.js 已进入维护模式,不再有功能开发。官方仅进行:

  • 关键安全补丁修复
  • 时区数据更新(IANA 数据库更新)
  • 不会修复 tree-shaking 问题
  • 不会修复可变性问题
  • 不会添加新功能

遗留项目中的 Moment.js 优化

// ✅ Webpack 排除不需要的 locale
const webpack = require('webpack')
new webpack.IgnorePlugin({
  resourceRegExp: /^\.\/locale$/,
  contextRegExp: /moment$/,
})
 
// ✅ 只引入需要的 locale
import moment from 'moment'
import 'moment/locale/zh-cn'

迁移策略

从 Moment.js 迁移到新库的一般策略:

  1. 评估使用范围:搜索所有 moment( 调用,统计影响面
  2. 选择替代库:根据项目特点选择 Day.js(最小改动)、date-fns(现代化)或 Luxon(功能完整)
  3. 逐步替换:可以在同一项目中同时使用 Moment.js 和新库,逐步迁移
  4. Day.js 作为过渡:Day.js 的 API 与 Moment.js 高度兼容,可作为最小改动迁移方案

性能与安全

性能问题

  • 包体积:Moment.js 核心 ~72KB(minified + gzipped),加上 moment-timezone 达到 ~250KB
  • 无法 tree-shaking:所有功能全量打包,即使只用了 format
  • Locale 膨胀:默认打包所有 130+ 种 locale

可变性陷阱

// ⚠️ 经典 bug:意外的对象修改
function formatEvent(date) {
  return date.startOf('day').format('YYYY-MM-DD') // 修改了传入的 date 对象!
}
 
const eventDate = moment('2026-07-07T15:30:00')
formatEvent(eventDate)
console.log(eventDate.format()) // 时间已被修改为 00:00:00!

安全注意事项

  • 浏览器 DevTools(如 Chrome)会对使用 Moment.js 的项目显示弃用警告
  • 部分安全扫描工具会将 Moment.js 标记为技术债务
  • 定期更新 moment-timezone 以获取最新的 IANA 时区数据

技术对比

特性Moment.jsDay.jsdate-fnsLuxon
包大小~72KB~2KB~17.5KB~53KB
不可变❌ 可变
Tree-shaking❌(插件不支持)✅ 完美✅ 部分
TypeScript
时区moment-timezone插件@date-fns/tz内置
维护状态⚠️ Legacy✅ 活跃✅ 活跃✅ 活跃
学习成本
社区规模大(存量)

Moment.js 的核心问题

  1. 可变对象:导致难以调试的 bug,与现代 React/Vue 的不 immutable 理念冲突
  2. 包体积臃肿:72KB+ 的体积在现代性能标准下不可接受
  3. 无法 tree-shaking:即使用了 Webpack/Rollup,也无法去除未使用的代码
  4. 无 TypeScript 支持:官方不提供类型定义(社区 @types/moment 存在但非官方)
  5. 全局 localemoment.locale() 影响全局,多语言应用有副作用风险
  6. 浏览器标记弃用:Chrome DevTools 等工具会标记 Moment.js 为需移除的库

最佳实践

如果你必须继续使用 Moment.js

// ✅ 总是使用 clone() 避免可变性陷阱
const result = myMoment.clone().add(1, 'day')
 
// ✅ 使用 strict 模式解析
moment('2026-07-07', 'YYYY-MM-DD', true)
 
// ✅ Webpack 中排除不需要的 locale
new webpack.IgnorePlugin({ resourceRegExp: /^\.\/locale$/, contextRegExp: /moment$/ })
 
// ✅ 检查日期有效性
if (moment(dateString).isValid()) {
  // 处理有效日期
}

迁移优先级建议

项目情况推荐替代
大量 Moment.js 代码,希望最小改动Day.js
TypeScript 项目,追求现代化date-fns
复杂时区需求Luxon
新项目(任何情况)不要使用 Moment.js

技术局限与边界

  • 项目已停止开发:不会再有功能更新或重大改进
  • 架构缺陷不可修复:可变性、不可 tree-shaking 等根本性问题无法在不打破兼容性的情况下修复
  • 与现代框架冲突:React/Vue 的不可变数据理念与 Moment.js 的可变设计冲突
  • bundle size 影响:72KB+ 的体积对移动端和 SSR 场景影响显著
  • 浏览器弃用标记:DevTools 会标记 Moment.js,影响开发体验
  • 安全扫描告警:部分安全/质量工具会将 Moment.js 视为技术债务
  • 新开发者不熟悉:越来越多的开发者直接学习 date-fns 或 Temporal,不了解 Moment.js

学习资源

2026 年现状

当前版本

  • v2.30.1:最终稳定版,不会再有 v2.31 或更高版本
  • 仅接收安全补丁和时区数据更新

社区活跃度

  • npm 周下载量约 1,400 万,但这是存量项目的惯性下载
  • 新项目几乎不再选择 Moment.js
  • GitHub Issues 基本处于冻结状态
  • 社区讨论已转向替代方案

发展趋势

  • 持续下降:Moment.js 的使用率持续下降,开发者加速向 Day.js、date-fns、Luxon 和 Temporal API 迁移
  • 浏览器标记弃用:越来越多的 DevTools 和质量工具标记 Moment.js 为"应移除"
  • Temporal API 终结:随着 Temporal API 成为 ES2026 标准并逐步获得浏览器原生支持,Moment.js 的替代方案将更加完善
  • 教育内容更新:新的教程、课程和文档不再教授 Moment.js,转向现代替代方案
  • 结论2026 年,Moment.js 绝不应该被用于新项目。 对于存量项目,建议制定迁移计划,逐步替换为 Day.js、date-fns 或 Luxon