diff --git a/packages/angular_devkit/build_angular/src/utils/process-bundle.ts b/packages/angular_devkit/build_angular/src/utils/process-bundle.ts index 3b26aa564541..2640ac083eff 100644 --- a/packages/angular_devkit/build_angular/src/utils/process-bundle.ts +++ b/packages/angular_devkit/build_angular/src/utils/process-bundle.ts @@ -634,7 +634,7 @@ export async function inlineLocales(options: InlineOptions) { // If locale data is provided, load it and prepend to file const localeDataPath = i18n.locales[locale]?.dataPath; if (localeDataPath) { - localeDataContent = await loadLocaleData(localeDataPath, true); + localeDataContent = await loadLocaleData(localeDataPath, true, options.es5); } } @@ -753,7 +753,7 @@ async function inlineLocalesDirect(ast: ParseResult, options: InlineOptions) { let localeDataSource: Source | null = null; const localeDataPath = i18n.locales[locale] && i18n.locales[locale].dataPath; if (localeDataPath) { - const localeDataContent = await loadLocaleData(localeDataPath, true); + const localeDataContent = await loadLocaleData(localeDataPath, true, options.es5); localeDataSource = new OriginalSource(localeDataContent, path.basename(localeDataPath)); } @@ -870,19 +870,36 @@ function findLocalizePositions( return positions; } -async function loadLocaleData(path: string, optimize: boolean): Promise { +async function loadLocaleData(path: string, optimize: boolean, es5: boolean): Promise { // The path is validated during option processing before the build starts const content = fs.readFileSync(path, 'utf8'); - // NOTE: This can be removed once the locale data files are preprocessed in the framework - if (optimize) { - const result = await terserMangle(content, { - compress: true, - ecma: 5, - }); + // Downlevel and optimize the data + const transformResult = await transformAsync(content, { + filename: path, + // The types do not include the false option even though it is valid + // tslint:disable-next-line: no-any + inputSourceMap: false as any, + babelrc: false, + configFile: false, + presets: [ + [ + require.resolve('@babel/preset-env'), + { + bugfixes: true, + // IE 9 is the oldest supported browser + targets: es5 ? { ie: '9' } : { esmodules: true }, + }, + ], + ], + minified: allowMinify && optimize, + compact: !shouldBeautify && optimize, + comments: !optimize, + }); - return result.code; + if (!transformResult || !transformResult.code) { + throw new Error(`Unknown error occurred processing bundle for "${path}".`); } - return content; + return transformResult.code; } diff --git a/tests/legacy-cli/e2e/tests/i18n/ivy-localize-dl-xliff2.ts b/tests/legacy-cli/e2e/tests/i18n/ivy-localize-dl-xliff2.ts index 28225d45a583..be3ab161c515 100644 --- a/tests/legacy-cli/e2e/tests/i18n/ivy-localize-dl-xliff2.ts +++ b/tests/legacy-cli/e2e/tests/i18n/ivy-localize-dl-xliff2.ts @@ -41,6 +41,18 @@ export async function executeTest() { await expectFileToMatch(`${outputPath}/vendor-es5.js`, '.ng.common.locales'); await expectFileToMatch(`${outputPath}/vendor-es2015.js`, '.ng.common.locales'); + // Verify the locale data is browser compatible + await expectToFail(() => expectFileToMatch(`${outputPath}/vendor-es5.js`, /\bconst\b/)); + await expectFileToMatch(`${outputPath}/vendor-es2015.js`, /\bconst\b/); + + // Verify locale data comments are removed in production + await expectToFail(() => + expectFileToMatch(`${outputPath}/vendor-es5.js`, '// See angular/tools/gulp-tasks/cldr/extract.js'), + ); + await expectToFail(() => + expectFileToMatch(`${outputPath}/vendor-es2015.js`, '// See angular/tools/gulp-tasks/cldr/extract.js'), + ); + // Execute Application E2E tests with dev server await ng('e2e', `--configuration=${lang}`, '--port=0');