Skip to content

Commit f5ec8c0

Browse files
clydinKeen Yee Liau
authored and
Keen Yee Liau
committed
fix(@angular-devkit/build-angular): ensure source locale data is injected when localizing
Fixes #16389
1 parent 84aeb9a commit f5ec8c0

File tree

2 files changed

+79
-27
lines changed

2 files changed

+79
-27
lines changed

packages/angular_devkit/build_angular/src/utils/i18n-options.ts

Lines changed: 33 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -202,40 +202,46 @@ export async function configureI18nBuild<T extends BrowserBuilderSchema | Server
202202
const loader = await createTranslationLoader();
203203
const usedFormats = new Set<string>();
204204
for (const [locale, desc] of Object.entries(i18n.locales)) {
205-
if (i18n.inlineLocales.has(locale) && desc.file) {
206-
const result = loader(path.join(context.workspaceRoot, desc.file));
207-
208-
for (const diagnostics of result.diagnostics.messages) {
209-
if (diagnostics.type === 'error') {
210-
throw new Error(
211-
`Error parsing translation file '${desc.file}': ${diagnostics.message}`,
212-
);
213-
} else {
214-
context.logger.warn(`WARNING [${desc.file}]: ${diagnostics.message}`);
215-
}
216-
}
205+
if (!i18n.inlineLocales.has(locale)) {
206+
continue;
207+
}
217208

218-
usedFormats.add(result.format);
219-
if (usedFormats.size > 1 && tsConfig.options.enableI18nLegacyMessageIdFormat !== false) {
220-
// This limitation is only for legacy message id support (defaults to true as of 9.0)
221-
throw new Error(
222-
'Localization currently only supports using one type of translation file format for the entire application.',
223-
);
224-
}
209+
const localeDataPath = findLocaleDataPath(locale, localeDataBasePath);
210+
if (!localeDataPath) {
211+
context.logger.warn(
212+
`Locale data for '${locale}' cannot be found. No locale data will be included for this locale.`,
213+
);
214+
} else {
215+
desc.dataPath = localeDataPath;
216+
}
225217

226-
desc.format = result.format;
227-
desc.translation = result.translation;
228-
desc.integrity = result.integrity;
218+
if (!desc.file) {
219+
continue;
220+
}
221+
222+
const result = loader(path.join(context.workspaceRoot, desc.file));
229223

230-
const localeDataPath = findLocaleDataPath(locale, localeDataBasePath);
231-
if (!localeDataPath) {
232-
context.logger.warn(
233-
`Locale data for '${locale}' cannot be found. No locale data will be included for this locale.`,
224+
for (const diagnostics of result.diagnostics.messages) {
225+
if (diagnostics.type === 'error') {
226+
throw new Error(
227+
`Error parsing translation file '${desc.file}': ${diagnostics.message}`,
234228
);
235229
} else {
236-
desc.dataPath = localeDataPath;
230+
context.logger.warn(`WARNING [${desc.file}]: ${diagnostics.message}`);
237231
}
238232
}
233+
234+
usedFormats.add(result.format);
235+
if (usedFormats.size > 1 && tsConfig.options.enableI18nLegacyMessageIdFormat !== false) {
236+
// This limitation is only for legacy message id support (defaults to true as of 9.0)
237+
throw new Error(
238+
'Localization currently only supports using one type of translation file format for the entire application.',
239+
);
240+
}
241+
242+
desc.format = result.format;
243+
desc.translation = result.translation;
244+
desc.integrity = result.integrity;
239245
}
240246

241247
// Legacy message id's require the format of the translations
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/**
2+
* @license
3+
* Copyright Google Inc. All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
import { expectFileToMatch } from '../../utils/fs';
9+
import { ng } from '../../utils/process';
10+
import { updateJsonFile } from '../../utils/project';
11+
import { externalServer, langTranslations, setupI18nConfig } from './legacy';
12+
13+
export default async function() {
14+
// Setup i18n tests and config.
15+
await setupI18nConfig(true);
16+
17+
// Update angular.json
18+
await updateJsonFile('angular.json', workspaceJson => {
19+
const appProject = workspaceJson.projects['test-project'];
20+
// tslint:disable-next-line: no-any
21+
const i18n: Record<string, any> = appProject.i18n;
22+
23+
i18n.sourceLocale = 'fr';
24+
25+
delete i18n.locales['fr'];
26+
});
27+
28+
// Build each locale and verify the output.
29+
await ng('build');
30+
for (const { lang, outputPath } of langTranslations) {
31+
// does not exist in this test due to the source locale change
32+
if (lang === 'en-US') {
33+
continue;
34+
}
35+
36+
await expectFileToMatch(`${outputPath}/vendor-es5.js`, lang);
37+
await expectFileToMatch(`${outputPath}/vendor-es2015.js`, lang);
38+
39+
// Verify the locale data is registered using the global files
40+
await expectFileToMatch(`${outputPath}/vendor-es5.js`, '.ng.common.locales');
41+
await expectFileToMatch(`${outputPath}/vendor-es2015.js`, '.ng.common.locales');
42+
43+
// Verify the HTML lang attribute is present
44+
await expectFileToMatch(`${outputPath}/index.html`, `lang="${lang}"`);
45+
}
46+
}

0 commit comments

Comments
 (0)