Skip to content

Commit

Permalink
feat(@angular/cli): add AOT parameter missingTranslation
Browse files Browse the repository at this point in the history
This adds the new parameter `missingTranslation` for AoT that was added in angular/angular/pull/15987 and that lets you define the MissingTranslationStrategy
  • Loading branch information
ocombe authored and hansl committed Aug 18, 2017
1 parent 47e9c7b commit e746369
Show file tree
Hide file tree
Showing 10 changed files with 98 additions and 11 deletions.
13 changes: 13 additions & 0 deletions docs/documentation/build.md
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,19 @@ Note: service worker support is experimental and subject to change.
</p>
</details>

<details>
<summary>missing-translation</summary>
<p>
<code>--missing-translation</code>
</p>
<p>
How to handle missing translations for i18n.
</p>
<p>
Values: <code>error</code>, <code>warning</code>, <code>ignore</code>
</p>
</details>

<details>
<summary>output-hashing</summary>
<p>
Expand Down
13 changes: 13 additions & 0 deletions docs/documentation/eject.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,19 @@ ng eject
</p>
</details>

<details>
<summary>missing-translation</summary>
<p>
<code>--missing-translation</code>
</p>
<p>
How to handle missing translations for i18n.
</p>
<p>
Values: <code>error</code>, <code>warning</code>, <code>ignore</code>
</p>
</details>

<details>
<summary>output-hashing</summary>
<p>
Expand Down
13 changes: 13 additions & 0 deletions docs/documentation/serve.md
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,19 @@ All the build Options are available in serve, below are the additional options.
</p>
</details>

<details>
<summary>missing-translation</summary>
<p>
<code>--missing-translation</code>
</p>
<p>
How to handle missing translations for i18n.
</p>
<p>
Values: <code>error</code>, <code>warning</code>, <code>ignore</code>
</p>
</details>

<details>
<summary>output-hashing</summary>
<p>
Expand Down
11 changes: 6 additions & 5 deletions docs/documentation/stories/internationalization.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,15 @@ ng xi18n --output-path src/locale
Now that you have generated a messages bundle source file, you can translate it.
Let's say that your file containing the french translations is named `messages.fr.xlf`
and is located in the `src/locale` folder.
If you want to use it when you serve your application you can use the 3 following commands:
If you want to use it when you serve your application you can use the 4 following commands:
- `--i18n-file` Localization file to use for i18n.
- `--i18n-format` Format of the localization file specified with --i18n-file.
- `--locale` Locale to use for i18n.
- `--missing-translation` Defines the strategy to use for missing i18n translations.

In our case we can load the french translations with the following command:
```sh
ng serve --aot --locale fr --i18n-format xlf --i18n-file src/locale/messages.fr.xlf
ng serve --aot --locale fr --i18n-format xlf --i18n-file src/locale/messages.fr.xlf --missing-translation error
```

Our application is exactly the same but the `LOCALE_ID` has been provided with "fr",
Expand All @@ -46,14 +47,14 @@ your bootstrap file yourself.
To build your application with a specific locale you can use the exact same commands
that you used for `serve`:
```sh
ng build --aot --locale fr --i18n-format xlf --i18n-file src/i18n/messages.fr.xlf
ng build --aot --locale fr --i18n-format xlf --i18n-file src/i18n/messages.fr.xlf --missing-translation error
```

When you build your application for a specific locale, it is probably a good idea to change
the output path with the command `--output-path` in order to save the files to a different location.

```sh
ng build --aot --output-path dist/fr --locale fr --i18n-format xlf --i18n-file src/i18n/messages.fr.xlf
ng build --aot --output-path dist/fr --locale fr --i18n-format xlf --i18n-file src/i18n/messages.fr.xlf --missing-translation error
```

If you end up serving this specific version from a subdirectory, you can also change
Expand All @@ -63,7 +64,7 @@ For example if the french version of your application is served from https://mya
then you would build the french version like this:

```sh
ng build --aot --output-path dist/fr --base-href fr --locale fr --i18n-format xlf --i18n-file src/i18n/messages.fr.xlf
ng build --aot --output-path dist/fr --base-href fr --locale fr --i18n-format xlf --i18n-file src/i18n/messages.fr.xlf --missing-translation error
```

If you need more details about how to create scripts to generate the app in multiple
Expand Down
5 changes: 5 additions & 0 deletions packages/@angular/cli/commands/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,11 @@ export const baseBuildCommandOptions: any = [
type: String,
description: 'Locale to use for i18n.'
},
{
name: 'missing-translation',
type: String,
description: 'How to handle missing translations for i18n.'
},
{
name: 'extract-css',
type: Boolean,
Expand Down
1 change: 1 addition & 0 deletions packages/@angular/cli/models/build-options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export interface BuildOptions {
i18nFile?: string;
i18nFormat?: string;
locale?: string;
missingTranslation?: string;
extractCss?: boolean;
watch?: boolean;
outputHashing?: string;
Expand Down
1 change: 1 addition & 0 deletions packages/@angular/cli/models/webpack-configs/typescript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ function _createAotPlugin(wco: WebpackConfigOptions, options: any) {
i18nFormat: buildOptions.i18nFormat,
locale: buildOptions.locale,
replaceExport: appConfig.platform === 'server',
missingTranslation: buildOptions.missingTranslation,
hostReplacementPaths,
// If we don't explicitely list excludes, it will default to `['**/*.spec.ts']`.
exclude: []
Expand Down
15 changes: 14 additions & 1 deletion packages/@ngtools/webpack/src/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import * as path from 'path';
import * as ts from 'typescript';
import * as SourceMap from 'source-map';

const {__NGTOOLS_PRIVATE_API_2} = require('@angular/compiler-cli');
const {__NGTOOLS_PRIVATE_API_2, VERSION} = require('@angular/compiler-cli');
const ContextElementDependency = require('webpack/lib/dependencies/ContextElementDependency');

import {WebpackResourceLoader} from './resource_loader';
Expand All @@ -31,6 +31,7 @@ export interface AotPluginOptions {
i18nFile?: string;
i18nFormat?: string;
locale?: string;
missingTranslation?: string;

// Use tsconfig to include path globs.
exclude?: string | string[];
Expand Down Expand Up @@ -68,6 +69,7 @@ export class AotPlugin implements Tapable {
private _i18nFile: string;
private _i18nFormat: string;
private _locale: string;
private _missingTranslation: string;

private _diagnoseFiles: { [path: string]: boolean } = {};
private _firstRun = true;
Expand Down Expand Up @@ -97,6 +99,7 @@ export class AotPlugin implements Tapable {
get i18nFile() { return this._i18nFile; }
get i18nFormat() { return this._i18nFormat; }
get locale() { return this._locale; }
get missingTranslation() { return this._missingTranslation; }
get firstRun() { return this._firstRun; }
get lazyRoutes() { return this._lazyRoutes; }
get discoveredLazyRoutes() { return this._discoveredLazyRoutes; }
Expand Down Expand Up @@ -246,6 +249,15 @@ export class AotPlugin implements Tapable {
if (options.hasOwnProperty('replaceExport')) {
this._replaceExport = options.replaceExport || this._replaceExport;
}
if (options.hasOwnProperty('missingTranslation')) {
const [MAJOR, MINOR, PATCH] = VERSION.full.split('.').map((x: string) => parseInt(x, 10));
if (MAJOR < 4 || (MINOR == 2 && PATCH < 2)) {
console.warn((`The --missing-translation parameter will be ignored because it is only `
+ `compatible with Angular version 4.2.0 or higher. If you want to use it, please `
+ `upgrade your Angular version.\n`));
}
this._missingTranslation = options.missingTranslation;
}
}

private _findLazyRoutesInAst(): LazyRouteMap {
Expand Down Expand Up @@ -483,6 +495,7 @@ export class AotPlugin implements Tapable {
i18nFile: this.i18nFile,
i18nFormat: this.i18nFormat,
locale: this.locale,
missingTranslation: this.missingTranslation,

readResource: (path: string) => this._resourceLoader.get(path)
});
Expand Down
35 changes: 31 additions & 4 deletions tests/e2e/tests/build/aot/aot-i18n.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import {ng} from '../../../utils/process';
import {expectFileToMatch, writeFile, createDir, appendToFile} from '../../../utils/fs';
import {expectFileToMatch, writeFile, createDir, appendToFile, readFile} from '../../../utils/fs';
import {expectToFail} from '../../../utils/utils';
import {Version} from '../../../../../packages/@angular/cli/upgrade/version';
import {SemVer} from 'semver';

export default function() {
return Promise.resolve()
Expand All @@ -22,10 +24,35 @@ export default function() {
'<h1 i18n="An introduction header for this sample">Hello i18n!</h1>'))
.then(() => ng('build', '--aot', '--i18n-file', 'src/locale/messages.fr.xlf', '--i18n-format',
'xlf', '--locale', 'fr'))
.then(() => ng('build', '--aot', '--i18nFile', 'src/locale/messages.fr.xlf', '--i18nFormat',
'xlf', '--locale', 'fr'))
.then(() => expectFileToMatch('dist/main.bundle.js', /Bonjour i18n!/))
.then(() => ng('build', '--aot'))
.then(() => expectToFail(() => expectFileToMatch('dist/main.bundle.js', /Bonjour i18n!/)))
.then(() => expectFileToMatch('dist/main.bundle.js', /Hello i18n!/));
.then(() => expectFileToMatch('dist/main.bundle.js', /Hello i18n!/))
.then(() => appendToFile('src/app/app.component.html',
'<p i18n>Other content</p>'))
.then(() => readFile('node_modules/@angular/compiler-cli/package.json')
.then((compilerCliPackage): any => {
const version = new Version(JSON.parse(compilerCliPackage).version);
if (version.major === 2) {
return expectToFail(() => ng('build', '--aot', '--i18nFile', 'src/locale/messages.fr.xlf',
'--i18nFormat', 'xlf', '--locale', 'fr', '--missingTranslation', 'ignore'));
} else {
return ng('build', '--aot', '--i18nFile', 'src/locale/messages.fr.xlf', '--i18nFormat',
'xlf', '--locale', 'fr', '--missingTranslation', 'ignore')
.then(() => expectFileToMatch('dist/main.bundle.js', /Other content/));
}
})
)
.then(() => readFile('node_modules/@angular/compiler-cli/package.json')
.then((compilerCliPackage): any => {
const version = new Version(JSON.parse(compilerCliPackage).version);
if (version.isGreaterThanOrEqualTo(new SemVer('4.2.0-beta.0')) || version.major === 2) {
return expectToFail(() => ng('build', '--aot', '--i18nFile', 'src/locale/messages.fr.xlf',
'--i18nFormat', 'xlf', '--locale', 'fr', '--missingTranslation', 'error'));
} else {
return ng('build', '--aot', '--i18nFile', 'src/locale/messages.fr.xlf',
'--i18nFormat', 'xlf', '--locale', 'fr', '--missingTranslation', 'error');
}
})
);
}
2 changes: 1 addition & 1 deletion tests/e2e/tests/i18n/extract-locale.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export default function() {
.then((output) => {
if (!output.stdout.match(/starting from Angular v4/)) {
expectFileToExist(join('src', 'messages.xlf'));
expectFileToMatch(join('src', 'messages.xlf'), /source-language="fr"/)
expectFileToMatch(join('src', 'messages.xlf'), /source-language="fr"/);
}
});
}

0 comments on commit e746369

Please sign in to comment.