Skip to content

Commit b6fd814

Browse files
alan-agius4dylhunn
authored andcommitted
fix(localize): update ng add schematic to support Angular CLI version 15 (#47763)
Prior to this, the `@angular/localize/init` was added as a polyfill which caused the `@angular/localize` types not to be included in the TypeScript program which caused errors such as the below: ``` Error: src/app/app.component.ts:9:11 - error TS2304: Cannot find name '$localize'. ``` With the recent changes in the CLI (angular/angular-cli#24032), adding `@angular/localize/init` as polyfil or in the `main.server.ts` is no longer necessary. Instead we add this as a TypeScript type. When users are running in JIT mode, we add `@angular/localize/init` as an additional entrypoint. This change also exposes the `$localize` method as a global when importing `@angular/localize`. Closes #47677 PR Close #47763
1 parent 4c95484 commit b6fd814

File tree

9 files changed

+274
-334
lines changed

9 files changed

+274
-334
lines changed

goldens/public-api/localize/init/index.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@
44
55
```ts
66

7-
import { ɵ$localize as $localize_2 } from '@angular/localize';
7+
import { ɵ$localize as $localize } from '@angular/localize';
88
import { ɵLocalizeFn as LocalizeFn } from '@angular/localize';
99
import { ɵTranslateFn as TranslateFn } from '@angular/localize';
1010

11-
export { $localize_2 as $localize }
11+
export { $localize }
1212

1313
export { LocalizeFn }
1414

integration/ng-add-localize/src/app/app.component.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,10 @@ import { Component } from '@angular/core';
2323
<h2><a target="_blank" rel="noopener" href="https://blog.angular.io/">Angular blog</a></h2>
2424
</li>
2525
</ul>
26-
26+
2727
`,
2828
styles: []
2929
})
3030
export class AppComponent {
31-
title = 'ng-add-localize';
31+
title = $localize`ng-add-localize`;
3232
}

packages/localize/BUILD.bazel

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
load("//tools:defaults.bzl", "api_golden_test_npm_package", "ng_package", "ts_library")
1+
load("//tools:defaults.bzl", "api_golden_test_npm_package", "extract_types", "ng_package", "ts_library")
22

33
package(default_visibility = ["//visibility:public"])
44

@@ -17,20 +17,26 @@ ts_library(
1717
],
1818
)
1919

20+
extract_types(
21+
name = "api_type_definitions",
22+
deps = [":localize"],
23+
)
24+
2025
ng_package(
2126
name = "npm_package",
2227
srcs = [
2328
"package.json",
29+
":api_type_definitions",
2430
],
2531
nested_packages = [
2632
"//packages/localize/schematics:npm_package",
2733
"//packages/localize/tools:npm_package",
2834
],
2935
skip_type_bundling = [
30-
# For the "init" entry-point we disable type bundling because API extractor
36+
# For the primary entry-point we disable type bundling because API extractor
3137
# does not properly handle module augumentation.
3238
# TODO: Remove once https://github.com/microsoft/rushstack/issues/2090 is solved.
33-
"init",
39+
"",
3440
],
3541
tags = [
3642
"release-with-framework",

packages/localize/init/index.ts

Lines changed: 0 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -11,100 +11,3 @@ export {$localize, LocalizeFn, TranslateFn};
1111

1212
// Attach $localize to the global context, as a side-effect of this module.
1313
_global.$localize = $localize;
14-
15-
// `declare global` allows us to escape the current module and place types on the global namespace
16-
declare global {
17-
/**
18-
* Tag a template literal string for localization.
19-
*
20-
* For example:
21-
*
22-
* ```ts
23-
* $localize `some string to localize`
24-
* ```
25-
*
26-
* **Providing meaning, description and id**
27-
*
28-
* You can optionally specify one or more of `meaning`, `description` and `id` for a localized
29-
* string by pre-pending it with a colon delimited block of the form:
30-
*
31-
* ```ts
32-
* $localize`:meaning|description@@id:source message text`;
33-
*
34-
* $localize`:meaning|:source message text`;
35-
* $localize`:description:source message text`;
36-
* $localize`:@@id:source message text`;
37-
* ```
38-
*
39-
* This format is the same as that used for `i18n` markers in Angular templates. See the
40-
* [Angular i18n guide](guide/i18n-common-prepare#mark-text-in-component-template).
41-
*
42-
* **Naming placeholders**
43-
*
44-
* If the template literal string contains expressions, then the expressions will be automatically
45-
* associated with placeholder names for you.
46-
*
47-
* For example:
48-
*
49-
* ```ts
50-
* $localize `Hi ${name}! There are ${items.length} items.`;
51-
* ```
52-
*
53-
* will generate a message-source of `Hi {$PH}! There are {$PH_1} items`.
54-
*
55-
* The recommended practice is to name the placeholder associated with each expression though.
56-
*
57-
* Do this by providing the placeholder name wrapped in `:` characters directly after the
58-
* expression. These placeholder names are stripped out of the rendered localized string.
59-
*
60-
* For example, to name the `items.length` expression placeholder `itemCount` you write:
61-
*
62-
* ```ts
63-
* $localize `There are ${items.length}:itemCount: items`;
64-
* ```
65-
*
66-
* **Escaping colon markers**
67-
*
68-
* If you need to use a `:` character directly at the start of a tagged string that has no
69-
* metadata block, or directly after a substitution expression that has no name you must escape
70-
* the `:` by preceding it with a backslash:
71-
*
72-
* For example:
73-
*
74-
* ```ts
75-
* // message has a metadata block so no need to escape colon
76-
* $localize `:some description::this message starts with a colon (:)`;
77-
* // no metadata block so the colon must be escaped
78-
* $localize `\:this message starts with a colon (:)`;
79-
* ```
80-
*
81-
* ```ts
82-
* // named substitution so no need to escape colon
83-
* $localize `${label}:label:: ${}`
84-
* // anonymous substitution so colon must be escaped
85-
* $localize `${label}\: ${}`
86-
* ```
87-
*
88-
* **Processing localized strings:**
89-
*
90-
* There are three scenarios:
91-
*
92-
* * **compile-time inlining**: the `$localize` tag is transformed at compile time by a
93-
* transpiler, removing the tag and replacing the template literal string with a translated
94-
* literal string from a collection of translations provided to the transpilation tool.
95-
*
96-
* * **run-time evaluation**: the `$localize` tag is a run-time function that replaces and
97-
* reorders the parts (static strings and expressions) of the template literal string with strings
98-
* from a collection of translations loaded at run-time.
99-
*
100-
* * **pass-through evaluation**: the `$localize` tag is a run-time function that simply evaluates
101-
* the original template literal string without applying any translations to the parts. This
102-
* version is used during development or where there is no need to translate the localized
103-
* template literals.
104-
*
105-
* @param messageParts a collection of the static parts of the template string.
106-
* @param expressions a collection of the values of each placeholder in the template string.
107-
* @returns the translated string, with the `messageParts` and `expressions` interleaved together.
108-
*/
109-
const $localize: LocalizeFn;
110-
}

packages/localize/localize.ts

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,107 @@
77
*/
88

99
// This file contains the public API of the `@angular/localize` entry-point
10+
import {LocalizeFn} from './src/localize';
1011

1112
export {clearTranslations, loadTranslations} from './src/translate';
1213
export {MessageId, TargetMessage} from './src/utils';
1314

1415
// Exports that are not part of the public API
1516
export * from './private';
17+
18+
// `declare global` allows us to escape the current module and place types on the global namespace
19+
declare global {
20+
/**
21+
* Tag a template literal string for localization.
22+
*
23+
* For example:
24+
*
25+
* ```ts
26+
* $localize `some string to localize`
27+
* ```
28+
*
29+
* **Providing meaning, description and id**
30+
*
31+
* You can optionally specify one or more of `meaning`, `description` and `id` for a localized
32+
* string by pre-pending it with a colon delimited block of the form:
33+
*
34+
* ```ts
35+
* $localize`:meaning|description@@id:source message text`;
36+
*
37+
* $localize`:meaning|:source message text`;
38+
* $localize`:description:source message text`;
39+
* $localize`:@@id:source message text`;
40+
* ```
41+
*
42+
* This format is the same as that used for `i18n` markers in Angular templates. See the
43+
* [Angular i18n guide](guide/i18n-common-prepare#mark-text-in-component-template).
44+
*
45+
* **Naming placeholders**
46+
*
47+
* If the template literal string contains expressions, then the expressions will be automatically
48+
* associated with placeholder names for you.
49+
*
50+
* For example:
51+
*
52+
* ```ts
53+
* $localize `Hi ${name}! There are ${items.length} items.`;
54+
* ```
55+
*
56+
* will generate a message-source of `Hi {$PH}! There are {$PH_1} items`.
57+
*
58+
* The recommended practice is to name the placeholder associated with each expression though.
59+
*
60+
* Do this by providing the placeholder name wrapped in `:` characters directly after the
61+
* expression. These placeholder names are stripped out of the rendered localized string.
62+
*
63+
* For example, to name the `items.length` expression placeholder `itemCount` you write:
64+
*
65+
* ```ts
66+
* $localize `There are ${items.length}:itemCount: items`;
67+
* ```
68+
*
69+
* **Escaping colon markers**
70+
*
71+
* If you need to use a `:` character directly at the start of a tagged string that has no
72+
* metadata block, or directly after a substitution expression that has no name you must escape
73+
* the `:` by preceding it with a backslash:
74+
*
75+
* For example:
76+
*
77+
* ```ts
78+
* // message has a metadata block so no need to escape colon
79+
* $localize `:some description::this message starts with a colon (:)`;
80+
* // no metadata block so the colon must be escaped
81+
* $localize `\:this message starts with a colon (:)`;
82+
* ```
83+
*
84+
* ```ts
85+
* // named substitution so no need to escape colon
86+
* $localize `${label}:label:: ${}`
87+
* // anonymous substitution so colon must be escaped
88+
* $localize `${label}\: ${}`
89+
* ```
90+
*
91+
* **Processing localized strings:**
92+
*
93+
* There are three scenarios:
94+
*
95+
* * **compile-time inlining**: the `$localize` tag is transformed at compile time by a
96+
* transpiler, removing the tag and replacing the template literal string with a translated
97+
* literal string from a collection of translations provided to the transpilation tool.
98+
*
99+
* * **run-time evaluation**: the `$localize` tag is a run-time function that replaces and
100+
* reorders the parts (static strings and expressions) of the template literal string with strings
101+
* from a collection of translations loaded at run-time.
102+
*
103+
* * **pass-through evaluation**: the `$localize` tag is a run-time function that simply evaluates
104+
* the original template literal string without applying any translations to the parts. This
105+
* version is used during development or where there is no need to translate the localized
106+
* template literals.
107+
*
108+
* @param messageParts a collection of the static parts of the template string.
109+
* @param expressions a collection of the values of each placeholder in the template string.
110+
* @returns the translated string, with the `messageParts` and `expressions` interleaved together.
111+
*/
112+
const $localize: LocalizeFn;
113+
}

packages/localize/schematics/ng-add/BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ ts_library(
3737
deps = [
3838
":ng-add",
3939
"@npm//@angular-devkit/schematics",
40+
"@npm//typescript",
4041
],
4142
)
4243

packages/localize/schematics/ng-add/README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22

33
This schematic will be executed when an Angular CLI user runs `ng add @angular/localize`.
44

5-
It will search their `angular.json` file, and find polyfills and main files for server builders.
6-
Then it will add the `@angular/localize/init` polyfill that `@angular/localize` needs to work.
5+
It will search their `angular.json` file, and add `types: ["@angular/localize"]` in the TypeScript
6+
configuration files of the project.
77

88
If the user specifies that they want to use `$localize` at runtime then the dependency will be
99
added to the `depdendencies` section of `package.json` rather than in the `devDependencies` which
10-
is the default.
10+
is the default.

0 commit comments

Comments
 (0)