dojo / framework

Dojo Framework. A Progressive Framework for Modern Web Apps
https://dojo.io/
Other
581 stars 79 forks source link

Remove Globalize.js in favor of `Intl` (and `MessageFormat`) #250

Open mwistrand opened 5 years ago

mwistrand commented 5 years ago

Enhancement

Dojo currently uses Globalize.js for the bulk of its internationalization/localization functionality, but at this point Intl is well-supported and robust enough that it can handle most use cases. For supported browsers that lack Intl support, there are shims available (Intl and Intl.RelativeFormat). With that in mind, we can remove Globalize.js, use MessageFormat internally for managing ICU message formatting, and recommend the native Intl for anything else.

This would be a breaking change, and applications that use functions like formatCurrency would need to update to their native equivalents like Intl.NumberFormat. Perhaps @dojo/cli-upgrade-app could help mitigate any manual updates

With regard to the build, conditional polyfill loading should help reduce the bundle size, but it would also be possible to pre-compile any messages and therefore eliminate most of the bulk from the MessageFormat library as well. However, doing so will be difficult without a standard means of differentiating message bundles from other files. Just as Dojo uses m.css to distinguish CSS module files from other CSS files, perhaps a similar approach could be used for localized message files. The build would then pre-compile the messages in these files and MessageFormat could be ignored entirely. More discussion is needed here.

dasa commented 5 years ago

Could Luxon be used to help with this effort or would it be something that users could optionally use on top of this?

matt-gadd commented 5 years ago

@mwistrand I'm all for this 👍 a few comments:

agubler commented 5 years ago

@mwistrand I second that, any changes that move us closer to the native platform and dependency free are big wins for me.

It would be great if we could detail the affected areas of the framework, with the work that needs to be done. Then we can work towards a POC for version 6 👍

mwistrand commented 5 years ago

@dasa Users are always free to use other libraries in their applications/custom elements, but I'd have to research such tools more to know whether it'd be good to provide custom build scenarios for them.

@matt-gadd It may be possible to map globalize formatter options back to native Intl options, but I'm still determining whether that could be done across the board. For example, Globalize allows format strings like GyMMMEd that would have to be parsed to Intl options. It's possible that we could completely avoid breaking changes, but that remains to be seen.

As for pre-compiling messages, we need to be able to determine which files contain those messages. For various reasons, we went with ES modules when other libraries use JSON or some other non-ES file type for locale messages. As such, it's difficult to differentiate from message files and other files, in turn making it difficult to pre-compile messages at build time.

@agubler Within the framework itself, only @dojo/widget-core/mixins/I18n uses anything from i18n, and that's only for message formatting. The i18n date/number/unit formatters pose a greater challenge if their functionality cannot be mapped cleanly to their ECMA-402 counterparts. If not, we would either need to 1) continue using Globalize but log deprecation warnings until some future version when they would be removed or 2) drop them completely, or 3) drop support for options that don't work with ECMA-402 functionality. The build would no longer need to load CLDR data, so the corresponding functionality would need to be dropped.

matt-gadd commented 5 years ago

@mwistrand as I said I’d like to see what bundle size reductions we’d actually gain by pre-compiling in the first place. If it’s not absolutely significant i wouldn’t want to make a sweeping breaking change on the message bundle file format or spend the time on potentially complicated build tooling. That’s one of the reasons using modules is actually really nice currently (+ bonus points that we can lazily load bundles down to a per language per bundle level). I don’t think even if we were using json it would be any less ambiguous either (same issue, no?).

matt-gadd commented 5 years ago

On the legacy globalize api’s, if we can’t manage to transform them at runtime it’s even more unlikely we’ll be able to transform them statically via cli-upgrade-app, which may be fine but would likely mean a manual migration guide.

mwistrand commented 5 years ago

It seems the unit formatting cannot map to existing functionality, so that would need to be manually updated. I mistakenly thought unit formatting was provided by one of the more advanced ECMA-402 proposals, but misremembered that. If we really wanted to avoid breaking changes (which I understand), we could keep globalize for the time being, log deprecation warnings to either use Intl or install globalize at the package-level, and then remove the deprecated globalize support in a future version.

I've mentioned this elsewhere in the past, but it should be possible to continue treating globalize as a first-class citizen by providing build-time support as there are existing plugins that pre-compile Globalize formatters, which would be possible to use if applications called those methods directly instead of through Dojo.