From f2e1047fd8bc88082169577dfe168384013c51cc Mon Sep 17 00:00:00 2001 From: kotwys <52920928+kotwys@users.noreply.github.com> Date: Thu, 23 Jul 2020 12:47:18 +0400 Subject: [PATCH] Introduce locale searching Some locales may be absent or incorrect in default packages so these should be obtained from other places instead. --- packages/app/services/i18n/intlPolyfill.ts | 69 ++++++++++++++++------ 1 file changed, 50 insertions(+), 19 deletions(-) diff --git a/packages/app/services/i18n/intlPolyfill.ts b/packages/app/services/i18n/intlPolyfill.ts index 34ade7a..02f3da9 100644 --- a/packages/app/services/i18n/intlPolyfill.ts +++ b/packages/app/services/i18n/intlPolyfill.ts @@ -7,6 +7,53 @@ const needs = { relative: !window?.Intl?.RelativeTimeFormat, }; +type ImportFunction = (l: string, m: string) => Promise; + +// WARNING: .js extension is required for proper function of ContextReplacementPlugin +// Thoroughly described imports are needed for Webpack to properly create chunks. +const LOCALE_PATH = new Map([ + [ + '*:common', + (l) => + import( + /* webpackChunkName: intl-[request] */ + `intl/locale-data/jsonp/${l}.js` + ), + ], + [ + '*:*', + (l, m) => + m === 'pluralrules' + ? import( + /* webpackChunkName: intl-pluralrules-[request] */ + `@formatjs/intl-pluralrules/dist/locale-data/${l}.js` + ) + : import( + /* webpackChunkName: intl-relativetimeformat-[request] */ + `@formatjs/intl-relativetimeformat/dist/locale-data/${l}.js` + ), + ], +]); + +/** + * Finds and applies localizations for Intl polyfills. + * + * @param {string} locale - locale to find + * @param {string} module - module to find locale for + * @returns {Promise} promise resolved when module is loaded + */ +function findLocale(locale: string, module: string): Promise { + for (const [key, found] of LOCALE_PATH) { + const [lc, api] = key.split(':'); + + if ((lc === locale || lc === '*') && (api === module || api === '*')) { + return found(locale, module); + } + } + + return Promise.resolve(); +} + /** * All modern browsers currently do support all required Intl APIs, * for the outdated browsers we will polyfill this api on demand @@ -61,15 +108,7 @@ async function polyfillIntl(locale: string): Promise { window.Intl = Intl; // MUST be loaded in series with the main polyfill - await Promise.all([ - import( - // WARNING: .js extension is required for proper function of ContextReplacementPlugin - /* webpackChunkName: "intl-[request]" */ - `intl/locale-data/jsonp/${locale}.js` - ), - polyfillPlural(locale), - polyfillRelative(locale), - ]); + await Promise.all([findLocale(locale, 'common'), polyfillPlural(locale), polyfillRelative(locale)]); } async function polyfillPlural(locale: string): Promise { @@ -79,11 +118,7 @@ async function polyfillPlural(locale: string): Promise { ); // MUST be loaded in series with the main polyfill - await import( - // WARNING: .js extension is required for proper function of ContextReplacementPlugin - /* webpackChunkName: "intl-pluralrules-[request]" */ - `@formatjs/intl-pluralrules/dist/locale-data/${locale}.js` - ); + await findLocale(locale, 'pluralrules'); } async function polyfillRelative(locale: string): Promise { @@ -93,11 +128,7 @@ async function polyfillRelative(locale: string): Promise { ); // MUST be loaded in series with the main polyfill - await import( - // WARNING: .js extension is required for proper function of ContextReplacementPlugin - /* webpackChunkName: "intl-relativetimeformat-[request]" */ - `@formatjs/intl-relativetimeformat/dist/locale-data/${locale}.js` - ); + await findLocale(locale, 'relativetimeformat'); } export default polyfill;