Skip to content

Commit

Permalink
fix(@angular-devkit/build-angular): allow new i18n options to work wi…
Browse files Browse the repository at this point in the history
…th VE

(cherry picked from commit 7987906)
  • Loading branch information
clydin authored and dgp1130 committed Nov 18, 2019
1 parent 6aee3b1 commit b8a2215
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 12 deletions.
45 changes: 42 additions & 3 deletions packages/angular_devkit/build_angular/src/utils/i18n-options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/
import { BuilderContext } from '@angular-devkit/architect';
import { json, virtualFs } from '@angular-devkit/core';
import { json } from '@angular-devkit/core';
import * as fs from 'fs';
import * as os from 'os';
import * as path from 'path';
Expand All @@ -25,6 +25,7 @@ export interface I18nOptions {
>;
flatOutput?: boolean;
readonly shouldInline: boolean;
veCompatLocale?: string;
}

export function createI18nOptions(
Expand Down Expand Up @@ -116,9 +117,32 @@ export async function configureI18nBuild<T extends BrowserBuilderSchema | Server
if (buildOptions.localize === undefined && usingIvy) {
mergeDeprecatedI18nOptions(i18n, buildOptions.i18nLocale, buildOptions.i18nFile);
} else if (buildOptions.localize !== undefined && !usingIvy) {
buildOptions.localize = undefined;
if (
buildOptions.localize === true ||
(Array.isArray(buildOptions.localize) && buildOptions.localize.length > 1)
) {
throw new Error(
`Localization with multiple locales in one build is not supported with View Engine.`,
);
}

for (const deprecatedOption of ['i18nLocale', 'i18nFormat', 'i18nFile']) {
// tslint:disable-next-line: no-any
if (typeof (buildOptions as any)[deprecatedOption] !== 'undefined') {
context.logger.warn(
`Option 'localize' and deprecated '${deprecatedOption}' found. Using 'localize'.`,
);
}
}

context.logger.warn(`Option 'localize' is not supported with View Engine.`);
if (
buildOptions.localize === false ||
(Array.isArray(buildOptions.localize) && buildOptions.localize.length === 0)
) {
buildOptions.i18nFile = undefined;
buildOptions.i18nLocale = undefined;
buildOptions.i18nFormat = undefined;
}
}

// Clear deprecated options when using Ivy to prevent unintended behavior
Expand Down Expand Up @@ -180,6 +204,21 @@ export async function configureI18nBuild<T extends BrowserBuilderSchema | Server
if (usedFormats.size > 0) {
buildOptions.i18nFormat = [...usedFormats][0];
}

// Provide support for using the Ivy i18n options with VE
if (!usingIvy) {
i18n.veCompatLocale = buildOptions.i18nLocale = [...i18n.inlineLocales][0];

if (buildOptions.i18nLocale !== i18n.sourceLocale) {
buildOptions.i18nFile = i18n.locales[buildOptions.i18nLocale].file;
}

// Clear inline locales to prevent any new i18n related processing
i18n.inlineLocales.clear();

// Update the output path to include the locale to mimic Ivy localize behavior
buildOptions.outputPath = path.join(buildOptions.outputPath, buildOptions.i18nLocale);
}
}

// If inlining store the output in a temporary location to facilitate post-processing
Expand Down
18 changes: 9 additions & 9 deletions packages/angular_devkit/build_angular/src/utils/output-paths.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,21 @@
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/

import { existsSync, mkdirSync } from 'fs';
import { join } from 'path';
import { I18nOptions } from './i18n-options';

export function ensureOutputPaths(baseOutputPath: string, i18n: I18nOptions): string[] {
const outputPaths = i18n.shouldInline && !i18n.flatOutput
? [...i18n.inlineLocales].map(l => join(baseOutputPath, l))
: [baseOutputPath];
const outputPaths =
i18n.shouldInline && !i18n.flatOutput
? [...i18n.inlineLocales].map(l => join(baseOutputPath, l))
: [i18n.veCompatLocale ? join(baseOutputPath, i18n.veCompatLocale) : baseOutputPath];

for (const outputPath of outputPaths) {
if (!existsSync(outputPath)) {
mkdirSync(outputPath, { recursive: true });
}
for (const outputPath of outputPaths) {
if (!existsSync(outputPath)) {
mkdirSync(outputPath, { recursive: true });
}
}

return outputPaths;
return outputPaths;
}
67 changes: 67 additions & 0 deletions tests/legacy-cli/e2e/tests/i18n/ve-localize-es2015.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { getGlobalVariable } from '../../utils/env';
import { expectFileToMatch, writeFile } from '../../utils/fs';
import { execAndWaitForOutputToMatch, ng, npm } from '../../utils/process';
import { updateJsonFile } from '../../utils/project';
import { expectToFail } from '../../utils/utils';
import { readNgVersion } from '../../utils/version';
import { baseDir, externalServer, langTranslations, setupI18nConfig } from './legacy';

export default async function() {
if (!getGlobalVariable('argv')['ve']) {
return;
}

// Setup i18n tests and config.
await setupI18nConfig();

// Using localize-based options requires the @angular/locale package
let localizeVersion = '@angular/localize@' + readNgVersion();
if (getGlobalVariable('argv')['ng-snapshots']) {
localizeVersion = require('../../ng-snapshot/package.json').dependencies['@angular/localize'];
}
await npm('install', `${localizeVersion}`);

// Ensure a ES2015 build is used.
await writeFile('browserslist', 'Chrome 65');
await updateJsonFile('tsconfig.json', config => {
config.compilerOptions.target = 'es2015';
config.angularCompilerOptions.disableTypeScriptVersionCheck = true;
});

// Attempts to build multiple locales with VE should fail
await expectToFail(() => ng('build'));

for (const { lang, outputPath, translation } of langTranslations) {
await ng('build', `--configuration=${lang}`);

await expectFileToMatch(`${outputPath}/main.js`, translation.helloPartial);
await expectToFail(() => expectFileToMatch(`${outputPath}/main.js`, '$localize`'));

// Execute Application E2E tests with dev server
await ng('e2e', `--configuration=${lang}`, '--port=0');

// Execute Application E2E tests for a production build without dev server
const server = externalServer(outputPath);
try {
await ng('e2e', `--configuration=${lang}`, '--devServerTarget=');
} finally {
server.close();
}
}

await execAndWaitForOutputToMatch(
'ng',
['build', '--configuration=fr', '--i18n-locale=en-US'],
/Option 'localize' and deprecated 'i18nLocale' found. Using 'localize'./,
);
await execAndWaitForOutputToMatch(
'ng',
['build', '--configuration=fr', '--i18n-format=xmb'],
/Option 'localize' and deprecated 'i18nFormat' found. Using 'localize'./,
);
await execAndWaitForOutputToMatch(
'ng',
['build', '--configuration=fr', '--i18n-file=error.json'],
/Option 'localize' and deprecated 'i18nFile' found. Using 'localize'./,
);
}

0 comments on commit b8a2215

Please sign in to comment.