question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

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:open
  • Created 6 years ago
  • Comments:18 (7 by maintainers)

github_iconTop GitHub Comments

1reaction
smirzaeicommented, Apr 15, 2017

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:

Currency:
{
	code: 'USD',
	symbol: '$',
	decimalDigits: 2
	defaultLocale: 'en-US'
}

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

import { format } from 'currency-formatter'
import USD from 'currency-formatter/currencies/USD'
import en_US from 'currency-formatter/locales/en-US'

const customUserOverrides = { symbolOnLeft: false } // this is optional

format(1234, USD, en_US, customUserOverrides)
format(1234, USD, en_US)

Set a default locale:

import { format, addLocale } from 'currency-formatter'
import USD from 'currency-formatter/currencies/USD'
import en_US from 'currency-formatter/locales/en-US'

addLocale(en_US)

const customUserOverrides = { symbolOnLeft: false } // this is optional

format(1234, USD, customUserOverrides)
format(1234, USD)

Set a default for both the locale and currency:

import { format, addCurrency, addLocale } from 'currency-formatter'
import USD from 'currency-formatter/currencies/USD'
import en_US from 'currency-formatter/locales/en-US'

addCurrency(USD)
addLocale(en_US)

const customUserOverrides = { symbolOnLeft: false } // this is optional

format(1234, customUserOverrides)
format(1234)

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)

import { format, addCurrency, addLocale } from 'currency-formatter'
import USD from 'currency-formatter/currencies/USD'
import en_US from 'currency-formatter/locales/en-US'

addCurrency(USD)
addLocale(en_US)

const o1 = { symbolOnLeft: false }
const o2 = { thousandsSeparator: ',' }

format(1234, o1, o2)

Some comments

What bundler to use

Up to you. I have very little experience with frontend build tools and bundlers.

Do we create separate bundles for every formatting file?

I don’t exactly know what you mean by that.

Do we publish the browser bundles to a CDN?

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 😃

0reactions
nunocfcommented, Mar 8, 2018

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. 😃

Read more comments on GitHub >

github_iconTop Results From Across the Web

3 steps to handle the dreaded Redesign /Rewrite /Rebuild ...
3 steps to handle the dreaded Redesign /Rewrite /Rebuild proposal · Step 1: Start discovery with an open mind · Step 2: Reframe...
Read more >
A Five-Step Process for Planning a Rewrite of a Legacy Project
Below is a simple five-step process my team has informally adopted when planning a rewrite of a legacy project. Perhaps it will be...
Read more >
Proposal Rewrite - Crowdspring
The client is running a article, report, & proposal project on crowdspring. The client is offering $500 in awards. The world's best entrepreneurs, ......
Read more >
Pitching an Application Rewrite – 4 Essential Arguments
When proposing a major rewrite, you need to demonstrate four things. 1. Establish that there's a measurable problem with the existing codebase.
Read more >
I will rewrite essays research proposals and research papers
Fiverr freelancer will provide Research & Summaries services and rewrite essays research proposals and research papers including Additional research within ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found