fix(common): locales/global/*.js are not ES5 compliant (#36342)

Although this code has been part of Angular 9.x I only noticed this
error when upgrading to Angular 9.1.x because historically the source
locale data was not injected when localizing, but as of
angular/angular-cli#16394 (9.1.0) it is now included. This tipped me off
that my other bundles were not being built properly, and this change
allows me to build a valid ES5 bundle (I have also added a verification
step to my build pipeline to alert me if this error appears again in any
of my bundles).

I found the `locales/global/*.js` file paths being referenced by the
`I18nOptions` in
@angular-devkit/build-angular/src/utils/i18n-options.ts,
and following that it looks like it is actually loaded and used in
@angular-devkit/build-angular/src/utils/process-bundle.ts. I saw the
function `terserMangle` does appear that it is likely aware of the build
being ES5, but I'm not sure why this is not producing a valid ES5
bundle.

This change updates `tools/gulp-tasks/cldr/extract.js` to produce ES5
compliant `locales/global/*.js` and that fixes my issue. However, I am
not sure if @angular-devkit/build-angular should be modified to produce
a valid ES5 bundle instead or if the files could be TypeScript rather
than JavaScript files.

A test that a valid ES5 bundle is produced would be helpful, and I hope
this is reproducible and not some issue with my config.

PR Close #36342
This commit is contained in:
Terence D. Honles
2020-03-30 16:02:19 -07:00
committed by atscott
parent 78136cc3a7
commit c8f3fa9f3e
543 changed files with 815 additions and 812 deletions

View File

@ -138,7 +138,7 @@ function generateGlobalLocale(locale, localeData, baseCurrencies) {
global.ng = global.ng || {};
global.ng.common = global.ng.common || {};
global.ng.common.locales = global.ng.common.locales || {};
const u = undefined;
var u = undefined;
${getPluralFunction(locale, false)}
global.ng.common.locales['${normalizeLocale(locale)}'] = ${data};
})(typeof globalThis !== 'undefined' && globalThis || typeof global !== 'undefined' && global || typeof window !== 'undefined' && window);
@ -559,19 +559,22 @@ function toRegExp(s) {
* todo(ocombe): replace "cldr" extractPluralRuleFunction with our own extraction using "CldrJS"
* because the 2 libs can become out of sync if they use different versions of the cldr database
*/
function getPluralFunction(locale, withTypes = true) {
function getPluralFunction(locale, typescript = true) {
let fn = cldr.extractPluralRuleFunction(locale).toString();
if (fn === EMPTY_RULE) {
fn = DEFAULT_RULE;
}
const numberType = withTypes ? ': number' : '';
const numberType = typescript ? ': number' : '';
fn = fn.replace(/function anonymous\(n[^}]+{/g, `function plural(n${numberType})${numberType} {`)
.replace(toRegExp('var'), 'let')
.replace(toRegExp('if(typeof n==="string")n=parseInt(n,10);'), '')
.replace(toRegExp('\n}'), ';\n}');
if (typescript) {
fn = fn.replace(toRegExp('var'), 'let');
}
// The replacement values must match the `Plural` enum from common.
// We do not use the enum directly to avoid depending on that package.
return fn.replace(toRegExp('"zero"'), ' 0')