Full rewrite proposal
See original GitHub issue@smirzaei already hinted that it might be a good idea to do a full rewrite of this library. I’ve been thinking a bit, and I’d like to share some of my thoughts of what I think would be good to include in a rewrite.
Perhaps we could use this issue as a place to discuss, and as a central place to monitor the progress of these issues once we start implementing them.
A quick overview:
- Getting a clear vision of the purpose boundaries of this library.
- Source code in modern EcmaScript (es2017 for example)
- Split currency and formatting data
- Allow for importing of specific currency and formatting files
- Create browser build (using something like webpack/rollup)
Not code-specific, but perhaps worth discussing:
In detail
Getting a clear vision of the purpose boundaries of this library
We’ve already had a bit of a discussion regarding the purpose of this library in #30. I think it might be a good idea to formulate the purpose of this library, and the problem scope it takes on. My attempt:
- currency-formatter is a library of currency formats.
- the actual formatting is done by accounting.js.
- currency-formatter defines sane defaults for each currency and locale, but allows for overriding these defaults.
Thinking of our library in this context helps us constrain the use cases that we want to support. For example, we currently go through a bit of effort to export the list of currencies as an array. I don’t think we should do this. IMHO we should expose each format we have, but leave it up to users to wrap it into one big array if they want to.
Source code in modern EcmaScript
Would involve setting up babel, since modules should provide an ES5 compatible version.
Split currency and formatting data
I think we might want to revise the data structure of our formats. As @Gwened pointed out in #37, a currency can have different formats, even within a single country:
For example, I think Canadians speaking French will use 5$ while English speakers write $5. In a similar way, if I’m targeting brits traveling in Europe, I would write €5 instead of 5 €.
I think it might be a good idea to split our formatting data up into currency, and locale formatting. Where currency data is (surprise) specified per currency, while locale formatting data should perhaps be specified per language (‘en’, ‘es’, ‘de’, …etc) or even per locale (‘en-US’, ‘en-GB’, ‘de-DE’, ‘de-AT’, …etc). These currency and locale formats could look like this:
Currency:
{
code: 'USD',
symbol: '$',
decimalDigits: 2
defaultLocale: 'en-US'
}
Locale:
{
locale: 'en-US',
thousandsSeparator: ' ',
decimalSeparator: '.',
symbolOnLeft: false,
spaceBetweenAmountAndSymbol: true,
}
We could map the current list of currencies to these two types of files. A nice benefit that comes with this structure would be that a lot of redundant formatting data can be captured in “language” level formats (‘en’, ‘de’) as opposed to duplicating all of the number formatting information. For example; 85 currencies share the exact same values as USD
for thousandsSeparator
, decimalSeparator
, symbolOnLeft
, and decimalDigits
:
Object.values(currencies).filter(c => (
c.thousandsSeparator === ',' &&
c.decimalSeparator === '.' &&
c.symbolOnLeft === true &&
c.decimalDigits === 2).length
))
// > 85
We could just write a single formatting file with locale: 'en'
and set defaultLocale: 'en'
for all of these 85 currencies.
Allow for importing of specific currency and formatting files
As requested in #34.
I personally think this will be the most important, as well as the most challenging feature. I’ve recently gone through the process of optimizing the performance of my own app, and stripping unused code is the first place to start. Allowing users to whitelist currencies would be a straightforward way to reduce the amount of unused bytes.
To make this happen we need to split formatting data into separate files, and provide a way for users to add currency and locale formatting data. (As a side note, we should probably have a convenience build or entrypoint which contains all formatting data.)
I’m a fan of how react-intl
does this:
import {addLocaleData} from 'react-intl';
import en from 'react-intl/locale-data/en';
import fr from 'react-intl/locale-data/fr';
import es from 'react-intl/locale-data/es';
addLocaleData([...en, ...fr, ...es]);
If we end up splitting currency and locale data, we would need two functions; addCurrencyData
and addLocaleData
. Given the defaultLocale
, we could have currency files auto-import their default locale. This would result in a simpler API for users that don’t care about locale formatting (they’ll never have to call addLocaleData
). Downside; if you only need to support a small set of locales, but all currencies, we might end up importing a lot of locale formats which will never be used.
Create browser build (using something like webpack/rollup)
Things to discuss:
- What bundler to use
- Do we create separate bundles for every formatting file?
- Do we publish the browser bundles to a CDN?
Issue Analytics
- State:
- Created 6 years ago
- Comments:18 (7 by maintainers)
Top GitHub Comments
Great sum up. Thanks @edorivai as always 😁 and I agree with pretty much every point you made 🙂
Just one thing… Changing the locale structure doesn’t seem very straightforward to me and I don’t see an easy way to find the
defaultLocale
here:Plus our locale data is very sparse.
If we keep both object structures the same (currency and locale) then we can use them to override each other (Object.assign). And people can add their locale info eventually.
This makes the most sense to me
Going to copy some parts of my comment
Set a default locale:
Set a default for both the locale and currency:
We also have the flexibility of allowing the user to add as many override objects as (s)he wants. (Who knows, it might come in handy in some situations)
Some comments
Up to you. I have very little experience with frontend build tools and bundlers.
I don’t exactly know what you mean by that.
It would probably makes it easier for people to import it in their web app if they are not using a build tool. Is there an automated way to do this?
And lastly @edorivai if you like, I can add you as a maintainer, you’ve been a huge help 😃
I’m willing to give a hand to get this library rewritten and a bit more customizable if you need any more colaborators. Send me a message if you’re looking for help. This is an extremely valuable piece of code that helps lots of people. 😃