accounting vs currency.js vs dinero.js vs numeral
前端货币与数字格式化库技术选型
accountingcurrency.jsdinero.jsnumeral类似的npm包:

前端货币与数字格式化库技术选型

accountingcurrency.jsdinero.jsnumeral 都是用于处理 JavaScript 中数字格式化、货币显示及计算的库。accountingnumeral 是早期的经典方案,主要用于格式化,但目前已不再维护。currency.js 专注于轻量级的货币处理,适合简单的展示需求。dinero.js 则提供了不可变的对象模型,专注于金融级别的计算精度和安全性。开发者需要根据项目的维护性要求、计算复杂度以及是否需要处理货币精度来选择合适工具。

npm下载趋势

3 年

GitHub Stars 排名

统计详情

npm包名称
下载量
Stars
大小
Issues
发布时间
License
accounting04,980-14512 年前-
currency.js03,382-615 年前MIT
dinero.js06,789858 kB235 个月前MIT
numeral09,704-3459 年前MIT

前端货币与数字格式化库深度对比:accounting vs currency.js vs dinero.js vs numeral

在前端开发中,处理货币和数字格式化看似简单,实则暗藏陷阱。JavaScript 的原生浮点数计算容易导致精度丢失,而不同地区的货币格式差异巨大。accountingcurrency.jsdinero.jsnumeral 是生态中常见的解决方案,但它们的设计目标和维护状态截然不同。本文将从维护状态、格式化能力、计算安全性和 API 设计四个维度进行深度对比。

⚠️ 维护状态与风险提示

选择第三方库时,维护状态是首要考量因素。一个不再维护的库可能包含未修复的安全漏洞,且无法兼容未来的 JavaScript 版本。

accountingnumeral 均已停止维护多年。

  • 最后更新时间大约在 2017 年左右。
  • 社区不再修复 Bug 或添加新功能。
  • 在新项目中使用它们会带来技术债务。

currency.jsdinero.js 目前相对活跃。

  • currency.js 专注于轻量级场景,更新稳定。
  • dinero.js 专注于金融级精度,v1 版本稳定,v2 版本正在重构中。
// 风险提示:以下库已不再维护,新项目慎用
import accounting from 'accounting'; 
import numeral from 'numeral'; 

// 推荐:以下库维护状态较好
import currency from 'currency.js';
import Dinero from 'dinero.js';

🎨 格式化能力对比

格式化是这些库最基础的功能。我们需要观察它们如何处理千位分隔符、小数位以及货币符号。

accounting 提供专门的货币格式化方法,配置项较为传统。

// accounting: 专门针对货币
accounting.formatMoney(12345678, { symbol: '¥', precision: 2 });
// 输出:¥12,345,678.00

currency.js 链式调用,默认处理货币符号,支持简单配置。

// currency.js: 链式格式化
currency(12345678, { symbol: '¥' }).format();
// 输出:¥12,345,678.00

dinero.js 基于对象创建,格式化方法更严谨,支持国际化参数。

// dinero.js: 基于对象实例
Dinero({ amount: 12345678, currency: 'CNY' }).format();
// 输出:¥12,345,678.00 (取决于环境配置)

numeral 通用数字格式化,需要通过字符串模板定义格式,灵活性高但易出错。

// numeral: 字符串模板定义格式
numeral(12345678).format('¥0,0.00');
// 输出:¥12,345,678.00

🧮 计算安全性与精度

这是区分普通格式化库和金融库的关键。JavaScript 的 0.1 + 0.2 !== 0.3 问题在货币计算中是致命的。

accounting 本质上是对原生 Number 的包装,不解决 浮点数精度问题。

// accounting: 无安全计算,直接使用原生数学
// 不推荐用于计算,仅用于展示
const total = 0.1 + 0.2; 
accounting.formatMoney(total); // 可能显示 ¥0.30000000000000004

currency.js 内部使用整数运算来处理小数,避免了大部分精度问题,适合简单加减。

// currency.js: 内部处理精度
const val1 = currency(0.1);
const val2 = currency(0.2);
val1.add(val2).format(); // 输出:¥0.30

dinero.js 严格使用整数(最小货币单位)进行计算,完全避免浮点数误差,最安全。

// dinero.js: 基于最小单位(如分)计算
const d1 = Dinero({ amount: 10, currency: 'USD' }); // 10 分
const d2 = Dinero({ amount: 20, currency: 'USD' }); // 20 分
d1.add(d2).format(); // 输出:$0.30

numeral 同样基于原生 Number,不解决 精度问题,仅提供格式化。

// numeral: 无安全计算
const total = 0.1 + 0.2;
numeral(total).format('0.00'); // 可能显示 0.30,但内部值仍不精确

🛠️ API 设计风格

API 的设计影响代码的可读性和可维护性。

accounting 采用传统函数式调用,配置通过对象传递。

// accounting: 函数 + 配置对象
accounting.formatNumber(1000, { thousand: ',', decimal: '.' });

currency.js 采用链式调用,代码流畅,适合快速开发。

// currency.js: 链式调用
currency(1000).multiply(2).format();

dinero.js 采用不可变对象模式,每次操作返回新实例,便于调试和追踪。

// dinero.js: 不可变实例
const d = Dinero({ amount: 1000, currency: 'USD' });
const newD = d.add(d); // d 不变,newD 是新对象

numeral 采用链式调用,但依赖字符串模板,类型安全性较差。

// numeral: 链式 + 字符串模板
numeral(1000).format('0,0');

📊 总结对比表

特性accountingcurrency.jsdinero.jsnumeral
维护状态❌ 已停止✅ 活跃✅ 活跃❌ 已停止
主要用途货币格式化轻量货币计算金融级计算通用数字格式化
精度安全❌ 原生浮点✅ 内部整数处理✅ 严格整数单位❌ 原生浮点
API 风格函数式链式调用不可变对象链式 + 模板
包体积极小中等

💡 架构师建议

在选择这些库时,请根据业务场景的复杂度做出决定。

对于现代新项目

  • 如果涉及 金钱计算,首选 dinero.js。它的不可变设计和整数运算能避免很多财务 bug。虽然 API 稍微繁琐,但安全性值得付出。
  • 如果只是 简单展示 货币,且希望代码轻量,currency.js 是很好的平衡点。它比 dinero.js 简单,比 accounting 安全。
  • 对于 非货币数字(如百分比、文件大小),建议优先使用原生 Intl.NumberFormat,而不是 numeral。原生 API 性能更好且无依赖。

对于旧项目维护

  • 如果现有代码使用了 accountingnumeral,且没有计算精度问题,可以暂时保留。但在新功能开发中,应逐步迁移到更安全的方案。

最终结论dinero.js 是处理金融逻辑的专业工具 — 安全但较重。currency.js 是前端展示的轻量利器 — 简单且够用。accountingnumeral 已成为历史 — 除非维护旧代码,否则不应再引入新项目。

如何选择: accounting vs currency.js vs dinero.js vs numeral

  • accounting:

    仅建议在维护旧项目时使用,因为该库已多年未更新,缺乏现代 JavaScript 特性支持。如果你的项目只需要简单的货币符号格式化且无法引入新依赖,它可以勉强胜任。但在新项目中,应避免使用此库,转而选择更活跃的替代方案。

  • currency.js:

    适合需要轻量级货币格式化且涉及简单加减计算的场景。它的 API 简单直观,包体积小,不会给项目带来太多负担。如果你的需求主要是前端展示货币金额,且不需要复杂的金融逻辑,这是一个不错的选择。

  • dinero.js:

    适合对货币计算精度和安全性有严格要求的金融类应用。它采用不可变数据模式,避免了浮点数误差,并提供了丰富的货币操作方法。如果你的项目涉及复杂的金额计算、分配或转换,应优先选择此库以确保数据准确。

  • numeral:

    仅建议在维护旧项目或非货币类的通用数字格式化场景中使用。该库已停止维护,存在潜在的安全和兼容性风险。如果只需要格式化百分比、字节大小等非货币数字,且能接受潜在风险,可以考虑,但新项目推荐使用 Intl API 或其他活跃库。

accounting的README

accounting.js is a tiny JavaScript library for number, money and currency parsing/formatting. It's lightweight, fully localisable, has no dependencies, and works great client-side or server-side. Use standalone or as a nodeJS/npm and AMD/requireJS module.

Visit the plugin homepage for demos and documentation: http://openexchangerates.github.io/accounting.js/

Please checkout or download the latest stable tag before using in production. Bug reports and pull requests are welcome.

Maintained by Open Exchange Rates and originally by @josscrowcroft and other contributors.


Works great with:

  • money.js - a tiny (1kb) standalone JavaScript currency conversion library, for web & nodeJS
  • Open Exchange Rates - the free currency conversion data API

Changelog

v0.4.1 - Alias accounting.formatNumber() as accounting.format()

v0.4 - Transferred repository to Open Exchange Rates for ongoing maintenance

v0.3.2 - Fixed package.json dependencies (should be empty object)

v0.3.0

  • Rewrote library structure similar to underscore.js for use as a nodeJS/npm and AMD module. Use npm install accounting and then var accounting = require("accounting"); in your nodeJS scripts.
  • Also works with requireJS or any AMD module loader.
  • unformat now only attempts to parse the number if it's not already a valid number.
  • acounting.unformat now also aliased as acounting.parse
  • Fixed an IE bug in the defaults method

v0.2.2 - Fixed same issue as #Num: #24 in formatNumber; switch to Google Closure Compiler for minified version.

v0.2.1 - Fixed issue #Num: #24 (locally-defined settings object was being modified by formatMoney)

v0.2

  • Rewrote formatting system for formatMoney and formatColumn for better control of string output
  • Now supports separate formats for negative and zero values (optionally) via accounting.settings.currency.format
  • Internal improvements and helper methods

v0.1.4

  • formatMoney recursively formats arrays
  • Added Jasmine test suite (thanks to millermedeiros) and QUnit functionality/speed tests

v0.1.3

  • Added configurable settings object for default formatting parameters.
  • Added format parameter to control symbol and value position (default "%s%v", or [symbol][value])
  • Methods consistently accept object as 2nd parameter, matching/overriding the library defaults

v0.1.2

  • formatColumn works recursively on nested arrays (e.g. accounting.formatColumn( [[1,12,123,1234], [1234,123,12,1]] ), returns matching array with inner columns lined up)
  • Fix rounding in formatNumber

v0.1.1

  • Added toFixed method (accounting.toFixed(value, precision)), which treats floats more like decimals for more accurate currency rounding
  • Minified version preserves semicolons
  • Fixed NaN errors when no value in unformat

v0.1 - First version