fix(ivy): i18n - update the compiler to output MessageIds (#32594)

Now that the `$localize` translations are `MessageId` based the
compiler must render `MessageId`s in its generated `$localize` code.
This is because the `MessageId` used by the compiler is computed
from information that does not get passed through to the `$localize`
tagged string.

For example, the generated code for the following template

```html
<div id="static" i18n-title="m|d" title="introduction"></div>
```

will contain these localization statements

```ts
if (ngI18nClosureMode) {
  /**
    * @desc d
    * @meaning m
    */
  const MSG_EXTERNAL_8809028065680254561$$APP_SPEC_TS_1 = goog.getMsg("introduction");
  I18N_1 = MSG_EXTERNAL_8809028065680254561$$APP_SPEC_TS_1;
}
else {
  I18N_1 = $localize \`:m|d@@8809028065680254561:introduction\`;
}
```

Since `$localize` is not able to accurately regenerate the source-message
(and so the `MessageId`) from the generated code, it must rely upon the
`MessageId` being provided explicitly in the generated code.

The compiler now prepends all localized messages with a "metadata block"
containing the id (and the meaning and description if defined).

Note that this metadata block will also allow translation file extraction
from the compiled code - rather than relying on the legacy ViewEngine
extraction code. (This will be implemented post-v9).

Although these metadata blocks add to the initial code size, compile-time
inlining will completely remove these strings and so will not impact on
production bundle size.

PR Close #32594
This commit is contained in:
Pete Bacon Darwin
2019-09-13 12:46:05 +01:00
committed by Andrew Kushnir
parent 357aa4a097
commit b741a1c3e7
8 changed files with 1282 additions and 1365 deletions

File diff suppressed because it is too large Load Diff

View File

@ -19,11 +19,9 @@ import {ivyEnabled, onlyInIvy} from '@angular/private/testing';
describe('ViewContainerRef', () => {
const TRANSLATIONS: any = {
'Bar': 'o',
'{$START_TAG_BEFORE}{$CLOSE_TAG_BEFORE}{$START_TAG_DIV}{$START_TAG_INSIDE}{$CLOSE_TAG_INSIDE}{$CLOSE_TAG_DIV}{$START_TAG_AFTER}{$CLOSE_TAG_AFTER}':
'F{$START_TAG_DIV}{$CLOSE_TAG_DIV}o',
'{$START_TAG_BEFORE}{$CLOSE_TAG_BEFORE}{$START_TAG_DIV}{$START_TAG_IN}{$CLOSE_TAG_IN}{$CLOSE_TAG_DIV}{$START_TAG_AFTER}{$CLOSE_TAG_AFTER}':
'{$START_TAG_DIV}{$CLOSE_TAG_DIV}{$START_TAG_BEFORE}{$CLOSE_TAG_BEFORE}'
'6587679027921703718': 'o',
'1059980791999999199': 'F{$START_TAG_DIV}{$CLOSE_TAG_DIV}o',
'8808498902423973223': '{$START_TAG_DIV}{$CLOSE_TAG_DIV}{$START_TAG_BEFORE}{$CLOSE_TAG_BEFORE}'
};
/**

View File

@ -11,8 +11,8 @@ import '@angular/localize/init';
import {loadTranslations} from '@angular/localize';
const translations = {
'Hello World!': 'Bonjour Monde!',
'Hello Title!': 'Bonjour Titre!',
'6947830843539421219': 'Bonjour Monde!',
'6935800796474951272': 'Bonjour Titre!',
};
loadTranslations(translations);

View File

@ -11,19 +11,27 @@ import '@angular/localize/init';
import {loadTranslations} from '@angular/localize';
export const translations = {
'What needs to be done?': `Qu'y a-t-il à faire ?`,
'{$START_HEADING_LEVEL1}todos{$CLOSE_HEADING_LEVEL1}{$TAG_INPUT}':
// What needs to be done?
'5102526651904871634': `Qu'y a-t-il à faire ?`,
// {$START_HEADING_LEVEL1}todos{$CLOSE_HEADING_LEVEL1}{$TAG_INPUT}
'8643091609122689720':
'{$START_HEADING_LEVEL1}liste de tâches{$CLOSE_HEADING_LEVEL1}{$TAG_INPUT}',
'{VAR_PLURAL, plural, =1 {item left} other {items left}}':
'{VAR_PLURAL, plural, =1 {tâche restante} other {tâches restantes}}',
'{$START_TAG_STRONG}{$INTERPOLATION}{$CLOSE_TAG_STRONG}{$ICU}':
'{$START_TAG_STRONG}{$INTERPOLATION}{$CLOSE_TAG_STRONG} {$ICU}',
' Clear completed ': ' Effacer terminés ',
'Demonstrate Components': 'Démontrer les components',
'Demonstrate Structural Directives': 'Démontrer les directives structurelles',
'Demonstrate {$value}': 'Démontrer {$value}',
'Demonstrate zoneless change detection': 'Démontrer la détection des changements sans zonejs',
'Demonstrate internationalization': `Démontrer l'internationalisation`
// {VAR_PLURAL, plural, =1 {item left} other {items left}}
'271375439086996113': '{VAR_PLURAL, plural, =1 {tâche restante} other {tâches restantes}}',
// {$START_TAG_STRONG}{$INTERPOLATION}{$CLOSE_TAG_STRONG}{$ICU}
'4169337202119891309': '{$START_TAG_STRONG}{$INTERPOLATION}{$CLOSE_TAG_STRONG} {$ICU}',
// Clear Completed
'3329962774478249377': ' Effacer terminés ',
// Demonstrate Components
'5738403869589701812': ' Démontrer les components',
// Demonstrate Structural Directives
'4405796757024158842': 'Démontrer les directives structurelles',
// Demonstrate {$value}
'2762077329405284613': 'Démontrer {$value}',
// Demonstrate zoneless change detection
'3484387157632222646': 'Démontrer la détection des changements sans zonejs',
// Demonstrate internationalization
'442837859415373816': `Démontrer l'internationalisation`
};
loadTranslations(translations);