Moment.js官方推荐使用其它时间处理库代替

猿友 2020-09-24 11:26:05 浏览数 (4062)
反馈

文章来源于公众号:印记中文 译者:Phobal

近期,Moment.js 在官方文档中发布了项目状态,文中写道:Momentjs 正式进入维护期,不会再提供大版本更新,推荐使用其他时间处理库代替或使用 JavaScript 处于实验阶段的提案 Temporal。

以下是针对这篇项目状态的中文翻译。

Moment.js 已广泛应用于数百万个项目中,能帮助你处理网站中日期和时间的问题,我们感到万分荣幸。截至 2020 年 9 月,Moment 每周下载量超 1200 万次!然而 Moment 是为 JavaScript 生态系统的上一个时代而构建的。这些年 Web 发生翻天覆地的变化,Moment 紧随其后,但其设计与 2011 年创建时基本相同。鉴于有很多项目依赖它,所以我们优先考虑稳定性而非新功能。

Moment 对象是可变对象(mutable),这点经常被用户所诟病。尽管我们在 使用指南 中写明了如何解决此问题,但还是会有很多新用户犯错。而如果将 Moment 变为不可变对象(immutable)这会对已使用 Moment 的项目产生破坏性的影响。让 Moment 支持 immutable 本身就是件艰巨的任务,这将使 Moment 变为另外一个库,现阶段已有很多类似的库实现这个特性,所以让 Moment 保持 mutable 也没什么不好。

而大家所诟病的另一点就是 Moment 包的体积大小,而 tree shakingMoment 无效,导致应用的包体积剧增。如果你的应用中需要用到国际化和时区,那么 Moment 可能会大到超乎想象。现代 Web 浏览器(和 Node.js)通过Intl 对象(其编号为 ECMA-402)实现了对国际化和时区支持。而像 Luxon 之类的库就利用了这一优势来降低库文件的大小。

最近,Chrome 开发工具会建议用户更换 Moment。我们也赞成此举动。

社区针对这个问题发表过很多文章:

  • 你可能不再需要 Moment.js
  • 你(可能)不需要 Moment.js
  • 为什么你不需要使用 Moment.js...
  • 4 个可替代 moment.js 的库,用于日期国际化

Moment 团队也针对这些问题做过详细的讨论。我们意识到可能已有项目会继续使用 Moment。但我们并不推荐你在新项目中使用它,相反,我们向大家 推荐 一些能更好应用于现代 web 的库。同时还推荐大家试用 JavaScript 处理时间的新提案 - Temporal,该提案需要大家的支持和贡献。

我们正式宣布 Moment 进入维护期,但并非消亡,只是完成了使命

事实上,这意味着:

  • 不再添加新功能。
  • 不会将 API 变为 immutable。
  • 不会解决 tree shaking 及包体积的问题。
  • 不会进行任何重大更改(不会有 v3)。
  • 可能选择不对 bug 进行修复,特别是长期存在的已知 bug。

关于 Moment 的国际化语言环境文件:

  • 我们可能选择不接受对语言环境字符串或本地化日期格式的更正,特别是它们的现有格式已被论证时。
  • 语言环境发生重大改变时,必须提出令人信服的依据来支持你的立场。
  • 如果你要更改字符串或格式,那么你必须先在 CLDR 上提交更改申请并被接受后才可更改。

但是,由于 Moment 使用者还很多,当遇到以下问题时我们会及时进行处理:

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

需要继续使用 Moment 的场景

在大多数情况下,新项目请不要选择 Moment。但是,在一些特殊的场景下你可能还是需要使用它。

浏览器支持

Moment 能在 IE8 下完美运行。相比之下,Luxon 只能在 IE 10 及更高版本上运行,并且还需要搭配 polyfill 使用。你可以在 Luxon 的文档中了解更多相关内容。

其他库在 Safari 上也有相同的问题,尤其是在移动设备上。如果你必须要支持旧版浏览器,那可能还要继续使用 Moment

但是,Day.js 支持 IE8 及更高版本,如果有兼容性相关的需求,你可以考虑使用它。

其他库的依赖

有些库,尤其是日期选择器和图形库,都将 Moment 作为依赖项,如果你正在使用类似的组件,且找不到替代方案,那么你的项目已经依赖了 Moment。你可以在项目中继续使用 Moment,而不需要再引入日期时间库。

忠实粉丝

如果你是 Moment 的忠实粉丝,那么你肯定非常了解它的 API 和局限性。如果是这样,并且不 care 上述问题,那可以继续使用它。

推荐一些替代库

有很多不错的库可以代替 Moment。

在做选择时,请考虑下面几点:

  • 有些库会被分割为模块,插件及配套库。
  • 有些库将 ECMAScript 的 Intl API 用于语言环境、时区或两者皆有。
  • 有些库仍像 Moment 和 Moment-Timezone 一样提供自己的语言环境和时区文件。

以下是我们推荐的替代方案:

Luxon

Luxon 可以认为是 Moment 的演变,它由 Moment 的长期撰稿人 Isaac Cambron 撰写。请阅读为什么会存在Luxon?以及 Luxon 文档中的 For Moment用户 相关文档。

  • 语言环境:Intl 实现
  • 时区:Intl 实现

Day.js

使用类似的 API,Day.js 被设计为 Moment.js 的极简替代品。它不是临时替代品,如果你习惯使用 Moment 的 API 并希望快速入门,请考虑使用 Day.js。

  • 语言环境:可以单独导入的自定义数据文件
  • 时区:Intl 通过插件实现

date-fns

Date-fns 提供了一系列用于处理 JavaScript Date 对象的函数。欲了解更多详细信息,请到date-fns 主页中阅读 “为什么使用 date-fns?” 一节。

  • 语言环境:可以单独导入的自定义数据文件
  • 时区:Intl 通过单独的库实现

js-Joda

js-JodaJavaThree-Ten BackportJavaScript 版本,该 backport 是根据 Java SE 8 java.time 包中 JSR-310 实现的基础。如果你熟悉java.time,Joda-Time 或 Noda Time,你会发现 js-Joda 具有可比性。

  • 语言环境:通过附加模块的自定义数据文件
  • 时区:通过附加模块的自定义数据文件

不使用任何第三方库

JavaScript 一直有一个 Date 对象,遵循了 ECMAScript(ECMA-262)的规范。

使用 Date 对象时,请注意以下几点:

  • Date 对象内部具有毫秒精度的 Unix 时间戳。它提供了可以在系统本地时区之间来回转换的功能,但是内部始终是 UTC。与 Moment 对象不同,不能将其设置为使用其他时区。它并不存在“模式”的概念。
  • 使用 Date.parsenew Date() 在过去一直存在 bug,且实现不一。当前的规范 支持定义解析 ISO 8601 的字符串,其中只有日期的形式会(如 "2020-09-14")被解析为 UTC,而非 ISO 8601 中的当地时间。即便如此,也不是所有的现代浏览器都会按照这个标准来实现(例如 Safari)。其他类型的字符串也可以使用,但是解析它们是额外实现的,并且可能会有很大的不同,特别是对于旧版本的浏览器来说。实现方式以及传入字符串的不同,可能会产生不同的结果。由于这些原因,我们同意 MDN 的声明,即 强烈反对使用 Date 对象对字符串进行解析

现代 JavaScript 环境也实现了 ECMA-402 的规范,提供了 Intl 对象,并在 Date 对象上定义了toLocaleStringtoLocaleDateString 以及 toLocaleTimeString 等方法。

使用 Intl 对象时,请注意以下几点:

  • 并非每个环境都会实现完整的规范。特别是,Node.js 环境依赖 ICU 提供的国际化支持。有关更多详细信息,请参见 Node.js 文档。
  • ECMAScript Intl 兼容性列表 (由 kangax 提供) ,方便查询支持情况。
  • 多数较新的环境提供了通过 IANA 时区支持 timeZoneIntl.DateTimeFormat 构造函数(以及 Date.toLocaleStringDate.toLocaleDateStringDate.toLocaleTimeString)选项。该选项可用于获取对象的内部基于 UTC 的时间戳和获取已转换为命名时区的字符串。但是,它不能将 Date 对象转换为其他时区。

如果 DateIntl 对象能满足你的需求,并且你完全了解它们的局限性,则可以考虑直接使用它们。

未来

Temporal - 使用 JavaScript 自带时间和日期处理方式会更好

将来,我们希望不再需要使用 JavaScript 相关的日期和时间处理库。而是直接使用 JavaScript 语言本身的特性。尽管今天有 Date 和提供了一些特性的 Intl,但我们从以往的经验和数据来看,它们仍有很大的改进空间。

从 ECMA TC39 的临时提案可以看出,组织正在努力为 JavaScript 语言编写更好的日期和时间 API。目前已处于 TC39 流程的第二阶段。

Temporal 将是一个充当顶级名称空间(如 Math)的新全局对象。它暴露了许多不同的类型的对象,包括 Temporal.AbsoluteTemporal.DateTimeTemporal.DateTemporal.TimeTemporal.TimeZone等。Temporal Cookbook 中包含了许多案例,并举例说明了如何在不同情况下使用这些对象。

你可以通过这个 实验性的 polyfill 来体验它,但还是不要在生产环境中使用它。

如果你有使用 Moment 或其他日期时间处理库的经验,并且对 temporal 提案感兴趣,欢迎参与讨论和开发。

以上就是W3Cschool编程狮关于Moment.js官方推荐使用其它时间处理库代替的相关介绍了,希望对大家有所帮助。

0 人点赞