Moment.js 使命完成,替代品推荐

看到新闻 Moment.js 宣布进入遗留状态 的当天觉得挺惊奇,没想到这一天这么快就到来,不禁感叹前端开发、Javascript 世界变化之快以及高效。到 Moment.js 官网看了声明,很清楚的说明项目的情况和考虑,前面一部分翻译如下:


项目状态

Moment.js 已被数百万个项目运用,我们为在 Web 上更好使用时间日期作出贡献而感到高兴。截至 2020年9月,Moment 每周的下载量超过 1200万!然而,Moment 是为 JavaScript 生态系统的上一个时代构建的。如今的现代 Web 看起来已大不相同。这些年来,Moment 有所发展,但其设计基本上与 2011年创建时相同。鉴于有众多项目依赖它,我们选择优先考虑稳定性而不是新功能。

例如,Moment 对象是可变的。这是有关 Moment 的常见抱怨来源。我们在使用指南中提到了该问题,但仍给大多数新用户带来意外困扰。对于每个使用 Moment 的项目,更改为不可变对象将是一项重大的断层式更新。创建不可变的 “Moment v3” 将是一项艰巨的任务,并将使 Moment 完全成为一个不同的库。由于这已在其他库中完成,因此我们认为保留可变的 API 更为重要。

在现代应用程序中针对 Moment 的另外一个问题是他的大小。Moment 在流行的 “tree shaking” 算法中工作的不太好,导致 Web 应用程序包的曾大。若需要国际化或时区支持,Moment 会非常大(译注:当前的 v2.29.0 官网上显示 moment.min.js gz压缩后为 18.2k,moment-with-locales.js gz压缩则增至 73.2k)。现代 Web浏览器(和 Node.js)通过规范编号为 ECMA-402Intl 对象暴露对国际化和时区支持。Luxon 等其他库利用这一优势,减少或取消自己提供数据文件的需要。

最近,Chrome 开发工具开始因其大小而建议替换掉 Moment。我们普遍支持这一举措。

你可能想阅读:

Moment 团队已详细讨论了这些问题。我们认识到许多现有项目可能会继续使用 Moment,但是我们不鼓励在以后的新项目中使用。作为替换,我们推荐当今在现代应用中使用的绝佳选择。我们还想推广 JavaScript 的 Temporal 新增提案,该功能正在寻求反馈和贡献者。

我们认定 Moment 现在是处于维护模式下的遗留项目。他并没有死,但他确实已完成使命。

这意味着:

  • 不再添加新功能特性。
  • 不再修改 Moment 的 API 为不可变对象。
  • 不再解决 tree shaking 和包大小问题。
  • 不再有大版本更新(没有 version 3)。
  • 可能不再修正 bug,特别是较久远的问题。

对于 Moment 国际化语言文件:

  • 我们可能不接受对区域设置字符串或本地化日期格式的修正,特别是在它们的当前形式已经被成功地论证过的情况下。
  • 您必须使用重要的,非轶事证据来为地区变更提出新的令人信服的论据,以支持您的立场。
  • 如果您要更改的字符串或格式反映在 CLDR 中,那么您必须首先在此处提交更改并接受它。

但由于 Moment 已在数百万个现有项目中使用:

  • 当出现严重安全问题时,我们将予以解决。
  • IANA时区数据库 发布后更新 Moment-Timezone 的数据。

替代品

官方推荐如下几个库:

我建议你去每个库的官网看看他们各自的特色和优点,然后再决定选择哪个作为替代。

其中 Luxon 的作者是 Moment 长期贡献者 Isaac Cambron,算是 Moment 的灵魂续作。Day.js 有着与 Moment 类似的 API,快速替换的好选择。date-fns 遵循函数式编程规范,直接操作 JS Date 对象,这是我的首选。

我与 Moment 的故事

2015下半年转行 Web 开发的第一份工作中,首次看到同事使用 Moment 后,我就对他格式化日期操作的便利性所吸引(不用再 getFullYear, getMonth …),然后被我运用到各种不同项目中。

上面提到的可变对象问题,今年在公司一个可视化大屏项目中,确实令我困扰了一下,直到我反复试验后才注意到 add() 操作后可变对象的问题。不过这只是一个小插曲而已,仍然要感谢 Moment 在这段时间中给我开发所带来的便利和愉悦。

Moment 的发展现状正是 Javascript 生态增长且发展的一个正面例子,是当今热门词汇内卷化的一个反面例证。

分享