ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Backstage ADR010:为何统一采用 Luxon 作为标准日期时间库

Backstage ADR010:为何统一采用 Luxon 作为标准日期时间库 Backstage ADR010为何统一采用 Luxon 作为标准日期时间库【免费下载链接】backstageBackstage is an open framework for building developer portals项目地址: https://gitcode.com/GitHub_Trending/ba/backstageBackstage 的 UI 与后端服务中随处可见日期格式化与计算例如 a day ago 这类相对时间展示而原生的 JavaScriptDate对象并不足以支撑这些需求。本文围绕 Backstage 的架构决策记录 ADR010: Use the Luxon Date Library 展开完整还原其决策背景Context、决策内容Decision与后果约定Consequences并结合当前仓库中 20 余个包的真实依赖声明与 78 个源码文件的导入情况说明这一决策是如何在全仓库范围内落地的。读完本文你将理解 Backstage 放弃 Moment.js 的完整理由、Luxon 在项目中的具体使用模式DateTime.fromISO、toRelative、toLocaleString预设以及如何在自己的 Backstage 插件中遵守同一套日期处理规范。背景原生 Date 的局限与 Moment.js 的困境ADR010 的 Context 部分交代了问题起源日期格式化如a day ago和日期计算在 Backstage 中非常常见但标准的 JavaScriptDate对象无法提供这些实用能力。业界长期用 Moment.js 来填补这一空白但它在 Backstage 这样的前端应用中存在三个致命问题包体过大large bundle sizesMoment.js 的完整产物体积会直接计入前端 bundle对门户类应用的加载性能不友好可变状态mutable stateMoment 对象是可变对象add()、subtract()等方法会就地修改对象本身在 React 这类强调不可变数据流的框架中极易引发难以排查的状态 bug项目已被官方宣布进入维护模式being sunsetMoment.js 官方已建议项目迁移到更现代的替代库这意味着继续依赖它是在为一条被放弃的技术路线押注。该 ADR 同时指向了社区层面的讨论起点[RFC] Standardized Date Time LibraryBackstage 仓库 issue #3401说明这一决策经过了公开的 RFC 讨论而非单点拍板。决策以 Luxon 作为 Backstage 的标准日期库Decision 部分给出的结论只有一句话但信息量很大Backstage 内部统一使用 Luxon 作为标准日期时间库。ADR 同时给出了选择 Luxon 的技术理由值得逐条拆解API 心智模型接近 Moment.jsLuxon 提供了与 Moment.js 相似的功能集与 API 形态团队从 Moment 迁移过来的学习成本很低不可变设计immutabilityLuxon 的DateTime对象不可变任何变换操作plus()、minus()、setZone()等都返回新对象这与 React 的数据流天然契合也从根本上规避了 ADR Context 中批评 Moment 的 mutable state 问题构建在现代 Web API 之上Luxon 的本地化格式化底层直接复用浏览器/Node 内置的IntlAPI而不是像 Moment 那样携带巨量的 locale 数据因此在提供完整功能集的同时显著减小了 bundle 体积减少附加依赖一套库即可覆盖常见的日期时间任务无需为不同场景再引入其他辅助库。后果约定三个对全仓库生效的约束ADR 的 Consequences 部分把决策转化成了对贡献者的硬性约定这也是理解 Backstage 代码风格的关键所有核心包与插件All core packages and plugins中凡是原生Date难以完成的日期操作或格式化必须使用 Luxon。这不是建议而是代码评审时的检查项单一日期库降低学习成本开发者只需掌握一套 API避免在多个日期库之间切换心智单一日期库减小 bundle 体积多个库各自携带的格式化逻辑与 locale 数据被合并为一套直接收益体现在产物大小上。Backstage 的 ADR 管理规则见 ADR 总览也规定决策记录一旦合并永不删除只允许被标记为被新决策取代superseded或弃用deprecated因此 ADR010 至今仍然是仓库内日期处理的最高准则。仓库实证Luxon 依赖如何落地到 20 余个包只写统一使用 Luxon而不看仓库是不完整的。在当前仓库中搜索所有package.json可以确认luxon已经被显式声明为依赖且版本线统一在 v3 系列包声明版本packages/types/package.json^3.0.0packages/backend-plugin-api/package.json^3.0.0packages/backend-defaults/package.json^3.0.0packages/integration/package.json^3.0.0plugins/catalog-backend/package.json^3.0.0plugins/auth-backend/package.json^3.0.0plugins/scaffolder-backend/package.json^3.0.0plugins/home/package.json^3.4.3plugins/catalog-unprocessed-entities/package.json^3.5.0plugins/auth-backend-module-pinniped-provider/package.json^3.4.3此外microsite文档站点、kubernetes-react、kubernetes-backend、kubernetes-common、scaffolder-react、catalog-backend-module-incremental-ingestion、events-backend-module-aws-sqs、app-backend等包同样声明了 Luxon 依赖覆盖从前端 React 插件、Node 后端插件到文档站点的完整链路。版本以^3.x起步、按包需要上浮符合 ADR单一标准库的约束——没有出现第二个日期库与 Luxon 并存的局面。从源码规模看对from luxon的统计显示共有78 个 TS/TSX 文件直接导入 Luxon头部消费者包括packages/backend-defaults18 个文件、plugins/kubernetes-react11 个、plugins/auth-backend9 个、plugins/catalog-backend8 个、packages/integration5 个。这说明该决策不仅约束前端展示也约束了后端服务中的日志时间、认证 token 过期计算、事件时间戳处理等场景。典型用法一相对时间展示a day ago场景ADR Context 中举的第一个例子就是a day ago这类相对时间表达。原生Date做不到距今多久的语义化输出而 Luxon 的toRelative()一行搞定。当前仓库中的真实用例首页访问记录列表 ItemDetail.tsx 中直接渲染visitDate.toRelative()把最近访问日期展示为 a day ago 这样的自然语言Kubernetes 插件的 Pod 事件列表 Events.tsx 使用DateTime.fromISO(event.metadata.creationTimestamp).toRelative(...)将 Kubernetes 事件的creationTimestamp转成相对时间展示并显式指定locale: en保持展示稳定。这个模式恰好回应了 ADR 的核心命题toRelative()正是原生 Date 难以完成、而标准库应该提供的典型能力。典型用法二遵循用户 locale 的本地化格式化与 ADR010 配套的是后续决策 ADR012: Use Luxon.toLocaleString and date/time presets为了让用户看到自己熟悉的日期格式Backstage 要求展示日期/时间时使用toLocaleString配合 Luxon 的日期/时间预设而不是自定义toFormat模板。ADR012 给出的对照示例是const date new luxon.DateTime(); /* 避免 */ date.toFormat(yyyy LLL dd); // 2014 Aug 06 date.toFormat(yyyy LLL dd hh:mm); // 2014 Aug 06 12:01 /* 应该改为 */ date.toLocaleString(luxon.DateTime.DATE_MED); // US: Oct 14, 1983 | FR: 14 oct. 1983 date.toLocaleString(luxon.DateTime.DATETIME_MED); // US: Oct 14, 1983, 9:30 | FR: 14 oct. 1983 9:30仓库中的合规实现可以见 Scaffolder 任务列表的创建时间列 CreatedAtColumn.tsximport { DateTime } from luxon; export function CreatedAtColumn({ createdAt, locale }: CreatedAtColumnProps) { const createdAtTime DateTime.fromISO(createdAt); const userLocale locale || window.navigator.language || en-US; const formatted createdAtTime.setLocale(userLocale).toLocaleString({ ...DateTime.DATETIME_SHORT_WITH_SECONDS, }); return Typography paragraph{formatted}/Typography; }这段代码同时体现了 ADR010 与 ADR012 两条约束的落地细节用DateTime.fromISO解析 ISO 时间戳而非手工new Date用setLocale把用户语言环境回退到window.navigator.language再回退到en-US注入DateTime不可变对象最后用预设DATETIME_SHORT_WITH_SECONDS完成本地化格式化全程没有一行自定义格式模板。对插件开发者的实践含义综合 ADR010 的约定与仓库现状如果你在 Backstage 上开发插件或阅读其源码可以遵循以下准则依赖声明在你自己的插件包中把luxon声明为dependencies版本对齐仓库主流的^3.x而不是引入 Moment 或其他日期库解析与展示解析时间戳优先DateTime.fromISO展示相对时间用toRelative()展示绝对时间用toLocaleString 官方预设如DATE_MED、DATETIME_MED、DATETIME_SHORT_WITH_SECONDS避免手写toFormat模板尊重 locale展示层尽量通过setLocale注入用户语言环境可参考 CreatedAtColumn.tsx 的三级回退写法评审检查点ADR012 的 Consequences 还明确指出需要审计既有 UI 中的日期展示使其符合约定并在后续 PR 评审中持续把关甚至推动把该规则自动化为 lint 检查——因此代码评审时是否使用了第二个日期库/自定义格式模板是一个明确的否决项。小结ADR010 的篇幅不长但它是 Backstage 全仓库日期处理风格的基础设施它以原生Date能力不足 Moment.js 包体大、可变、被官方 sunset为前提选择了不可变、基于Intl、API 平滑过渡的 Luxon并通过 Consequences 把选择固化成了对全部核心包与插件的强制性约定。当前仓库中 20 余个包的^3.x依赖声明、78 个文件的from luxon导入以及 ItemDetail.tsx、CreatedAtColumn.tsx 中的真实用法共同验证了这一决策已完全落地并与 ADR012 一起构成 Backstage 前端日期展示的统一规范。【免费下载链接】backstageBackstage is an open framework for building developer portals项目地址: https://gitcode.com/GitHub_Trending/ba/backstage创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表