Skip to content

Commit 406d792

Browse files
clydinmgechev
authored andcommitted
fix(@angular-devkit/build-angular): ensure HTML lang attribute is set when localizing
1 parent 5ec4a54 commit 406d792

File tree

8 files changed

+41
-19
lines changed

8 files changed

+41
-19
lines changed

packages/angular_devkit/build_angular/src/browser/index.ts

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ export function buildWebpackBrowser(
230230
const host = new NodeJsSyncHost();
231231
const root = normalize(context.workspaceRoot);
232232
const baseOutputPath = path.resolve(context.workspaceRoot, options.outputPath);
233-
let outputPaths: undefined | string[];
233+
let outputPaths: undefined | Map<string, string>;
234234

235235
// Check Angular version.
236236
assertCompatibleAngularVersion(context.workspaceRoot, context.logger);
@@ -304,7 +304,7 @@ export function buildWebpackBrowser(
304304
emittedFiles,
305305
i18n,
306306
baseOutputPath,
307-
outputPaths,
307+
Array.from(outputPaths.values()),
308308
scriptsEntryPointName,
309309
// tslint:disable-next-line: no-non-null-assertion
310310
webpackStats.outputPath!,
@@ -529,7 +529,7 @@ export function buildWebpackBrowser(
529529
),
530530
},
531531
],
532-
outputPaths,
532+
Array.from(outputPaths.values()),
533533
'',
534534
);
535535
} catch (err) {
@@ -561,7 +561,7 @@ export function buildWebpackBrowser(
561561
normalize(projectRoot),
562562
projectSourceRoot === undefined ? undefined : normalize(projectSourceRoot),
563563
),
564-
outputPaths,
564+
Array.from(outputPaths.values()),
565565
context.workspaceRoot,
566566
);
567567
} catch (err) {
@@ -646,7 +646,7 @@ export function buildWebpackBrowser(
646646
emittedFiles,
647647
i18n,
648648
baseOutputPath,
649-
outputPaths,
649+
Array.from(outputPaths.values()),
650650
scriptsEntryPointName,
651651
// tslint:disable-next-line: no-non-null-assertion
652652
webpackStats.outputPath!,
@@ -660,7 +660,7 @@ export function buildWebpackBrowser(
660660
}
661661

662662
if (options.index) {
663-
for (const outputPath of outputPaths) {
663+
for (const [locale, outputPath] of outputPaths.entries()) {
664664
try {
665665
await generateIndex(
666666
outputPath,
@@ -670,6 +670,8 @@ export function buildWebpackBrowser(
670670
noModuleFiles,
671671
moduleFiles,
672672
transforms.indexHtml,
673+
// i18nLocale is used when Ivy is disabled
674+
locale || options.i18nLocale,
673675
);
674676
} catch (err) {
675677
return { success: false, error: mapErrorToMessage(err) };
@@ -678,7 +680,7 @@ export function buildWebpackBrowser(
678680
}
679681

680682
if (!options.watch && options.serviceWorker) {
681-
for (const outputPath of outputPaths) {
683+
for (const outputPath of outputPaths.values()) {
682684
try {
683685
await augmentAppWithServiceWorker(
684686
host,
@@ -703,7 +705,7 @@ export function buildWebpackBrowser(
703705
...event,
704706
baseOutputPath,
705707
outputPath: baseOutputPath,
706-
outputPaths: outputPaths || [baseOutputPath],
708+
outputPaths: outputPaths && Array.from(outputPaths.values()) || [baseOutputPath],
707709
} as BrowserBuilderOutput),
708710
),
709711
);
@@ -719,6 +721,7 @@ function generateIndex(
719721
noModuleFiles: EmittedFiles[] | undefined,
720722
moduleFiles: EmittedFiles[] | undefined,
721723
transformer?: IndexHtmlTransform,
724+
locale?: string,
722725
): Promise<void> {
723726
const host = new NodeJsSyncHost();
724727

@@ -736,7 +739,7 @@ function generateIndex(
736739
styles: options.styles,
737740
postTransform: transformer,
738741
crossOrigin: options.crossOrigin,
739-
lang: options.i18nLocale,
742+
lang: locale,
740743
}).toPromise();
741744
}
742745

packages/angular_devkit/build_angular/src/server/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ export function execute(
5757
const tsConfig = readTsconfig(options.tsConfig, root);
5858
const target = tsConfig.options.target || ScriptTarget.ES5;
5959
const baseOutputPath = path.resolve(root, options.outputPath);
60-
let outputPaths: undefined | string[];
60+
let outputPaths: undefined | Map<string, string>;
6161

6262
return from(initialize(options, context, transforms.webpackConfiguration)).pipe(
6363
concatMap(({ config, i18n }) => {
@@ -81,7 +81,7 @@ export function execute(
8181
emittedFiles,
8282
i18n,
8383
baseOutputPath,
84-
outputPaths,
84+
Array.from(outputPaths.values()),
8585
[],
8686
// tslint:disable-next-line: no-non-null-assertion
8787
webpackStats.outputPath!,

packages/angular_devkit/build_angular/src/utils/output-paths.ts

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,21 @@ import { existsSync, mkdirSync } from 'fs';
99
import { join } from 'path';
1010
import { I18nOptions } from './i18n-options';
1111

12-
export function ensureOutputPaths(baseOutputPath: string, i18n: I18nOptions): string[] {
13-
const outputPaths =
14-
i18n.shouldInline && !i18n.flatOutput
15-
? [...i18n.inlineLocales].map(l => join(baseOutputPath, l))
16-
: [i18n.veCompatLocale ? join(baseOutputPath, i18n.veCompatLocale) : baseOutputPath];
12+
export function ensureOutputPaths(baseOutputPath: string, i18n: I18nOptions): Map<string, string> {
13+
const outputPaths: [string, string][] =
14+
i18n.shouldInline
15+
? [...i18n.inlineLocales].map(l => [l, i18n.flatOutput ? baseOutputPath : join(baseOutputPath, l)])
16+
: [
17+
i18n.veCompatLocale
18+
? [i18n.veCompatLocale, join(baseOutputPath, i18n.veCompatLocale)]
19+
: ['', baseOutputPath],
20+
];
1721

18-
for (const outputPath of outputPaths) {
22+
for (const [, outputPath] of outputPaths) {
1923
if (!existsSync(outputPath)) {
2024
mkdirSync(outputPath, { recursive: true });
2125
}
2226
}
2327

24-
return outputPaths;
28+
return new Map(outputPaths);
2529
}

tests/legacy-cli/e2e/tests/i18n/ivy-localize-dl-xliff2.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ export async function executeTest() {
3131
await expectFileToMatch(`${outputPath}/vendor-es5.js`, lang);
3232
await expectFileToMatch(`${outputPath}/vendor-es2015.js`, lang);
3333

34+
// Verify the HTML lang attribute is present
35+
await expectFileToMatch(`${outputPath}/index.html`, `lang="${lang}"`);
36+
3437
// Verify the locale data is registered using the global files
3538
await expectFileToMatch(`${outputPath}/vendor-es5.js`, '.ng.common.locales');
3639
await expectFileToMatch(`${outputPath}/vendor-es2015.js`, '.ng.common.locales');

tests/legacy-cli/e2e/tests/i18n/ivy-localize-es2015.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ export default async function() {
2222
await expectFileNotToExist(`${outputPath}/main-es5.js`);
2323
await expectFileToMatch(`${outputPath}/main.js`, lang);
2424

25+
// Verify the HTML lang attribute is present
26+
await expectFileToMatch(`${outputPath}/index.html`, `lang="${lang}"`);
27+
2528
// Execute Application E2E tests with dev server
2629
await ng('e2e', `--configuration=${lang}`, '--port=0');
2730

tests/legacy-cli/e2e/tests/i18n/ivy-localize-es5.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ export default async function() {
2222
await expectFileNotToExist(`${outputPath}/main-es2015.js`);
2323
await expectFileToMatch(`${outputPath}/main.js`, lang);
2424

25+
// Verify the HTML lang attribute is present
26+
await expectFileToMatch(`${outputPath}/index.html`, `lang="${lang}"`);
27+
2528
// Execute Application E2E tests with dev server
2629
await ng('e2e', `--configuration=${lang}`, '--port=0');
2730

tests/legacy-cli/e2e/tests/i18n/legacy.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ export async function setupI18nConfig(useLocalize = true, format: keyof typeof f
181181
for (const { lang, outputPath } of langTranslations) {
182182
if (!useLocalize) {
183183
if (lang == sourceLocale) {
184-
buildConfigs[lang] = { outputPath };
184+
buildConfigs[lang] = { outputPath, i18nLocale: lang };
185185
} else {
186186
buildConfigs[lang] = {
187187
outputPath,
@@ -262,6 +262,9 @@ export default async function () {
262262
await expectFileToMatch(`${outputPath}/main-es5.js`, translation.helloPartial);
263263
await expectFileToMatch(`${outputPath}/main-es2015.js`, translation.helloPartial);
264264

265+
// Verify the HTML lang attribute is present
266+
await expectFileToMatch(`${outputPath}/index.html`, `lang="${lang}"`);
267+
265268
// Execute Application E2E tests with dev server
266269
await ng('e2e', `--configuration=${lang}`, '--port=0');
267270

tests/legacy-cli/e2e/tests/i18n/ve-localize-es2015.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ export default async function() {
3737
await expectFileToMatch(`${outputPath}/main.js`, translation.helloPartial);
3838
await expectToFail(() => expectFileToMatch(`${outputPath}/main.js`, '$localize`'));
3939

40+
// Verify the HTML lang attribute is present
41+
await expectFileToMatch(`${outputPath}/index.html`, `lang="${lang}"`);
42+
4043
// Execute Application E2E tests with dev server
4144
await ng('e2e', `--configuration=${lang}`, '--port=0');
4245

0 commit comments

Comments
 (0)