Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Intl Support #23

Closed
danilobuerger opened this issue Jul 12, 2019 · 182 comments
Closed

Intl Support #23

danilobuerger opened this issue Jul 12, 2019 · 182 comments
Labels
enhancement New feature or request

Comments

@danilobuerger
Copy link

In https://github.com/facebook/hermes/blob/master/doc/Features.md Intl is listed as Excluded From Support. With

Hermes plans to target ECMAScript 2015 (ES6), with some carefully considered exceptions.

What are those considerations regarding Intl? (If its about size, why not have a variant like jsc does?)
How should i18n look like with Hermes?

@fbartho
Copy link

fbartho commented Jul 12, 2019

Intl is super important for us, and unfortunately, it's a blocker for my team. The Polyfills we tried before switching to jsc-intl weren't complete (they allowed compilation/basic testing, but didn't work in actual localized environments).

Is there a plan for when Intl might be discussed again for the Hermes Engine?

@dulinriley
Copy link
Contributor

It will help us prioritize work on Intl if we know the following things:

  • Its main use cases (most popular function it has) to the RN community
  • Any important libraries that depend on it
  • What alternatives exist (is there a JS-only way to implement it?)

I don't remember the exact conversation we had about Intl, but I think it was related to ICU's binary size, and that it is not part of the normal EcmaScript JS spec.

@avp or @ridiculousfish have more context on this

@danilobuerger
Copy link
Author

Its main use cases (most popular function it has) to the RN community

Enabling I18n for apps regarding:

  • Date / Time Formats
  • Relative Time Formats
  • List Formats
  • Number (also Currency) Formats
  • Plural Rules

Any important libraries that depend on it

https://github.com/formatjs/react-intl (> 10K Stars)
https://github.com/moment/luxon (> 8K Stars)

What alternatives exist (is there a JS-only way to implement it?)

As pointed out by @fbartho, polyfilling doesn't work properly. Every other solution is incomplete at least regarding locale rules around the world.

but I think it was related to ICU's binary size

If it is just about binary size, it could be done like JSC: a variant with Intl.
See https://github.com/react-native-community/jsc-android-buildscripts/#international-variant

and that it is not part of the normal EcmaScript JS spec

However, lots of functions that are part of the ECMAScript 2015, are dependent on Intl to function "properly", or at least need a locale aware implementation anyway. For example:

20.3.4.39 Date.prototype.toLocaleString ( [ reserved1 [ , reserved2 ] ] )
An ECMAScript implementation that includes the ECMA-402 Internationalization API must implement the Date.prototype.toLocaleString method as specified in the ECMA-402 specification. If an ECMAScript implementation does not include the ECMA-402 API the following specification of the toLocaleString method is used.

This function returns a String value. The contents of the String are implementation-dependent, but are intended to represent the Date in the current time zone in a convenient, human-readable form that corresponds to the conventions of the host environment’s current locale.

@dulinriley dulinriley added the enhancement New feature or request label Jul 15, 2019
@TheTimeWalker
Copy link

TheTimeWalker commented Jul 16, 2019

One thing to add: Intl works perfectly out of box on iOS as it has to use its V8 (oops!) JavaScriptCore engine which already integrates this. So I find it strange why we're trying to back off from Intl support as this would just confuse RN developers with the iOS and Android feature gap.

@fbartho
Copy link

fbartho commented Jul 16, 2019

That's a great point @TheTimeWalker -- this is a "platform compatibility issue" where iOS & Android's JavaScript engines differ. (Nit: iOS uses the JavaScriptCore engine rather than the V8 engine, but your point is the same).

I guess the key question is: What is this project's driving mandate with regards to differences between iOS & Android? -- Presumably the expectation is that there shouldn't be significant framework-level differences? Especially not in things that can't be polyfilled-well.

Unfortunately, the existing Polyfills in this case are insufficient. React-Native developers targeting more than one language will be stuck on jsc-intl unless this feature is provided by Hermes!

@gmaclennan
Copy link

As @danilobuerger clearly states, there is no complete and reliable JS-only solution to this. For I18n apps Intl is needed. It adds to binary size, but as I understand it that's because I18n is so darn complicated with so many edge-cases.

@wyzzy
Copy link

wyzzy commented Jul 30, 2019

Strong +1 for including Intl support out-of-the-box in Hermes, having just encountered this limitation ourselves!

At the moment the lack of Intl support on Android RN is a major source of inconsistency in behaviour between iOS and Android. On iOS Intl 'just works' as expected, but not so on Android, where you're stuck trying to find some workable solution to restore parity in behaviour on the two platforms. On iOS, Number.prototype.toLocaleString() for formatting numbers and currency values all work as expected, as does Date.prototype.toLocaleString() for dates, and all the Intl API...

The lack of Intl support on Android's out-of-the-box JSC was one significant hurdle we encountered in enabling our iOS-first RN app for Android. As many folks have said, the pollyfills just don't work well enough and feel like an unsatisfactory hack.

For our investment app, date/time and currency formatting are the primary drivers, though relative time rules, plural rules, and list formats would all undeniably help offer a more polished user experience.

Needing to include a custom JSC build on Android is non-trivial and really shouldn't be necessary for such a fundamental piece of functionality!

If Hermes is worried about size, some RN config to optionally exclude Intl support for those (rare?) apps that don't need it might be a way forward. Surely these days most commercial quality apps need to reliably present localised time & date or numeric/currency values?

If Hermes did fully support Intl, switching from the existing JSC would be a no-brainer for us. On the other hand, no support means we would perhaps be better off with a JSC build that does support it?? Feels like a problem that Hermes needs an answer to, one way or the other.

I18n certainly is darn complicated, which is precisely why it's so important that the platform itself offers first-class support for Intl out of the box! Even on Android.

@learnyst

This comment has been minimized.

@jcurtis
Copy link

jcurtis commented Aug 13, 2019

Intl is a major concern for all the apps I have ever worked on. Today we're using react-intl which is one of the most popular React libraries for handling intl. As stated before, there are no polyfills that work properly on Android right now.

I'd be curious if someone could tell us what Facebook uses to handle intl in their React Native apps? Specifically for number and date formatting.

facebook-github-bot pushed a commit that referenced this issue Oct 30, 2019
Summary:
This is used by the generateReleaseBuildConfig, which is needed when
fbjni is included as a submodule.
Pull Request resolved: facebookincubator/fbjni#23

Test Plan:
`./gradlew generateReleaseBuildConfig`
(In PyTorch) `./gradlew assembleRelease`

Reviewed By: passy

Differential Revision: D18226540

Pulled By: dreiss

fbshipit-source-id: c4ece2d1d8e7cbb095bc6991bbad53393e6f6ecb
@gpawlik
Copy link

gpawlik commented Dec 12, 2019

@dulinriley is there any more information that you need in order to prioritise this issue?

@feruzm
Copy link

feruzm commented Dec 22, 2019

Big thanks to this thread, Hermes is great but we need support for Intl which most fundamental part of any app.

@OtacilioN

This comment has been minimized.

@OtacilioN
Copy link

Hey folks,

Is that any workaround suggested for Number.prototype.toLocaleString() while they don't implement Intl ?

We broke our minds for some weeks with this bug because when we were using the debug mode in React Native, the Number.prototype.toLocaleString() works, I think because it uses my browser engine to run JavaScript, but as soon we assemble the app or turnOff the debug mode, Number.prototype.toLocaleString() starts to no work.

@fbartho
Copy link

fbartho commented Jan 2, 2020

@OtacilioN -- On my team we're still using org.webkit:android-jsc-intl:r245459 until Hermes supports Intl (we would love to use Hermes for Android Performance reasons!!) Not to give you useless advice, but that's what I recommend.

And I ran into exactly the same debug-time issues with some other features including Proxy (also missing in Hermes, #33), before that was updated to be available on android-jsc. I feel your pain!

@OtacilioN

This comment has been minimized.

@mars-lan

This comment has been minimized.

@patrickkempff
Copy link

How does facebook handle Intl in their apps when using Hermes?

@thinklinux

This comment has been minimized.

@tmikov
Copy link
Contributor

tmikov commented Jan 9, 2020

Sorry about the delayed response here. Internally at Facebook we use fbt, with its own specific translation assets handling, and translation dictionary shipped with the app binary. fbt was open sourced a while back, and fortunately we have RN android variant in OSS now.

See:
https://github.com/facebookincubator/fbt
https://github.com/facebookincubator/fbt/tree/master/packages/fbt-rn-android-native
https://github.com/facebookincubator/fbt/tree/rn-demo-app

The published version currently builds for Android but AFAIK there is nothing preventing porting to iOS.

On the subject of Intl support: we would like to have it in Hermes, but it isn't our top priority, since, as described above, we don't use it internally. We welcome help from the community in implementing it.

@TheSavior
Copy link
Member

TheSavior commented Mar 27, 2020

EDIT: I found that Chrome Status shares data publicly on the usage of these APIs. I have gathered and ordered that data for the Intl APIs in this comment.

Additional anecdotal data is probably not as helpful now.


We are revisiting Intl support on Hermes and need your help figuring out which functions to prioritize. There are a ton of Intl APIs and I'd bet that only a handful of them are the most critical functions blocking Hermes adoption.

Please help us understand the particular function calls that are blocking your ability to use Hermes. For example, I've seen Number.prototype.toLocaleString() mentioned twice in this thread. That's the kind of specific example I'm looking for. "Relative Time Formats" is too vague. I'm sure there are many more functions that would be really nice to have but aren't as critical. Please mention them, but separately so I can track that.

Intl functions blocking usage of Hermes:

  • Number.prototype.toLocaleString()
  • Date.prototype.toLocaleString
  • Date.prototype.toLocaleTimeString
  • Intl.DateTimeFormat().resolvedOptions
  • Intl.DateTimeFormat().format() (specific options)
  • Intl.NumberFormat().format() (specific options)
  • Intl.RelativeTimeFormat().format()
  • String.prototype.localeCompare

Also, I saw a mention of the react-intl project. Can someone go through that and identify what Intl functions it uses and share those here?

Thanks!

@fbartho
Copy link

fbartho commented Mar 27, 2020

I'm not entirely sure how to search react-intl for "particular function calls" that need to be supported. I'm trying to join their slack to figure that out.

In addition to react-intl, a super popular library is MomentJS -- https://momentjs.com & its sub library moment-timezone https://momentjs.com/timezone/

Moment has a CI testing various browsers/environments, so maybe you can add hermes to that list, and then get an enumeration of the methods that are missing / fail tests?

@dlebedynskyi
Copy link

dlebedynskyi commented Mar 27, 2020

@TheSavior
I believe we are specifically interested in DateTime and TimeZone related ones such as

  • Date.prototype.toLocaleString
  • Date.prototype.toLocaleTimeString
  • Intl.DateTimeFormat().resolvedOptions
  • rest of timezone related things

For react-intl it is probably better to start with intl-messageformat as it is most used one.

@fbartho
I believe moment is not actually using Intl.

@fbartho
Copy link

fbartho commented Mar 27, 2020

Our codebase also directly uses

@janicduplessis
Copy link

I'm currently using the following polyfills for Hermes:

I'm using https://lingui.js.org/ as a higher level abstraction over intl apis.

I don't have anything blocking usage of hermes since it works fine with these polyfills. First thing would be to try and remove usage of the intl polyfill, this one actually implements a lot of apis, the list is available here https://github.com/andyearnshaw/Intl.js#implemented.

Here are some Intl apis I use either directly or through lingui-js:

  • Intl.NumberFormat for currency formatting.
  • Intl.DateTimeFormat for date formatting.
  • Intl.RelativeTimeFormat for relative date formatting (x days ago).

@TheSavior
Copy link
Member

@dlebedynskyi thanks, from my quick searching it looks like IntlMessageFormat isn't part of a finalized spec. Am I looking in the wrong place?

@TheSavior
Copy link
Member

@janicduplessis, it looks like the Intl APIs you list are a collection of multiple functions. Do you know which functions in those APIs you use? The more specific the better here :)

@tamlyn
Copy link

tamlyn commented Sep 21, 2022

Some other NumberFormat features are missing too:

// NOTE: NSNumberFormatter has following limitations:
// - "scientific" notation is supprted, "engineering" and "compact" are not.
// - roundingType is not supported.
// - compactDisplay is not supported.
// - signDisplay is not supported.
// - NSNumberFormatter has maximumIntegerDigits, which is 42 by default

@billnbell
Copy link

PK so we need a comprehensive list. What is the delta between Android and IOS?

@dlebedynskyi
Copy link

Is there a plan to support dateStyle and timeStyle on Android?

It is on iOS, but on Android poly fill is still required, if you try to those options

@mganandraj
Copy link
Contributor

It should be a fairly straightforward to add the support for dateStyle/timeStyle form Android platform 24+ ..

Could you file an issue if one doesn't exist? A PR would be welcome as well !

@dlebedynskyi
Copy link

@mganandraj created #926.

@joluet
Copy link

joluet commented Feb 27, 2023

Maybe worth pointing out that iOS's implementation is still missing support for NumberFormat.formatToParts.

Is it planned to add this anytime soon?

@arnolicious
Copy link

Can anyone else confirm that only on iOS, DateTimeFormat seems to not support any TimeZone Names starting with Etc, such as Etc/GMT, Etc/UTC Etc/Greenwich ?

All other TZs seem to work (Europe/..., Atlantic/... etc)

@billnbell
Copy link

Any new news?

@tmikov
Copy link
Contributor

tmikov commented May 31, 2023

Closing this, since Intl support has been added to Hermes. Please file separate issues for individual problems (of which there are many, since the implementation is not complete).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests