资讯详情

资讯详情

Dinero.js 为何采用独立函数而非链式方法:模块化、Tree-shaking 与函数式组合设计解析

金融科技【免费下载链接】dinero.jsCreate, calculate, and format money in JavaScript and TypeScript项目地址https://gitcode.com/gh_mirrors/di/dinero.js点击查看免费下载本篇技术指南聚焦 Dinero.js 的核心 API 设计哲学为什么add(d1, d2)而不是d1.add(d2)。文章将从模块化与 tree-shaking 的根本动机出发结合仓库源码类型定义、core 层实现、package.json 配置逐步拆解独立函数设计的底层原理并给出函数式组合、自定义链式封装的实战方案。读完你将理解这一设计如何让 Dinero.js 保持极小的打包体积以及如何在你的项目中自由选择函数式或链式风格。两种 API 风格的直观对比Dinero.js 的运算 API 全部采用独立函数的形式把 Dinero 对象作为参数传入而不是作为对象方法调用。import { add } from dinero.js; // 函数式Dinero.js 的方式 add(d1, d2);对比链式方法风格// 链式非 Dinero.js 的方式 d1.add(d2);两种写法在语义上等价——都将d1与d2相加并返回新的结果。但底层的数据结构与代码组织方式截然不同在 Dinero.js 中运算逻辑不挂在对象上而是由库顶层导出的纯函数承载。这一点可以从源码中得到直接印证。根本原因模块化带来的 Tree-shaking 能力FAQ 明确指出Dinero.js 选择独立函数的首要原因是模块化modularity独立函数可以被打包器bundler消除未使用的代码而链式方法意味着每个 Dinero 对象都会在其原型prototype上携带全部运算方法——包括你从未使用过的那部分。从源码看这一设计贯穿始终Dinero 类型定义 中对象只有四个字段calculator计算器、formatter格式化器、create工厂函数和toJSON序列化没有任何加法、乘法、格式化等运算方法全部 25 个运算/格式化函数add、multiply、allocate、toDecimal、compare等由 api/index.ts 以独立命名导出的方式统一暴露并最终从 src/index.ts 汇出每个函数都从传入的 Dinero 对象上解构出calculator再委托给 core 层实现例如 api/add.tsexport function addTAmount, TCurrency extends string( ...[augend, addend]: AddParamsTAmount, TCurrency ) { const { calculator } augend; const addFn safeAdd(calculator); return addFn(augend, addend); }由于运算逻辑与对象结构彻底解耦打包器可以精准地按需保留你只 import 了add那么multiply、convert、allocate等函数的代码就能在产物中被剔除。为什么链式方法做不到这一点链式 API 必须把每个方法都挂在原型上即便你只调用其中两个整个原型链上的方法及其依赖也会进入最终包体因为它们是一个整体对象的一部分。官方配置层面的佐证仓库中的两个证据进一步确认了这一论点packages/dinero.js/package.json 显式声明sideEffects: false告知打包器所有模块均无副作用、可以被安全地消除——这是 tree-shaking 生效的前提官方文档 optimizing-for-production 明确指出如果只用 Dinero.js 做加减那么最终产物中只应包含dinero、add、subtract及其依赖并给出建议import { dinero, add, subtract } from dinero.js; import { USD } from dinero.js/currencies; // 只有这些函数会进入最终打包产物这种按需引入的能力直接源于独立函数 无副作用模块的设计。对一个金额计算库而言包体大小在移动端和性能敏感场景中尤为重要。组合性独立函数天然适配函数式工具独立函数与函数式编程工具链的组合是自然且顺滑的。FAQ 给出了用ramda的pipe串联多个运算的示例——每一步都接受 Dinero 对象并返回新的 Dinero 对象恰好满足管道pipeline的输入输出契约import { pipe } from ramda; import { multiply, add, toDecimal } from dinero.js; pipe( (d) multiply(d, 2), (d) add(d, fee), (d) toDecimal(d), )(price);pipe之所以能成立是因为 DineroBinaryOperation 与 DineroUnaryOperation 等类型本身就是输入值 → 输出值的函数签名运算之间以数据流衔接而不是依赖对象内部可变状态。底层原理运算结果是不变的新对象组合的前提是每一步都不修改原对象。core 层实现保证了这一点以 core/api/add.ts 为例其内部unsafeAdd通过augend.toJSON()读取金额与精度再用augend.create({ amount, currency, scale })构造并返回全新的 Dinero 对象function unsafeAddTAmount(calculator: DineroCalculatorTAmount) { return function addTCurrency extends string( ...[augend, addend]: AddParamsTAmount, TCurrency ) { const { amount: augendAmount, currency, scale } augend.toJSON(); const { amount: addendAmount } addend.toJSON(); const amount calculator.add(augendAmount, addendAmount); return augend.create({ amount, currency, scale, }); }; }结合createDinerocreateDinero.ts返回的对象结构可知Dinero 是不可变immutable的值对象所有运算都产出新实例。这也正是它能在pipe、map、reduce等纯函数语境中安全流动的根本原因。测试用例同样印证了这种调用方式例如 api/tests/add.test.ts 中直接以add(d1, d2)调用并断言返回快照const snapshot toSnapshot(add(d1, d2)); expect(snapshot).toEqual({ amount: 600, currency: USD, scale: 2, });自定义链式封装鱼与熊掌兼得函数式风格的优势是模块化与组合性但连续多步运算内联嵌套时确实可读性欠佳。FAQ 给出了一个典型痛点——嵌套顺序与阅读顺序相反// 实际执行先 multiply 后 add但看起来像是先加后乘 add(multiply(d1, 2), d2);如果你更偏好链式写法完全可以在不引入额外依赖的情况下用薄薄一层包装函数自行实现。FAQ 提供了可运行的模板function chain(d) { return { multiply: (n) chain(multiply(d, n)), add: (other) chain(add(d, other)), }; } chain(d1).multiply(2).add(d2);每个方法都调用对应的 Dinero.js 独立函数并把结果重新包装回chain从而在保留链式可读性的同时仍然只按需引入你真正用到的那些函数。库本身不需要为这种个性化风格付出任何打包代价——这正是库保持精简、风格交还给使用者的设计取向。适用边界与总结FAQ 的结论是对大多数使用场景而言函数式风格表现良好并能让打包体积保持最小。追求最小包体、按需引入 → 直接使用独立函数偏好函数式组合、需要与pipe/compose等工具协作 → 独立函数天然契合偏好链式可读性 → 用自定义chain包装器按需封装。从 src/index.ts 的导出结构可以清楚看到Dinero.js 将数据Dinero 对象与行为独立函数彻底分离对象只携带 calculator/formatter 配置与金额数据所有运算、比较、格式化的行为都由纯函数统一承载。这一设计让库在模块化、可测试性与 tree-shaking 友好性上同时获益也回答了为什么是函数而不是方法这个关于 API 设计本质的问题。赞分享金融科技【免费下载链接】dinero.jsCreate, calculate, and format money in JavaScript and TypeScript项目地址https://gitcode.com/gh_mirrors/di/dinero.js点击查看免费下载相关推荐dinero.js v2 完全重写解读从链式 API 到可 tree-shaking 的函数式货币计算库dinero.js v2 完全重写解读从链式 API 到可 tree shaking 的函数式货币计算库 本文基于仓库根目录 CHANGELOG.md htt金融科技dinero.js 按需导入实现 Tree-Shaking独立函数 API 的打包体积优化实战指南dinero.js 按需导入实现 Tree Shaking独立函数 API 的打包体积优化实战指南 本文基于 dinero.js 仓库内的 .agents/s金融科技MaxViT模型变种全面解析从CoAtNet到MaxxViT-V2的演进之路MaxViT模型变种全面解析从CoAtNet到MaxxViT V2的演进之路 在计算机视觉领域 MaxViT模型变种 代表了卷积与注意力机制融合的最新进展。上一篇如何用Inertia.js打造元宇宙级沉浸式Web体验2023终极指南下一篇前端自动化部署安全MDN Learning Area凭证管理与权限控制创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →