Compare commits

...

177 Commits

Author SHA1 Message Date
Alex Rickabaugh d24cbcea70 release: cut the v13.0.0-rc.3 release (#44011)
PR Close #44011
2021-11-01 18:50:22 -07:00
Alex Rickabaugh 4fd388b084 docs: initial commit of Angular Package Format documentation (#43987)
This commit adds the Angular Package Format to AIO. Previously this document
was updated and versioned in Google Docs.

The document is also updated for the Angular Package Format version 13.

PR Close #43987
2021-11-01 18:24:21 -07:00
Joe Martin (Crowdstaffing) 74c497289f docs: update per feedback (#44009)
Update content per feedback from previous PR.

PR Close #44009
2021-11-01 17:38:54 -07:00
mgechev 892ded5865 docs: update the roadmap in alignment with v13 progress (#43986)
PR Close #43986
2021-11-01 14:02:14 -07:00
Andrew Scott 87bcb3f183 Revert "refactor(router): restore history in a consistent way on canceled navigations (#43651)" (#44006)
This reverts commit a268c4471f.

Causes failures in internal team's code. The failures likely relate to
attempting to manually update private Router state tracking properties,
which this change would have affected.

PR Close #44006
2021-11-01 09:25:36 -07:00
Joe Martin (Crowdstaffing) 0382f863db docs: update left-nav (#43964)
Update left-nav toc.

PR Close #43964
2021-10-29 16:51:34 -07:00
Joe Martin (Crowdstaffing) 0a51212d0e docs: add link (#43964)
Add link for RFC. Clean up markdown formatting.

PR Close #43964
2021-10-29 16:51:33 -07:00
Joe Martin (Crowdstaffing) dd79d317a4 docs: update per tech review (#43964)
Update content per feedback in tech review.

PR Close #43964
2021-10-29 16:51:33 -07:00
Joe Martin (Crowdstaffing) c9718897a6 docs: update release notes (#43964)
Update release note for version 13.

PR Close #43964
2021-10-29 16:51:33 -07:00
Joe Martin (Crowdstaffing) 618a9c76f7 docs: add redirect test (#43964)
Add redirect test for new latest version topic.

PR Close #43964
2021-10-29 16:51:33 -07:00
Joe Martin (Crowdstaffing) 4e57cab6d4 docs: add links (#43964)
docs: add links to additional information.

PR Close #43964
2021-10-29 16:51:33 -07:00
Joe Martin (Crowdstaffing) a23942ef53 docs: remove previous latest verison (#43964)
Remove content for previous latest version.

PR Close #43964
2021-10-29 16:51:33 -07:00
Joe Martin (Crowdstaffing) b671a37ba8 docs: update migration content (#43964)
Update content for AngularJS to Angular migration.  Add note to manually create UMD bundles.

PR Close #43964
2021-10-29 16:51:33 -07:00
Joe Martin (Crowdstaffing) a4dc5da4ee docs: update library use content (#43964)
Update content for library use.

PR Close #43964
2021-10-29 16:51:33 -07:00
Joe Martin (Crowdstaffing) 97eed3e83c docs: add latest version content (#43964)
Add the update to latest version content for version 13.  Add redirect for latest version content.  Update toc for later version content.

PR Close #43964
2021-10-29 16:51:33 -07:00
Alan Agius 9c99afdc7c fix(docs-infra): search box input line-height (#43983)
This fixes an issue on Safari which caused the text to be pushed down when blurring out of the search input field. The root cause of the problem appears to be that previously the computed line height was that of 32px, which caused a shift in content.

Closes #43935

PR Close #43983
2021-10-29 15:47:09 -07:00
Joe Martin (Crowdstaffing) 6b248556e8 docs: update note (#43979)
Update the note for hierarchy of locale identifiers.

PR Close #43979
2021-10-29 15:46:37 -07:00
Joe Martin (Crowdstaffing) aea63fcc17 docs: remove link (#43979)
Remove redundant link.

PR Close #43979
2021-10-29 15:46:37 -07:00
Andrew Kushnir f4ea80a3c1 refactor(core): add ViewRef to private exports (#43978)
This commit adds `ViewRef` to private exports, so it can be reused in internal packages.

The `ViewRef` symbol remains *private* and should not be referenced directly.

PR Close #43978
2021-10-29 15:45:50 -07:00
George Kalpakas 494d056c48 refactor(docs-infra): remove obsolete way of disabling DocViewer animations (#43977)
Previously, there were two ways to disable view transition animations in
`DocViewerComponent`: Using a `.no-animations` CSS class on the
`<aio-doc-viewer>` element and setting the static
`DocViewerComponent.animationsEnabled` property to `false`. The latter
was only used to disable animations for testing purposes.

With the recent introduction of `AppComponent.reducedMotion`, there is
now an easy way to disable animations in tests using the
`.no-animations` class (which is applied by `AppComponent` based on the
value of `AppComponent.reducedMotion`). Therefore, it is no longer
necessary to have `DocViewerComponent.animationEnabled`.

This commit removes the now obsolete `animationsEnalbed` property.

PR Close #43977
2021-10-29 15:45:02 -07:00
George Kalpakas 22c5f35a8c fix(docs-infra): improve accessibility by respecting prefers-reduced-motion (#43977)
Make the app easier to use for people with motion sensitivities by
disabling several animations (esp. ones involving moving things around)
when the user prefers reduced motion. The user's preference is detected
using the [prefers-reduced-motion][1] CSS media feature.

Disabled animations include:
- View fade in/out transitions.
- Sidenav open/close animations.
- Top-menu color and size changes.
- Contributor cards flip animations.

For more details on using `prefers-reduced-motion` and disabling
Angular animations see:
- [Designing with reduced motion for motion sensitivities][2]
- [Disabling Angular animations at runtime][3]

[1]: https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-reduced-motion
[2]: https://www.smashingmagazine.com/2020/09/design-reduced-motion-sensitivities/
[3]: https://dev.to/this-is-angular/disabling-angular-animations-at-runtime-9a6

PR Close #43977
2021-10-29 15:45:02 -07:00
Alan Agius 7307ea33bd test: remove ng_elements_schematics integration test (#43975)
This test has been removed as since the elements schematic has been removed in a previous commit.

PR Close #43975
2021-10-29 15:43:56 -07:00
Alan Agius f544a53f5f fix(elements): remove incorrect @angular/platform-browser peer dependency (#43975)
The elements package doesn't use `@angular/platform-browser` therefore this is not needed.

PR Close #43975
2021-10-29 15:43:56 -07:00
Alan Agius a468213f34 fix(elements): remove ng-add schematic (#43975)
This schematic is no longer needed since all the [browsers](https://angular.io/guide/browser-support) that Angular supports `CustomElementRegistry` APIs.

Side note: `document-register-element` has been deprecated in favor of `@ungap/custom-element`

PR Close #43975
2021-10-29 15:43:56 -07:00
Alan Agius 8f7ceae5df docs: update elements page (#43975)
This section was outdated since now all CLI projects are es2015+ and don't require the polyfill since legacy browsers are no longer supported.

PR Close #43975
2021-10-29 15:43:56 -07:00
Alan Agius fce7bb8daf test: remove document-register-element from elements tests (#43975)
All the [browsers](https://angular.io/guide/browser-support) that Angular supports `CustomElementRegistry` APIs

PR Close #43975
2021-10-29 15:43:56 -07:00
Andrew Kushnir c50abe57c8 docs: update dynamic component guide to use factory-less ViewContainerRef.createComponent (#43895)
PR Close #43895
2021-10-29 15:39:04 -07:00
George Kalpakas 3084df8b64 ci: improve angular.io deployment process for the master branch (#43963)
Previously, the master branch was only deployed to the
`next-angular-io-site` Firebase site, which is connected to the
`next.angular.io` domain. However, if the master major version was
higher than the stable major version (or the RC major version in case
there was an active RC), we also had to manually configure (via the
Firebase console and/or DNS records) the `v<X>.angular.io` domain to
redirect to `next.angular.io`. Then, once `<X>` became the new stable or
RC version, we had to manually remove the redirect (to let
`v<X>.angular.io` be redirected to `angular.io` or `rc.angular.io`).

This commit is part of a new process that reduces the manual steps as
follows (the steps below only apply when the master major version is
higher than the current stable and RC (if applicable)):
- A `v<X>-angular-io-site` Firebase site will be created as soon as the
  version in the `master` branch's `package.json` is updated to a new
  major.
- The `v<X>.angular.io` domain will be connected to that new Firebase
  site.
- When deploying from the master branch, we will deploy to both
  `next-angular-io-site` and `v<X>-angular-io-site`. In addition, the
  deployment to `v<X>-angular-io-site` will update the Firebase config
  file to redirect to `next.angular.io`.
- When the master version becomes the new stable/RC, we will start
  deploying to `v<X>-angular-io-site` from the stable/RC branch, which
  will update the Firebase config to stop redirecting to
  `next.angular.io` and redirect to `(rc.)angular.io` instead (without
  requiring changes in the Firebase console or DNS).

PR Close #43963
2021-10-29 15:05:11 -07:00
George Kalpakas 6662fcfa12 ci: improve angular.io deployment process for the RC branch (#43963)
Previously, (when there was an active RC) the RC branch was only
deployed to the `rc-angular-io-site` Firebase site, which is connected
to the `rc.angular.io` domain. However, if the RC major version was
higher than the stable major version, we also had to manually configure
(via the Firebase console and/or DNS records) the `v<X>.angular.io`
domain to redirect to `rc.angular.io`. Then, once `<X>` became the new
stable version, we had to manually remove the redirect (to let
`v<X>.angular.io` be redirected to `angular.io`).

This commit is part of a new process that reduces the manual steps as
follows (the steps below only apply to RC versions that have a higher
major version than the current stable):
- A `v<X>-angular-io-site` Firebase site will be created for the new RC
  version.
- The `v<X>.angular.io` domain will be connected to that new Firebase
  site.
- When deploying from the RC branch, we will deploy to both
  `rc-angular-io-site` and `v<X>-angular-io-site`. In addition, the
  deployment to `v<X>-angular-io-site` will update the Firebase config
  file to redirect to `rc.angular.io`.
- When the RC version becomes the new stable, we will start deploying to
  `v<X>-angular-io-site` from the stable branch, which will update the
  Firebase config to stop redirecting to `rc.angular.io` and redirect to
  `angular.io` instead (without requiring changes in the Firebase
  console or DNS).

PR Close #43963
2021-10-29 15:05:11 -07:00
George Kalpakas 40abf0307d ci: improve angular.io deployment process for the stable branch (#43963)
Previously, the stable branch was always deployed to the
`v<X>-angular-io-site` Firebase site, which was connected to the
`angular.io` domain. Whenever a new major version was released (and
became the new stable version), the `angular.io` domain had to be
disconnected from the previous Firebase site and be connected to the new
`v<Y>-angular-io-site` Firebase site. This was a manual process that
involved making changes in the Firebase console and the DNS records.

This commit is part of a new process that reduces the manual steps as
follows:
- A new `stable-angular-io-site` Firebase site is created.
- The `angular.io` domain will be connected to that new Firebase site.
- When deploying from the stable branch, we will deploy to both
  `stable-angular-io-site` and `v<X>-angular-io-site`. In addition, the
  deployment to `v<X>-angular-io-site` will update the Firebase config
  file to redirect to `angular.io`.
- When a new major version is released, we will start deploying from the
  new stable branch to `stable-angular-io-site`, but there will be no
  need to connect/disconnect the `angular.io` domain. Also,
  `v<X>.angular.io` will stop redirecting to `angular.io` by means of
  updating the Firebase config file (without requiring changes in the
  Firebase console or DNS).

PR Close #43963
2021-10-29 15:05:11 -07:00
George Kalpakas d1321a1fe7 feat(docs-infra): add post-deploy actions for testing more redirect configs (#43963)
Add `deploy-to-firebase` post-deploy actions to allow testing various
redirect configs.
In a future commit, this will allow testing redirects for the `stable`,
`rc` and `next` deployments via the Firebase config file (without
requiring changes in the Firebase console or DNS).

PR Close #43963
2021-10-29 15:05:11 -07:00
George Kalpakas f5d236b248 refactor(docs-infra): make it easier to configure Firebase redirects at deployment (#43963)
Refactor the `deploy-to-firebase` post-deploy actions by extracting
logic to separate helper functions. This makes it easier to create more
functions for testing various redirect configs (in a future commit).

PR Close #43963
2021-10-29 15:05:11 -07:00
George Kalpakas 78d0bda39e feat(docs-infra): add more granular support for configuring Firebase redirects at deployment (#43963)
Previously, there was a `deploy-to-firebase` pre-deploy action for
configuring Firebase to redirect non-file requests to `angular.io`. This
is used for ensuring that `rc.angular.io` is correctly redirected to
`angular.io`, even when people have previously visited (and have a
ServiceWorker activated on) `rc.angular.io`.

This commit adds pre-deploy actions for configuring Firebase to redirect
a deployment to any of `angular.io`, `rc.angular.io` or
`next.angular.io` and also configure whether all requests or only
non-file requests will be redirected.
In a future commit, this will allow managing redirects for the `stable`,
`rc` and `next` deployments via the Firebase config file (without
requiring changes in the Firebase console or DNS).

PR Close #43963
2021-10-29 15:05:11 -07:00
George Kalpakas 609579c8f2 feat(docs-infra): create undo functions for all pre-deploy actions (#43963)
Create functions to undo the changes made by any pre-deploy action.
In a future commit, this will allow deploying a build to multiple
projects/sites with different small tweaks for each.

PR Close #43963
2021-10-29 15:05:11 -07:00
George Kalpakas 57e6339cd1 test(docs-infra): avoid running expensive operations when focusing/skipping tests (#43963)
Previously, the pre-computation of branch version info for the
`deploy-to-firebase` tests would always take place even when the tests
that used that info were skipped. This pre-computation involves network
access and may add a noticeable delay.

This commit refactors the tests to not do the pre-computation if the
corresponding tests are skipped. This allows for a faster iteration
when focusing on a different set of tests.

PR Close #43963
2021-10-29 15:05:10 -07:00
George Kalpakas 4c22339bcb refactor(docs-infra): move deploy-to-firebase post-deploy actions to a separate file (#43963)
Move some functions that are used as post-deploy actions from
`deploy-to-firebase/index.mjs` to a separate file
(`deploy-to-firebase/post-deploy-actions.mjs`) to keep `index.mjs` small
and easier to maintain.

NOTE:
While not strictly necessary atm, `post-deploy-actions.mjs` uses the
same default export pattern for consistency with `utils.mjs`.

PR Close #43963
2021-10-29 15:05:10 -07:00
George Kalpakas 5049124b25 refactor(docs-infra): move deploy-to-firebase pre-deploy actions to a separate file (#43963)
Move some functions that are used as pre-deploy actions from
`deploy-to-firebase/index.mjs` to a separate file
(`deploy-to-firebase/pre-deploy-actions.mjs`) to keep `index.mjs` small
and easier to maintain.

Also, rename the `removeServiceWorker()` function to
`disableServiceWorker()`, which is a little more accurate.

NOTE:
While not strictly necessary atm, `pre-deploy-actions.mjs` uses the same
default export pattern for consistency with `utils.mjs`.

PR Close #43963
2021-10-29 15:05:10 -07:00
George Kalpakas 6d7c2e0e71 refactor(docs-infra): move deploy-to-firebase util functions to a separate file (#43963)
Move some util functions from `deploy-to-firebase/index.mjs` to a
separate file (`deploy-to-firebase/utils.mjs`) to keep `index.mjs` small
and easier to maintain.

NOTE:
To make it easier to mock functions in tests, `utils.mjs` uses a default
export (instead of multiple named exports) and references local
functions through the default exported object.

PR Close #43963
2021-10-29 15:05:10 -07:00
George Kalpakas 7120a008c8 refactor(docs-infra): create logSectionHeader() helper in deploy-to-firebase script (#43963)
Create a `logSectionHeader()` helper function to avoid duplicating code.

PR Close #43963
2021-10-29 15:05:10 -07:00
George Kalpakas 50b2d273b8 refactor(docs-infra): convert deploy-to-firebase script to ESM (#43963)
Convert the `deploy-to-firebase` script (and corresponding tests) from
CommonJS format to ESM.

PR Close #43963
2021-10-29 15:05:10 -07:00
George Kalpakas c359da412b build(docs-infra): validate computed deployments in deploy-to-firebase script (#43963)
The `deploy-to-firebase` script might have to deploy a single AIO build
to multiple projects/sites (potentially with small tweaks between each).

This commit adds a step to validate the computed deployments to ensure
they are compatible with each other (for example, that there is exactly
one primary deployment that builds the app and sets the theme/mode and
that all secondary deployments are compatible with the primary one).

PR Close #43963
2021-10-29 15:05:10 -07:00
George Kalpakas 3f480a1836 refactor(docs-infra): add name and type to deployment info (#43963)
This commit adds two new properties, `name` and `type`, to deployment
info data. This will make it easier to differentiate between deployment
targets (e.g. primary vs secondary) and will provide more informative
log messages.

In a subsequent commit, this new data can be used to validate the
computed deployments list.

PR Close #43963
2021-10-29 15:05:10 -07:00
George Kalpakas 8292c6636b fix(docs-infra): improve an error message in deploy-to-firebase script (#43963)
This commit fixes a typo in an error message thrown in the
`deploy-to-firebase` script (`but it was but it was` --> `but it was`).

It also makes the error clearer when the request was not redirected.

Old error:
> Expected '<original-url>' to be redirected to '<expected-url>', but it
> was but it was redirected to 'undefined'.

New error:
> Expected '<original-url>' to be redirected to '<expected-url>', but it
> was not redirected.

PR Close #43963
2021-10-29 15:05:10 -07:00
George Kalpakas 6ee479d8eb build(docs-infra): enable linting for deploy-to-firebase scripts (#43963)
This commit enables linting for the scripts in
`aio/scripts/deploy-to-firebase/`. It also makes the necessary changes
to the files to make linting pass.

PR Close #43963
2021-10-29 15:05:10 -07:00
George Kalpakas 2fa48e5f88 refactor(docs-infra): move deploy-to-firebase.js into a dedicated directory (#43963)
This commit moves the `aio/scripts/deploy-to-firebase.js` script into a
new directory, `aio/scripts/deploy-to-firebase/`. This will make it
easier to break it up into multiple smaller files to better organize the
code (without polluting the `aio/scripts/` directory).

PR Close #43963
2021-10-29 15:05:10 -07:00
Alan Agius 96b99c443b docs: update creating libraries guide (#43982)
We update the `creating libraries` guide to remove View Engine references. This is because in version 13 users are no longer able to build libraries using View Engine.

In addition to the above, we also remove references to `npm link`. As this is actually not a recommended workflow, and was mostly needed in older versions of the CLI prior to version 6, were multi-projects workspaces were introduced.

Closes #43949

PR Close #43982
2021-10-29 14:23:04 -07:00
George Kalpakas 3faef7180d refactor(docs-infra): align docs examples with default CLI TS config (#43880)
This commit enable the `noImplicitOverride` and
`noPropertyAccessFromIndexSignature` TypeScript compiler options for
docs examples to better align with the default configuration of new
Angular CLI apps. It also makes the necessary changes to the docs
examples source code.

PR Close #43880
2021-10-29 13:10:26 -07:00
George Kalpakas 12b7f4490f build(docs-infra): update docs examples to Angular v13.0.0-rc.0 (#43880)
This commit updates the docs examples to Angular v13.0.0-rc.0. In
addition to updating the dependency versions, it also updates the
projects' structure and configs to more closely match what a new v13 CLI
app would look like. See, also, the [diff][1] between a basic v12.1.3
CLI app and a v13.0.0-rc.0 one.
(NOTE: v12.1.3 was the last version for which we aligned the projects
with how a new CLI app would look like.)

Additionlly:
- Since we now use RxJS v7 in docs examples, this commit removes the
  extra CI steps to explicitly test the docs examples against RxJS v7.
- Since Angular v13 no longer supports IE, this commit removes an
  IE-specific section from `upgrade-setup.md`.

[1]: https://github.com/cexbrayat/angular-cli-diff/compare/12.1.3..13.0.0-rc.0

PR Close #43880
2021-10-29 13:10:26 -07:00
George Kalpakas 620a705065 test(docs-infra): fix practical-observable-usage docs example tests with RxJS v7 (#43880)
Due to how `debounceTime()` works in RxJS v7, Jasmine's mock clock was
not enough to trigger it. This commit fixes it by providing a similar
mock clock that is able to mock all of `Date.now()`, `setInterval()` and
`setTimeout()`.

PR Close #43880
2021-10-29 13:10:26 -07:00
George Kalpakas 6ff9798268 build: use the latest version of Chrome (v93) in non-bazel tests (#43880)
This commit updates the version of Chrome used in non-bazel tests (via
Puppeteer) to the latest (v93).

PR Close #43880
2021-10-29 13:10:26 -07:00
Jochen Kraushaar f225bfde80 docs(common): describe behavior when reference changes (#42863)
PR Close #42863
2021-10-28 11:34:26 -07:00
vthinkxie 8ae99821d6 fix(core): support InjectFlags argument in NodeInjector.get() (#41592)
The `InjectFlags` argument was defined for both `getOrCreateInjectable()` and `Injector`, but was ignored in `NodeInjector`.
This PR adds support for getting parent token via `NodeInjector.get()`.

close #31776

PR Close #41592
2021-10-28 11:20:01 -07:00
Pete Bacon Darwin 59ca52fd4f refactor: simplify the LOCALE_ID provider (#43913)
Other parts of the intialization process are responsible for passing the locale id to ivy, so it does not need to happen in the provider factory. E.g. `PlatformRef.bootstrapModule()` and `R3TestBedCompiler.finalize()`.

PR Close #43913
2021-10-28 11:19:13 -07:00
Pete Bacon Darwin 4ba1a249ad refactor: remove ɵloc and related code (#43913)
This code is not used in ivy - and probably was not being used
in View Engine either.

PR Close #43913
2021-10-28 11:19:13 -07:00
Jessica Janiuk 8d89b2853c Revert "refactor(forms): update minlength/maxlength to inherit abstractValidator" (#43971)
This reverts commit 7b31b887f9.

PR Close #43971
2021-10-27 21:42:26 +00:00
Jessica Janiuk a2ce1da85b release: cut the v13.0.0-rc.2 release (#43968) 2021-10-27 11:29:30 -07:00
Mladen Jakovljević 7de7dc89bf fix(docs-infra): fix heritage links (#43956)
Fix incorrect escape of special characters when rendering member heritage docs. Example: DefaultIterableDiffer docs incorrectly renders what this class implements - it does not fully display generic types of implemented interfaces.

PR Close #43956
2021-10-27 16:13:36 +00:00
Virginia Dooley b7be4cfc02 docs: review tag added (#43465)
PR Close #43465
2021-10-27 16:13:02 +00:00
Alan Agius cfc509c48a refactor(migrations): remove no longer accessible migrations (#43947)
With this change we remove no longer needed migrations. These migrations are no longer accessible following a change angular/angular-cli#21986 in the Angular CLI.  The CLI now shows an error message when users try to update `@angular/` and `@nguniversal/` packages across multiple major versions.

Example to update from version 11 to version 13 the recommand approach is to run the following commands

```
ng update @angular/core@12
ng update @angular/core@13 (which is the same as ng update @angular/core)
```

NB: It is recommand that when update from one major to another, users verify that their applications is working as expected.

PR Close #43947
2021-10-26 23:59:42 +00:00
Virginia Dooley ec23ae99d5 docs: reviewed tag added (#43487)
PR Close #43487
2021-10-26 23:57:45 +00:00
Virginia Dooley 0dbe1c695a docs: reviewed tag added (#43488)
PR Close #43488
2021-10-26 22:57:21 +00:00
Renovate Bot 081a4c2722 build: update all non-major dependencies (#43917)
PR Close #43917
2021-10-26 21:16:07 +00:00
iRealNirmal c44d1cbd58 refactor(forms): update minlength/maxlength to inherit abstractValidator (#43835)
Modified minlength and maxlength validator to inherit abstractValidator

For every validator type different PR will be raised as discussed in #42378.

Closes #42267

PR Close #43835
2021-10-26 20:24:40 +00:00
Joey Perrott 97b6f6843f ci: update commit-message-based-labels job to be called labels (#43944)
Using the job name labels results in a more readable and better looking Github status.

PR Close #43944
2021-10-26 20:20:05 +00:00
Joey Perrott 1571c2b58f build: create issue selector configuration (#43923)
Create a configuration file to set up the new issue selector page.

PR Close #43923
2021-10-26 20:19:07 +00:00
Renovate Bot 269feceb67 build: lock file maintenance (#43937)
PR Close #43937
2021-10-26 20:12:01 +00:00
JoostK fa7693f784 refactor(compiler-cli): extract error documentation base url into separate file (#43527)
Prior refactorings caused unexpected g3 sync issues due to a patch that
changes the error documentation URL. This commit moves the base url into
a separate file to make this more apparent.

PR Close #43527
2021-10-26 18:22:34 +00:00
JoostK 8e13c351ac fix(compiler-cli): avoid broken references in .d.ts files due to @internal markers (#43527)
The `ErrorCode` enum in the `error_code.ts` file is governed by public
api guards but the other top-level exports from that file are exempt
from public api documentation and are therefore marked as `@internal`.
However, TypeScript is configured with the `stripInternal` compiler
option such that declarations with `@internal` markers are not emitted
into the `.d.ts` files, but this means that the reexports in the barrel
file end up referring to missing declarations.

The `stripInternal` option is considered internal and its documentation
states to use at your own risk (as per https://github.com/microsoft/TypeScript/issues/45307).
Having the option enabled is desirable for us as it works well for
hiding class fields that are marked `@internal`, which is an effective
way to hide members from the .d.ts file. As a workaround for the issue
with top-level symbols, the declarations with `@internal` markers are
moved to dedicated files for which no public api guard is setup,
therefore allowing their `@internal` markers to be dropped.

Fixes #43097

PR Close #43527
2021-10-26 18:22:33 +00:00
dirk diebel 59e56e79d0 docs(docs-infra): change deprecated keyboardEvent.keyCode example to use keyboardEvent.code (#43934)
PR Close #43934
2021-10-26 00:05:23 +00:00
amayer42 940eafa351 docs(localize): fix spelling of documentation link (#43941)
Fixes the spelling of 'i18n' in a documentation link.
PR Close #43941
2021-10-25 22:05:18 +00:00
Jessica Janiuk 15bdd0d48f Revert "refactor(migrations): remove no longer accessible migrations" (#43943)
This reverts commit f21ad8780b.

PR Close #43943
2021-10-25 22:02:32 +00:00
Alan Agius 087fae5ea9 refactor(migrations): remove no longer accessible migrations (#43942)
With this change we remove no longer needed migrations. These migrations are no longer accessible following a change https://github.com/angular/angular-cli/pull/21986 in the Angular CLI.  The CLI now shows an error message when users try to update `@angular/` and `@nguniversal/` packages across multiple major versions.

Example to update from version 11 to version 13 the recommand approach is to run the following commands

```
ng update @angular/core@12
ng update @angular/core@13 (which is the same as ng update @angular/core)
```

NB: It is recommand that when update from one major to another, users verify that their applications is working as expected.

PR Close #43942
2021-10-25 19:32:27 +00:00
Andrew Kushnir 8277c38bd8 test(platform-browser): complete component bootstrap before switching to the next test (#43933)
The bootstrap tests that reused the same component (the `HelloRootCmp` one) were randomly failing due to the incomplete cleanup between tests. This commit ensures that the component bootstrap is fully cimpleted and there are no pending async actions before going to the next test.

PR Close #43933
2021-10-25 17:58:27 +00:00
George Kalpakas 7c5d642106 fix(ngcc): support alternate UMD layout when adding new imports (#43931)
In #43879, `UmdReflectionHost` was updated to deal with the new UMD
format used by Rollup, where the parenthesis is around the wrapper
function and not the wrapper function call.
For reference, this caused failures in the `ngcc-validation` repo
([example 1][1], [example 2][2]).

This commit updates `UmdRenderingFormatter` to also handle both UMD
formats. In order to validate the change, this commit also updates the
`UmdRenderingFormatter` tests to run against both UMD formats.

[1]: https://circleci.com/gh/angular/ngcc-validation/65916
[2]: https://circleci.com/gh/angular/ngcc-validation/65758

PR Close #43931
2021-10-25 17:56:27 +00:00
Doug Parker 8178a3028b docs: deprecate @angular-devkit/build-optimizer (#43915)
The entire package is deprecated in v13. Deprecation message is mostly copied from the package's [README](https://github.com/angular/angular-cli/blob/13.0.0-next.9/packages/angular_devkit/build_optimizer/README.md), with just some minor edits.

(cherry picked from commit d81744e600)

PR Close #43915
2021-10-25 17:54:52 +00:00
Alan Agius 9968a8ad82 docs: remove fesm5 and esm5 deprecation notice. (#43915)
This has been removed in version 11 and should no longer be listed.

PR Close #43915
2021-10-25 17:54:52 +00:00
Alan Agius e569a9c1fe docs: update CLI deprecation guide to reflect new deprecations (#43915)
With this change we update the CLI deprecations sections as per version 13.

PR Close #43915
2021-10-25 17:54:52 +00:00
Alan Agius 096ebb2830 docs: format tables in deprecations page (#43915)
Currently, the table are unformatted which makes it extremely hard to read when viewing the markdown file directly.

PR Close #43915
2021-10-25 17:54:52 +00:00
ericcheng2005 97fc9de2c4 refactor(core): made comment structure consistent in index.ts (#43684)
changed second big block of comments to use multi-line comment structure instead of multiple single-line comments

PR Close #43684
2021-10-21 18:40:00 +00:00
ericcheng2005 6dc4d83f37 docs: added commas to sentences in .vscode/README.md (#43684)
PR Close #43684
2021-10-21 18:40:00 +00:00
ericcheng2005 23928a02d3 docs: fixed minor grammar mistakes in CONTRIBUTING (#43684)
PR Close #43684
2021-10-21 18:39:59 +00:00
Doug Parker 72f6877cb0 docs: remove Ivy-specific guides (#43860)
Ivy is the only supported rendering engine in v13, so there is no need to document the concept. Everything in Angular is Ivy. This starts the removal process by deleting Ivy-specific guides and references to them. It also updates the glossary to be more clear that Ivy is the current rendering engine while View Engine is simply a historical note.

This does not attempt to fully remove all references to "Ivy" or "View Engine", that will likely be a more involved clean up process.

PR Close #43860
2021-10-21 18:14:34 +00:00
krzysztof-grzybek adc68b100b fix(router): reuse route strategy fix (#43791)
Currently, it's impossible to cache (detach/attach) parent route without caching child routes.
This produces a bug, when navigating from a/b to c, then to a/d, where a route is cached.
On the last navigation, we incorrectly restore a/b route instead of a/d.
This change introduces new behavior: if the route should be detached/attached,
we do so, but we check also child routes recursively.

Fixes #17333

PR Close #43791
2021-10-21 16:28:03 +00:00
Alan Agius 5d031848d3 ci: update angular/dev-infra/github-actions sha (#43904)
Consume latest version of `angular/dev-infra/github-actions`.

PR Close #43904
2021-10-21 16:26:36 +00:00
Alan Agius bbbf678bed ci: replace breaking-changes-label with commit-message-based-labels (#43904)
See: https://github.com/angular/dev-infra/pull/269 for more context

PR Close #43904
2021-10-21 16:26:35 +00:00
Tomasz Domański 22009f62df docs: fix typos in the workspace config guide (#43918)
PR Close #43918
2021-10-21 14:42:46 +00:00
George Kalpakas 0039b712c0 refactor(service-worker): avoid unnecessary writes to cache when version fails (#43680)
When an app version is detected as broken, the SW calls the
`Driver#versionFailed()` method. Previously, this method would in turn
call the `Driver#sync()` method, which writes some metadata about the
SW's state to the `ngsw:/:db:contol` cache. More specifically,
`Driver#sync()` persists info about all known app versions, which one is
the latest and also what version each client is assigned to.

However, no relevant info is changed inside `Driver#versionFailed()`, so
the call to `Driver#sync()` is redundant (since there are no changes
that need to be synced with the cache). This is a left-over from
before #43518, when `Driver#versionFailed()` used to update version
assignments and thus did require synchronization with the cache.

This commit removes the redundant `Driver#sync()` call to avoid an
unnecessary write to the cache.

PR Close #43680
2021-10-21 14:20:51 +00:00
iRealNirmal 665466def3 docs: move deprecations example snippets to external file (#43700)
Moving angular depreciation examples to external project

closes #43337

PR Close #43700
2021-10-20 20:24:55 +00:00
Willy Schott ae52bf1df3 docs: clarify meaning of ellipsis in bazel command (#43890)
PR Close #43890
2021-10-20 20:14:49 +00:00
Andrew Kushnir b31a9a75ad release: cut the v13.0.0-rc.1 release (#43911) 2021-10-20 09:57:26 -07:00
JoostK 7d33af0400 test(compiler-cli): run i18n extraction tests using Ivy compiler (#43893)
This commit re-enables the `extract_i18n` test target and updates the
test to run with the Ivy compiler.

PR Close #43893
2021-10-19 16:26:22 -07:00
JoostK aef01389e1 test(compiler-cli): run watch mode tests using Ivy compiler (#43893)
This commit re-enables the `perform_watch` test target and updates the
test to run with the Ivy compiler.

Additionally, this target was switched over to use Angular v12 packages
as input to the test, to allow the ViewEngine tests to continue working
with v13 packages which are Ivy-only. This commit reverts those changes
now that View Engine tests are disabled, as it's desirable to test
against local artifacts that are build within the monorepo instead of
depending on NPM packages.

PR Close #43893
2021-10-19 16:26:22 -07:00
Alan Agius 9d9346c57a docs: add docs about build cache (#43843)
With this change we add docs about persistant disk cache with was enabled by default in the CLI via https://github.com/angular/angular-cli/pull/21827

PR Close #43843
2021-10-19 10:45:30 -07:00
Joey Perrott 812a33df8c ci: mark core/schematics/test:test and compiler-cli/test:perform_watch test as view engine only (#43862)
Both test targets fail because, at test time, they use the view engine compiler, even when bazel sets the
configuration to use ivy.

PR Close #43862
2021-10-19 10:06:57 -07:00
Doug Parker aafde79a71 refactor(compiler-cli): throw an error when compiling with View Engine. (#43862)
The View Engine compiler now throws when constructed and will be removed shortly. Direct users should switch to `NgtscProgram` to build with [Ivy](https://angular.io/guide/ivy). The View Engine compiler is being removed, so this makes it throw an error to ensure no one accidentally depends on code being removed.

PR Close #43862
2021-10-19 10:06:57 -07:00
Joey Perrott 57bf6b7cbd ci: correct comment related to building view engine npm packages (#43862)
Removing the comment related about building the npm packages using view engine as it was actually done via
ivy, now that ivy is used for all builds there is no need for expressing the aspect of the build.

PR Close #43862
2021-10-19 10:06:57 -07:00
Joey Perrott 5e562b66d4 ci: remove view engine test job (#43862)
Remove the view engine test job as view engine is no longer being tested on CI.  Additionally, update size
tracking to rely on test job instead of test_ivy_aot.

PR Close #43862
2021-10-19 10:06:57 -07:00
Joey Perrott 04b4209d71 ci: remove windows view engine test job (#43862)
Remove the windows view engine test job as view engine is no longer being tested on CI.

PR Close #43862
2021-10-19 10:06:57 -07:00
Joey Perrott f1e18493ca ci: remove saucelabs view engine tests (#43862)
Remove the view engine specific saucelabs test job and associated tags/tooling as view engine is no longer being tested
on CI.

PR Close #43862
2021-10-19 10:06:57 -07:00
Joey Perrott 442f520e48 build: remove ivy-aot bazel tag (#43862)
Remove the ivy-aot bazel tag from usage as it served a duplicate purpose as ivy-only which is now removed as both are
unneeded with Ivy as the default compiler used.

PR Close #43862
2021-10-19 10:06:57 -07:00
Joey Perrott 90ac77051d build: remove fixme-ivy-aot tag filter (#43862)
Remove the fixme-ivy-aot tag filter from usage as no targets are tagged with fixme-ivy-aot as ivy is now the
compiler used by default.

PR Close #43862
2021-10-19 10:06:56 -07:00
Joey Perrott 959f563fc9 build: remove "ivy-only" bazel tag (#43862)
Because all actions are assumed to be running on Ivy, things which only work on Ivy should not be marked as
Ivy only.

PR Close #43862
2021-10-19 10:06:56 -07:00
Joey Perrott 730511b948 build: rename "no-ivy-aot" tag to "view-engine-only" (#43862)
Using the tag "view-engine-only" better describes the expected usage of bazel targets with the test. They can
only be run with view engine.

PR Close #43862
2021-10-19 10:06:56 -07:00
Joey Perrott c3f677dbe6 build: remove test-ivy-aot yarn script (#43862)
Since building with ViewEngine is not longer desired on CI, removing the ivy vs non-ivy testing yarn scripts
is done, informing developers to instead use `yarn test` as all tests should be run using the Ivy complier.

PR Close #43862
2021-10-19 10:06:56 -07:00
Joey Perrott b75ee8d810 build: Use Ivy compiler for bazel builds by default (#43862)
Setting the angular_ivy_enabled environment variable to True will default Bazel builds to use the Ivy
compiler rather than defaulting to ViewEngine.

PR Close #43862
2021-10-19 10:06:56 -07:00
Joey Perrott b489ae5ecd ci: remove browserstack configuration (#43881)
Remove browserstack configuration from the repo as it is not used for our CI.

PR Close #43881
2021-10-18 15:00:23 -07:00
Pete Bacon Darwin c882b9fa8b fix(ngcc): support alternate wrapper function layout for UMD (#43879)
Recently rollup, used by ng-packagr, changed the position of parentheses
around its generated UMD wrapper functions.

This commit ensures that ngcc can handle both.

Fixes #43870

PR Close #43879
2021-10-18 14:57:03 -07:00
Andrew Kushnir fc6519c25a Revert "fix(compiler): support i18n interpolated only attribute bindings (#43815)" (#43882)
This reverts commit bba0a87055.

The reason for rollback: this change is breaking some targets in Google's codebase when there is no attribute value is displayed (attr.aria-label) when translated.

PR Close #43882
2021-10-18 13:16:01 -07:00
Kristiyan Kostadinov 14b492df26 fix(compiler): do not error if $any is used inside a listener (#43866)
Fixes that `$any` casts weren't being converted to statements inside listeners which resulted in a compiler error.

Fixes #43841.

PR Close #43866
2021-10-18 10:43:03 -07:00
George Kalpakas cbde9edace docs: fix a couple of random typos (#43878)
PR Close #43878
2021-10-18 10:41:34 -07:00
Andrew Scott dc6909ad3e fix(router): Do not clear currentNavigation if already set to next one (#43852)
Experimentation with the Router URL management exposed a situation where
the `currentNavigation` was being cleared in the `finalize` after the
`currentNavigation` was already set to the next one.

This change ensures that the `currentNavigation` is only cleared if the
id of the finalized transition matches the one on the
`currentNavigation` object.

PR Close #43852
2021-10-18 10:30:54 -07:00
Andrew Scott dbcc4bebee refactor(router): Remove use of browserUrlTree in scheduleNavigation (#43632)
There are no added tests here because the change is generally equivalent
to what was there before. The goal of that piece of code is to prevent
duplicate navigations due to the location synchronization code between
AngularJS and Angular. That is, the Angular router listens to the
`popstate` event and triggers navigations, but so does the AngularJS
router and triggers navigations through `router.navigateByUrl`. The
`setTimeout` in the Angular Router's `setUpLocationChangeListener` is
there to make this bit of code work: the 'popstate'/'hashchange'
navigation will necessarily come after the imperative nav triggered by
AngularJS's location sync.

Anyhow, in the long run, I would like to get rid of this bit of code
altogether. We should not have special handling for these cases. The
AngularJS/Angular location sync should either:

1. Not trigger a duplicate navigation in the first place
or
2. Be tolerant to processing the duplicate navigation.

In the short term, this change benefits the router while we investigate
removing this logic completely because now browserUrlTree has a single
responsiblity: to support `onSameUrlNavigation==='reload'`. This means
that we can work towards removing the `browserUrlTree` tracking from the
Router code at some point as well and have the `onSameUrlNavigation`
logic be part of a pre-navigation hook that can be handled outside the
`Router`. This may or may not be possible, but the change here opens up
that change for investigation.

PR Close #43632
2021-10-18 10:29:23 -07:00
David Shevitz db57e391cc docs: update getting started links to provide a more consistent user experience (#43872)
PR Close #43872
2021-10-18 09:25:36 -07:00
Pete Bacon Darwin 8c91e33d5d fix(compiler): support i18n interpolated only attribute bindings (#43815)
While fully dynamic bound properties (and attributes) cannot be marked for localization, properties that only contain interpolation can.

This commit ensure that attribute bindings that only contain interpolation can also be marked for localization.

Closes #43260

PR Close #43815
2021-10-18 09:24:42 -07:00
dario-piotrowicz ebc9b55dcf fix(docs-infra): add paddings to docs-card titles (#43859)
improve the aio docs-card title by adding some padding
so that it doesn't get too close to the card's edges

PR Close #43859
2021-10-18 09:23:19 -07:00
dario-piotrowicz 017748c477 fix(docs-infra): move security anchors outside callout elements (#43865)
two callout elements in the security guide have anchors
as their first child element instead of the callout's header
causing ugly/unwanted spacing, move the anchors above the
callout elements to fix such issue

PR Close #43865
2021-10-18 09:22:39 -07:00
Paul Gschwendtner ee2678ca42 build: update bazel integration test to rules_nodejs v4.4.1 (#43853)
Updates the Bazel integration test to `rules_nodejs` v4.4.1. Renovate
could not complete this update automatically because it is unable
to update the `package.json` and `lock` file due to there being
relative `file:` references.

PR Close #43853
2021-10-15 13:55:53 -07:00
Renovate Bot 0983eec7ab build: update all non-major dependencies (#43853)
Updates all non-major dependencies to their latest available
versions.

PR Close #43853
2021-10-15 13:55:53 -07:00
Pete Bacon Darwin 70c14ed66d build(docs-infra): add a box around CLI command line reference syntax (#43850)
This commit helps to make the section that describes an overview of the syntax of a CLI command stand out from the surrounding text.

Closes #26574

PR Close #43850
2021-10-15 11:35:47 -07:00
Andrew Scott 772e08d14e fix(router): fix Router's public API for canceledNavigationResolution (#43842)
The commit which made the `canceledNavigationResolution` property on the `Router`
public did not add the corresponding configuration in the `ExtraOptions`.
https://github.com/angular/angular/commit/3c6b653089837459809a370ebcaf8911c3bab9ed
This was a mistake and is being corrected in this commit. We should not
encourage changing the properties post-setup (i.e.
`inject(Router).canceledNavigationResolution = 'computed'`). This manner
of configuration makes the options non-tree shakeable because we have to
keep both implementations in case the value changes at runtime.

PR Close #43842
2021-10-15 11:35:02 -07:00
Younes Jaaidi 12dfc0e991 docs: add younes jaaidi to GDE resources (#43721)
PR Close #43721
2021-10-15 10:49:26 -07:00
Doug Parker 426a3ecae7 fix(compiler-cli): updates ngc to pass the build when only warnings are emitted (#43673)
Refs #42966.

Previously, a build when emitted one warning and no errors would fail with a non-zero exit code. This is not what users would expect, but had not been an issue before since the compiler did not actually emit any warnings. With upcoming extended template diagnostics and other warnings, this is now a case that needs to be supported. Warnings are printed to `stderr` as before, but `ngc` now exits with code `0` and the build is considered successful.

Implemented this by adding a new `expectedExitCode` parameter to `driveDiagnostics()` which asserts against the real exit code. Most importantly, it does not **require** the the build to pass since any exit code can be given, so it is up to the test to assert this as well as many messages printed to make sure they are acceptable. This is useful for testing warnings and ensuring the build still passes.

PR Close #43673
2021-10-15 10:17:39 -07:00
JoostK e3b4abe3db docs: include WrappedValue as removed API on deprecation page (#43685)
A rebase of #43507 seems to have inadvertently dropped the note about
the removed `WrappedValue` API from the deprecations page, so this
commit reintroduces the text.

PR Close #43685
2021-10-15 10:16:03 -07:00
dario-piotrowicz 7e5268174b fix(docs-infra): apply minor style fixes to aio contributor cards (#43844)
improve the aio contributors card by aligning centrally the
contributor's name and adding some padding so that it doesn't
get too close to the card's edges

Note: the name's aligning was already present by wrongly removed in
PR #43355

PR Close #43844
2021-10-15 10:12:59 -07:00
Joe Martin (Crowdstaffing) 91e73c4505 docs: internationalization topics (#43819)
Update links and code-examples.  Remove redundant comments.

PR Close #43819
2021-10-14 15:53:27 -07:00
Andrew Scott 68cdcd3259 Revert "refactor(router): clean up internal hooks (#43804)" (#43845)
This reverts commit 5cc51880db.

PR Close #43845
2021-10-14 14:43:41 -07:00
Renovate Bot de5a63ba40 build: update dependency @typescript-eslint/parser to v5 (#43807)
PR Close #43807
2021-10-14 10:14:49 -07:00
Andrew Scott 5f6e568dd6 refactor(router): clean up internal hooks (#43804)
* beforePreactivation hook is unused
* The only place that uses afterPreactivation does not use the arguments

Not to say we won't want to provide hooks similar to this in the future,
but the current state is over-engineered for what it's being used for.

PR Close #43804
2021-10-14 10:04:01 -07:00
Alan Agius 39cb30e2f2 docs: add missing value types to optimization configuration (#43839)
It appears that when the tables were changed from HTML to markdown some value types were lost. With this change we add the missing types and remove the commented out HTML content.

PR Close #43839
2021-10-14 10:01:57 -07:00
Alan Agius 342d642301 docs: remove no longer relevant sections in build page (#43837)
`Backward compatibility with Lighthouse` and `Backward compatibility with CSS grid` sections are no longer relevant since Internet Explorer is no longer supported.

PR Close #43837
2021-10-14 10:01:20 -07:00
Natalia Venditto 1c3afc9658 docs: add natalia venditto to GDE resources (#43825)
PR Close #43825
2021-10-14 10:00:02 -07:00
Joey Perrott 6113813300 docs: add missing split marker (#43830)
Due to an outdated version of ng-dev running during release the changelog generated did not include a split marker,
it should be added to avoid issues in the future.

PR Close #43830
2021-10-13 18:48:00 +00:00
Andrew Scott b5eccde447 release: cut the v13.0.0-rc.0 release (#43828) 2021-10-13 11:24:59 -07:00
Alan Agius 7ba9591a1d ci: remove rollup from renovate ignoreDeps (#43737)
We can now update to the latest rollup version.

PR Close #43737
2021-10-13 16:56:42 +00:00
Alan Agius 80449f4570 build: update rollup dependencies (#43737)
With this change we update `rollup` and remove the usage of no longer maintained `rollup-plugin-commonjs` and `rollup-plugin-node-resolve` plugins.

PR Close #43737
2021-10-13 16:56:42 +00:00
dario-piotrowicz b155bf71d0 refactor(docs-infra): remove unnecessary tsconfig.json file (#43818)
the tsconfig.json file in aio/content/examples does not seem necessary
anymore as it was only used for tslinting and tslint has been removed
from the examples in PR #43592 and PR #43746

PR Close #43818
2021-10-13 16:51:11 +00:00
Renovate Bot 567c8fad42 build: update dependency @typescript-eslint/eslint-plugin to v5 (#43806)
PR Close #43806
2021-10-13 16:49:50 +00:00
Joey Perrott 780082c025 build: update to cldr@39 (#43820)
Update repository to use cldr version 39 as it is the latest available.

PR Close #43820
2021-10-13 16:49:24 +00:00
Renovate Bot c6496350a9 build: update dependency @rollup/plugin-commonjs to v21 (#43675)
PR Close #43675
2021-10-13 16:48:46 +00:00
dario-piotrowicz 098d7ade70 docs(core): apply minor improvements to the InjectionToken's api docs (#43693)
PR Close #43693
2021-10-13 16:46:28 +00:00
Joe Martin (Crowdstaffing) ad832900b7 docs: update internationalization topics (#43722)
Add new $localize and Ivy content.  Clean up navigation.

PR Close #43722
2021-10-12 21:38:38 +00:00
Andrew Scott db01894791 docs: remove mention of router API that 'may be deprecated' (#43765)
The `params` and `queryParams` properties are listed in the deprecations as
properties that "may be deprecated in the future". We should not
document "maybe" deprecations. They are either deprecated or they are
not deprecated. For this case, there is no value in the deprecation
without a plan for how we will remove them. Once that is in place, we
can truly deprecate them.

PR Close #43765
2021-10-12 17:56:06 +00:00
dario-piotrowicz 663690fc86 fix(docs-infra): improve cancel icon in top-menu search (#43600)
webkit browsers show a cancel X icon in the input search on focus/hover
which allows to clear the content of the input, such icon has small
glitches/imperfections so use a mat-icon instead

(this also adds such icon to non-webkit browsers)

PR Close #43600
2021-10-12 17:50:30 +00:00
Joey Perrott 42f93418b6 docs: update CHANGELOG.md readme to include entry separators (#43799)
Add `<!-- CHANGELOG SPLIT MARKER -->` between changelog entries to match the expected
format of the CHANGELOG.md file for the repository tooling.

PR Close #43799
2021-10-12 17:49:20 +00:00
Renovate Bot af31781e10 build: lock file maintenance (#43793)
PR Close #43793
2021-10-12 17:48:28 +00:00
dario-piotrowicz 39f625a4e9 docs(animations): fix wrong code links present in the animations guide (#43787)
fix the links present in the animations guide under td elements written as
`<code>[text](link)()</code>` which are not rendered properly

Note:
  - the bug was introduced in PR #42885
  - the bug is only present for code blocks inside html block elements,
    the aforementioned format can be used in the inline html elements without issues

PR Close #43787
2021-10-12 17:48:00 +00:00
mgechev 154dda2eed docs: update ngUpgrade support message (#43704)
PR Close #43704
2021-10-12 17:46:15 +00:00
Alan Agius 27ba8033dc docs: update how to remove a configuration item (#43795)
To remove a configuration item, `undefined` needs to be used as value.
PR Close #43795
2021-10-12 17:44:56 +00:00
Alan Agius 8e9e27a1df docs: update config path in per user tracking section (#43795)
`cli.analyticsSharing.user` is not a valid config path. `cli.analyticsSharing.uuid` is the correct one.

Partially addresses https://github.com/angular/angular-cli/issues/21916

PR Close #43795
2021-10-12 17:44:56 +00:00
Alan Agius 05c03117bc ci: use Node.js browsers image (#43810)
Spinning up a Node.js browsers image has little to no overhead when the image is not cached on the host. `install_chrome_libs` however takes takes ~13s everytime.

PR Close #43810
2021-10-12 17:43:15 +00:00
Alan Agius 73c1570237 build(docs-infra): update min range of node versions (#43810)
Eslint 8 which is used in AIO requires Node.js `14.17.x` or later.

PR Close #43810
2021-10-12 17:43:15 +00:00
Alan Agius 791b6f47e4 ci: update default circle ci image to cimg/node:14.17.6 (#43810)
With this change we update Node.js version to 14.17 which is needed because of Eslint 8. Also, we replace the legacy images `circleci/node` with the new images `cimg/node`.

See: https://circleci.com/developer/images/image/cimg/node

PR Close #43810
2021-10-12 17:43:15 +00:00
Paul Gschwendtner a589aff3e4 ci: re-enable dev-app building in components-repo-unit-tests job (#43798)
Re-enables the building of the `src/dev-app` package in the components
repo when the components-repo-unit-test job runs. We previously disabled
the dev-app because it was not compatible with template typechecking of
ngtsc. This should be fixed now and can re-enable it.

This could be valuable for having some actual real test scenarios of
type checking.

PR Close #43798
2021-10-12 17:42:46 +00:00
Paul Gschwendtner 562137e16b ci: re-enable components-repo-unit-tests job after APF v13 adjustments (#43798)
The APF v13 changes have landed in the `angular/components` repository
so that the CI check can be re-enabled.

PR Close #43798
2021-10-12 17:42:46 +00:00
David Shevitz 44f3eeb32d docs: add redirect from angular.io/guide to angular.io/docs (#43341)
PR Close #43341
2021-10-12 17:41:49 +00:00
Daniel Díaz 631769ca85 docs: fix typo in hierarchical injectors file (#43652)
PR Close #43652
2021-10-12 17:41:25 +00:00
Kristiyan Kostadinov 7396021e4b fix(core): avoid duplicating comments in TestBed teardown migration (#43776)
Currently the TestBed teardown migration is set up in a similar way to all other migrations where we take a `CallExpression`, add a parameter to it, print it, and replace the existing call. The problem is that doing so while preserving the `expression` of the original `CallExpression` can cause comments to be duplicated. This can happen quite frequently, because by default the CLI generates comments before `initTestModule` calls.

To work around it, these changes make the migration more precise by inserting a new parameter or replacing and existing one using string manipulation.

This requires a bit more code, but it's more reliable than the following alternatives:
1. Using `getFullStart` and `getFullWidth` to replace the node. This would work with our current setup, but the problem is that `getFullStart` also includes whitespace and newlines before the leading comment. This can cause us to mess up the user's formatting and figuring out which whitespace to keep and which one to remove is tricky.
2. Recreating the `CallExpression.expression` when constructing the new node. This would also work since it'll drop any existing comments, but the problem is that `CallExpression.expression` can be a wide variety of nodes which we would have to account for. We can't use `getMutableClone`, because it preserves the comments.

Fixes #43739.

PR Close #43776
2021-10-11 17:18:55 +00:00
dario-piotrowicz 6b9045213d refactor(docs-infra): remove tslint from cli systemjs examples (#43746)
remove the deprecated tslint from the examples of type systemjs

note: eslint hasn't be applied and linting has been removed entirely
to follow angular's unopinionated view on linting

PR Close #43746
2021-10-11 17:14:30 +00:00
Renovate Bot 2a67227ab3 build: update dependency jsdom to v18 (#43786)
PR Close #43786
2021-10-11 16:44:47 +00:00
Thomas Turrell-Croft ef1a70fc53 docs: Formalize language describing HttpClient (#43778)
PR Close #43778
2021-10-11 16:43:16 +00:00
Tanguy Nodet bfb2b81556 docs: add missing declaration of CartComponent in tutorial (#43774)
PR Close #43774
2021-10-11 16:42:36 +00:00
Paul Gschwendtner bc36814f0d build: update karma-sauce-launcher to latest version with heartbeat to prevent idle timeout (#43659)
Updates the `karma-sauce-launcher` to the latest version that comes with
the heartbeat implemented. Whenever we create an instance of a browser
in Saucelabs, we need to send a Selenium command every X seconds as otherwise
Saucelabs will terminate the session due to it thinking the session is already
unused. This is especially a problem for Karma unit tests as there is no
selenium command at all, except for the initial one loading the Karma site.

The latest version of the launcher has implemented an interval that
dispatches a noop selenium command every X seconds to notify Saucelabs
that the instance is still active.

The current version of the launcher does not do that. This is likely
the source of some disconnects because after 10-13min, the SL browser
is terminated but Karma still waits some minute after realizing the
browser is actually disconnected.

We (the Angular team), contributed to that version in the past since
the heartbeat was very flaky.. and we removed it. With the new version
a lot has changed, the underlying Selenium client has changed so it's
worth trying again with the heartbeat re-implemented; it worked pretty
well so far in the COMP repo).

PR Close #43659
2021-10-11 16:41:28 +00:00
dario-piotrowicz 1869474386 refactor(docs-infra): remove linting from i18n example angular.json (#43747)
remove linting from the i18n angular.json example as that is no longer
present in the boilerplace angular.json (and the two should be kept in
sync)

note: the linting was removed from the boilerplate angular.json file in PR #43592

PR Close #43747
2021-10-08 20:42:01 +00:00
Doug Parker 978ac81af5 docs: update CSP section to mention Angular's minimum requirements (#43553)
Closes angular/angular-cli#21711.
Refs #6361, #37631.

PR Close #43553
2021-10-08 20:40:54 +00:00
George Kalpakas 7778cb3680 fix(docs-infra): ensure SwUpdatesService is instantiated (#43766)
In 305d05545a, we accidentally stopped
instantiating the `SwUpdatesService` service, which meant that we were
no longer subscribing to ServiceWorker update events and proactively
checking for updates. We would still gets updates, because the
ServiceWorker automatically checks on each navigation request and when a
new ServiceWorker instance is created, but we would not proactively
fetch updates and also miss `unrecoverable` errors.

This commit fixes this by exposing an `enable()` method from
`SwUpdatesService`, which has to be explicitly called for the service to
be enabled, and ensures that the method is called when `AppComponent` is
initialized.
The commit also gets rid of the `SwUpdatesModule` (whose only purpose
was to provide `SwUpdatesService`) in favor of using `providedIn`.

Fixes #43695

PR Close #43766
2021-10-08 20:39:46 +00:00
markostanimirovic af11d3b721 docs: fix forms in template examples (#43772)
PR Close #43772
2021-10-08 20:39:13 +00:00
George Kalpakas a64adabf65 fix(docs-infra): avoid prepending version info to error messages twice (#43767)
Previously, we used to prepend version info to error messages by
updating their `message` property and their `stack` property. However,
due to the fact that on some browsers `error.stack` is lazily computed
based on `error.message` the first time the `stack` property is
accessed, this resulted in prepending the version info twice.

This commit ensures that the version info is only prepended to
`error.stack` once to avoid unnecessary repetition in error messages.

PR Close #43767
2021-10-08 20:17:59 +00:00
George Kalpakas e2bf4e442a ci: avoid testing angular.io against RxJS v7 twice (#43767)
Previously, we used to run the angular.io unit tests against both RxJS
v6 (which was the version specified in `package.json`) and RxJS v7 on
CI, as a way to guard against future regressions with RxJS v7.

Now that `package.json` has been updated to RxJS v7, there is no reason
to explicitly re-run the unit test against RxJS v7 on CI, so this commit
removes the corresponding steps.

PR Close #43767
2021-10-08 20:17:59 +00:00
George Kalpakas 6194696340 fix(docs-infra): fix Sass rule resulting in invalid CSS (#43767)
The way the Sass rule was defined previously resulted in invalid CSS of
the form:
```css
table > thead > { ... }
```

This, in turn, resulted in a build-time warning:
```
Warning:  > styles.9a5a35b070498c08.css:3079:14: warning: Unexpected "{"
    3079 │ table thead > {
         ╵               ^
```

This commit fixes the affected rule (mostly to avoid the warning,
because this change doesn't seem to have any visual difference). It also
fixes other rules that were currently not affected (because they only
had nested rules and no direct styles), but were susceptible to being
affected in the future.

PR Close #43767
2021-10-08 20:17:59 +00:00
George Kalpakas d049a61f2a docs: use correct service name when creating error handler in http example (#43767)
PR Close #43767
2021-10-08 20:17:59 +00:00
Joey Perrott 7e858f362c build: update to latest @angular/dev-infra-private (#43785)
Update to the latest version of the dev infra packages to allow for merging deprecations during the feature
freeze period.

PR Close #43785
2021-10-08 20:15:36 +00:00
Alan Agius 747553dd68 docs: deprecate ViewEngine-based renderModuleFactory (#43757)
DEPRECATED:

The `renderModuleFactory` symbol in `@angular/platform-server` is no longer necessary as of Angular v13.

The `renderModuleFactory` calls can be replaced with `renderModule`.

PR Close #43757
2021-10-07 16:47:54 -07:00
Renovate Bot 06a87c4a65 build: update all non-major dependencies (#43760)
PR Close #43760
2021-10-07 20:56:11 +00:00
hchiam f8ae6ff08e docs(docs-infra): fix a11y of external links (#43725)
prevent screen readers from falsely announcing "open_in_new" since they may not actually open new tabs/windows but simply send the current page to a domain outside angular.io

Fixes #43512

PR Close #43725
2021-10-07 20:55:24 +00:00
Andrew Scott aef18bcbd6 release: cut the v13.0.0-next.15 release (#43769) 2021-10-07 12:08:50 -07:00
Dylan Hunn 325fafad70 release: cut the v13.0.0-next.14 release (#43751) (#43768)
PR Close #43751

PR Close #43768
2021-10-07 19:03:42 +00:00
Paul Gschwendtner d977701a43 feat(bazel): allow for custom conditions to be set in ng_package targets (#43764)
The APF v13 `ng_package` rule will generate the `exports` field if not
set. Currently it allows for additional subpath entries to be configured
manually. The packager does not allow for custom conditions in subpath
exports which are auto-generated.

This is sometimes useful and necessary though. e.g. in Angular Material,
we also need to expose the index Sass file through a `sass` conditional
that the Webpack Sass loader will pick up. For this, the packager needs
to support manual additional conditions (as long as they do not
conflict).

PR Close #43764
2021-10-07 16:50:50 +00:00
521 changed files with 12253 additions and 33465 deletions
+2 -3
View File
@@ -84,9 +84,8 @@ query --deleted_packages=integration/bazel,integration/bazel/src,integration/baz
################################
# Temporary Settings for Ivy #
################################
# To determine if the compiler used should be Ivy instead of ViewEngine, one can use `--config=ivy`
# on any bazel target. This is a temporary flag until codebase is permanently switched to Ivy.
build --define=angular_ivy_enabled=False
# Set the default compiler used for bazel builds to be Ivy.
build --define=angular_ivy_enabled=True
build:view-engine --define=angular_ivy_enabled=False
build:ivy --define=angular_ivy_enabled=True
+37 -154
View File
@@ -24,19 +24,19 @@ version: 2.1
# **NOTE 2 **: If you change the cache key prefix, also sync the cache_key_fallback to match.
# **NOTE 3 **: Keep the static part of the cache key as prefix to enable correct fallbacks.
# See https://circleci.com/docs/2.0/caching/#restoring-cache for how prefixes work in CircleCI.
var_3: &cache_key v5-angular-node-14-{{ checksum "month.txt" }}-{{ checksum ".bazelversion" }}-{{ checksum "yarn.lock" }}-{{ checksum "WORKSPACE" }}-{{ checksum "aio/yarn.lock" }}
var_3: &cache_key v6-angular-node-14-{{ checksum "month.txt" }}-{{ checksum ".bazelversion" }}-{{ checksum "yarn.lock" }}-{{ checksum "WORKSPACE" }}-{{ checksum "aio/yarn.lock" }}
# We invalidate the cache if the Bazel version changes because otherwise the `bazelisk` cache
# folder will contain all previously used versions and ultimately cause the cache restoring to
# be slower due to its growing size.
var_4: &cache_key_fallback v5-angular-node-14-{{ checksum "month.txt" }}-{{ checksum ".bazelversion" }}
var_4: &cache_key_fallback v6-angular-node-14-{{ checksum "month.txt" }}-{{ checksum ".bazelversion" }}
# Windows needs its own cache key because binaries in node_modules are different.
var_3_win: &cache_key_win v5-angular-win-node-14-{{ checksum "month.txt" }}-{{ checksum ".bazelversion" }}-{{ checksum "yarn.lock" }}-{{ checksum "WORKSPACE" }}-{{ checksum "aio/yarn.lock" }}
var_4_win: &cache_key_win_fallback v5-angular-win-node-14-{{ checksum "month.txt" }}-{{ checksum ".bazelversion" }}
var_3_win: &cache_key_win v6-angular-win-node-14-{{ checksum "month.txt" }}-{{ checksum ".bazelversion" }}-{{ checksum "yarn.lock" }}-{{ checksum "WORKSPACE" }}-{{ checksum "aio/yarn.lock" }}
var_4_win: &cache_key_win_fallback v6-angular-win-node-14-{{ checksum "month.txt" }}-{{ checksum ".bazelversion" }}
# Cache key for the `components-repo-unit-tests` job. **Note** when updating the SHA in the
# cache keys also update the SHA for the "COMPONENTS_REPO_COMMIT" environment variable.
var_5: &components_repo_unit_tests_cache_key v1-angular-components-{{ checksum "month.txt" }}-db18b4093f23ae5c0ef76f6a9699c670ee5d55f7
var_5: &components_repo_unit_tests_cache_key v1-angular-components-{{ checksum "month.txt" }}-83da73fb621720fbe801d3a503d50fd82b3da0c8
var_6: &components_repo_unit_tests_cache_key_fallback v1-angular-components-{{ checksum "month.txt" }}
# Workspace initially persisted by the `setup` job, and then enhanced by `build-npm-packages`.
@@ -86,7 +86,17 @@ executors:
type: string
default: medium
docker:
- image: circleci/node:14.16.1@sha256:951e12268fe692615bfd155c327bd910e10c99db98404badd03879f984c32b31
- image: cimg/node:14.17.6@sha256:589b5e494173bfb48923fa8d29b010b4d17079ac98d08de95dd4a78e57f5aa0b
resource_class: << parameters.resource_class >>
working_directory: ~/ng
test-browser-executor:
parameters:
resource_class:
type: string
default: medium
docker:
- image: cimg/node:14.17.6-browsers@sha256:aa6d08a04d13dd8aa18ae94be70a703c14dde0e99ea572e885e548f47f95eaa9
resource_class: << parameters.resource_class >>
working_directory: ~/ng
@@ -118,22 +128,6 @@ commands:
- attach_workspace:
at: *workspace_location
# Install shared libs used by Chrome that is either provisioned by
# rules_webtesting or by puppeteer.
install_chrome_libs:
description: Install shared Chrome libs
steps:
- run:
name: Install shared Chrome libs
command: |
sudo apt-get update
# Install GTK+ graphical user interface (libgtk-3-0), advanced linux sound architecture (libasound2)
# and network security service libraries (libnss3) & X11 Screen Saver extension library (libssx1)
# which are dependencies of chrome & needed for karma & protractor headless chrome tests.
# This is a very small install which takes around 7s in comparing to using the full
# circleci/node:x.x.x-browsers image.
sudo apt-get -y install libgtk-3-0 libasound2 libnss3 libxss1
# Install java runtime which is required by some integration tests such as
# //integration:hello_world__closure_test, //integration:i18n_test and
# //integration:ng_elements_test to run the closure compiler
@@ -298,7 +292,7 @@ jobs:
test:
executor:
name: default-executor
name: test-browser-executor
# Now that large integration tests are running locally in parallel (they can't run on RBE yet
# as they require network access for yarn install), this test is running out of memory
# consistently with the xlarge machine.
@@ -307,28 +301,13 @@ jobs:
steps:
- custom_attach_workspace
- init_environment
- install_chrome_libs
- install_java
- run:
command: yarn bazel test //... --build_tag_filters=-ivy-only --test_tag_filters=-ivy-only
# We need to explicitly specify the --symlink_prefix option because otherwise we would
# not be able to easily find the output bin directory when uploading artifacts for size
# measurements.
command: yarn test --symlink_prefix=dist/ //...
no_output_timeout: 20m
# Temporary job to test what will happen when we flip the Ivy flag to true
test_ivy_aot:
executor:
name: default-executor
resource_class: xlarge
steps:
- custom_attach_workspace
- init_environment
- install_chrome_libs
# We need to explicitly specify the --symlink_prefix option because otherwise we would
# not be able to easily find the output bin directory when uploading artifacts for size
# measurements.
- run:
command: yarn test-ivy-aot //... --symlink_prefix=dist/
no_output_timeout: 20m
# Publish bundle artifacts which will be used to calculate the size change. **Note**: Make
# sure that the size plugin from the Angular robot fetches the artifacts from this CircleCI
# job (see .github/angular-robot.yml). Additionally any artifacts need to be stored with the
@@ -349,7 +328,7 @@ jobs:
destination: core/todo/bundle.br
# NOTE: This is currently limited to master builds only. See the `monitoring` configuration.
saucelabs_view_engine:
saucelabs:
executor:
name: default-executor
# In order to avoid the bottleneck of having a slow host machine, we acquire a better
@@ -361,47 +340,22 @@ jobs:
- init_environment
- init_saucelabs_environment
- run:
name: Run Bazel tests on Saucelabs with ViewEngine
name: Run Bazel tests on Saucelabs
# See /tools/saucelabs/README.md for more info
command: |
yarn bazel run //tools/saucelabs:sauce_service_setup
TESTS=$(./node_modules/.bin/bazelisk query --output label '(kind(karma_web_test, ...) intersect attr("tags", "saucelabs", ...)) except attr("tags", "ivy-only", ...) except attr("tags", "fixme-saucelabs-ve", ...)')
TESTS=$(./node_modules/.bin/bazelisk query --output label '(kind(karma_web_test, ...) intersect attr("tags", "saucelabs", ...)) except attr("tags", "view-engine-only", ...) except attr("tags", "fixme-saucelabs", ...)')
yarn bazel test --config=saucelabs ${TESTS}
yarn bazel run //tools/saucelabs:sauce_service_stop
no_output_timeout: 40m
- notify_webhook_on_fail:
webhook_url_env_var: SLACK_DEV_INFRA_CI_FAILURES_WEBHOOK_URL
# NOTE: This is currently limited to master builds only. See the `monitoring` configuration.
saucelabs_ivy:
executor:
name: default-executor
# In order to avoid the bottleneck of having a slow host machine, we acquire a better
# container for this job. This is necessary because we launch a lot of browsers concurrently
# and therefore the tunnel and Karma need to process a lot of file requests and tests.
resource_class: xlarge
steps:
- custom_attach_workspace
- init_environment
- init_saucelabs_environment
- run:
name: Run Bazel tests on Saucelabs with Ivy
# See /tools/saucelabs/README.md for more info
command: |
yarn bazel run //tools/saucelabs:sauce_service_setup
TESTS=$(./node_modules/.bin/bazelisk query --output label '(kind(karma_web_test, ...) intersect attr("tags", "saucelabs", ...)) except attr("tags", "no-ivy-aot", ...) except attr("tags", "fixme-saucelabs-ivy", ...)')
yarn bazel test --config=saucelabs --config=ivy ${TESTS}
yarn bazel run //tools/saucelabs:sauce_service_stop
no_output_timeout: 40m
- notify_webhook_on_fail:
webhook_url_env_var: SLACK_DEV_INFRA_CI_FAILURES_WEBHOOK_URL
test_aio:
executor: default-executor
executor: test-browser-executor
steps:
- custom_attach_workspace
- init_environment
- install_chrome_libs
# Build aio
- run: yarn --cwd aio build --progress=false
# Lint the code
@@ -420,23 +374,19 @@ jobs:
- run: yarn --cwd aio redirects-test
deploy_aio:
executor: default-executor
executor: test-browser-executor
steps:
- custom_attach_workspace
- init_environment
- install_chrome_libs
# Deploy angular.io to production (if necessary)
- run: setPublicVar_CI_STABLE_BRANCH
- run: yarn --cwd aio deploy-production
test_aio_local:
executor: default-executor
environment:
RXJS_VERSION_7: '7.4.0'
executor: test-browser-executor
steps:
- custom_attach_workspace
- init_environment
- install_chrome_libs
# Build aio (with local Angular packages)
- run: yarn --cwd aio build-local-ci
# Run unit tests
@@ -447,17 +397,6 @@ jobs:
- run: yarn --cwd aio test-pwa-score-localhost $CI_AIO_MIN_PWA_SCORE
# Check the bundle sizes.
- run: yarn --cwd aio payload-size aio-local
# Run tests with RxJS v7.
- run: yarn --cwd aio add rxjs@$RXJS_VERSION_7 && yarn --cwd aio aio-use-local
- run:
name: Ensure we use RxJS v7
command: >-
node --eval "
const expected = process.env.RXJS_VERSION_7;
const actual = require('./aio/node_modules/rxjs/package.json').version;
assert(actual === expected, 'Expected RxJS v' + expected + ', but found v' + actual + '.');
"
- run: yarn --cwd aio test --progress=false --watch=false
test_aio_tools:
executor: default-executor
@@ -473,33 +412,18 @@ jobs:
test_docs_examples:
executor:
name: default-executor
name: test-browser-executor
resource_class: xlarge
parallelism: 5
environment:
RXJS_VERSION_7: '7.4.0'
steps:
- custom_attach_workspace
- init_environment
- install_chrome_libs
# Install aio
- run: yarn --cwd aio install --frozen-lockfile --non-interactive --cache-folder ~/.cache/yarn
# Run examples tests. The "CIRCLE_NODE_INDEX" will be set if "parallelism" is enabled.
# Since the parallelism is set to "5", there will be five parallel CircleCI containers.
# with either "0", "1", etc as node index. This can be passed to the "--shard" argument.
- run: yarn --cwd aio example-e2e --setup --local --cliSpecsConcurrency=5 --shard=${CIRCLE_NODE_INDEX}/${CIRCLE_NODE_TOTAL}
# Run tests with RxJS v7.
- run: yarn --cwd aio/tools/examples/shared add rxjs@$RXJS_VERSION_7 && yarn --cwd aio example-use-local && yarn --cwd aio boilerplate:add
- run:
name: Ensure we use RxJS v7
command: >-
node --eval "
const expected = process.env.RXJS_VERSION_7;
const actual = require('./aio/tools/examples/shared/node_modules/rxjs/package.json').version;
assert(actual === expected, 'Expected RxJS v' + expected + ', but found v' + actual + '.');
"
# Exclude some examples that are not yet compatible with v7.
- run: yarn --cwd aio example-e2e --cliSpecsConcurrency=5 --shard=${CIRCLE_NODE_INDEX}/${CIRCLE_NODE_TOTAL} --exclude=practical-observable-usage --exclude=upgrade-module --exclude=upgrade-phonecat
# This job should only be run on PR builds, where `CI_PULL_REQUEST` is not `false`.
aio_preview:
@@ -519,11 +443,10 @@ jobs:
# This job should only be run on PR builds, where `CI_PULL_REQUEST` is not `false`.
test_aio_preview:
executor: default-executor
executor: test-browser-executor
steps:
- custom_attach_workspace
- init_environment
- install_chrome_libs
- run: yarn --cwd aio install --frozen-lockfile --non-interactive --cache-folder ~/.cache/yarn
- run:
name: Wait for preview and run tests
@@ -535,8 +458,6 @@ jobs:
# the bazel packages more than once. Even though we have a remote cache, these jobs will
# typically run in parallel so up-to-date outputs will not be available at the time the build
# starts.
# Build the view engine npm packages. No new jobs should depend on this.
build-npm-packages:
executor:
name: default-executor
@@ -631,11 +552,10 @@ jobs:
command: yarn node aio/scripts/test-external-urls.js
aio_monitoring_stable:
executor: default-executor
executor: test-browser-executor
steps:
- custom_attach_workspace
- init_environment
- install_chrome_libs
- run: setPublicVar_CI_STABLE_BRANCH
- run:
name: Check out `aio/` and yarn from the stable branch
@@ -654,11 +574,10 @@ jobs:
webhook_url_env_var: SLACK_DEV_INFRA_CI_FAILURES_WEBHOOK_URL
aio_monitoring_next:
executor: default-executor
executor: test-browser-executor
steps:
- custom_attach_workspace
- init_environment
- install_chrome_libs
- run:
name: Run tests against https://next.angular.io/
command: ./aio/scripts/test-production.sh https://next.angular.io/ $CI_AIO_MIN_PWA_SCORE
@@ -804,31 +723,13 @@ jobs:
- setup_win
- run:
name: Build all windows CI targets
command: bazel build --build_tag_filters=-ivy-only //packages/compiler-cli/...
command: bazel build --build_tag_filters=-view-engine-only //packages/compiler-cli/...
no_output_timeout: 15m
- run:
name: Test all windows CI targets
command: bazel test --test_tag_filters="-ivy-only,-browser:chromium-local" //packages/compiler-cli/...
command: bazel test --test_tag_filters="-view-engine-only,-browser:chromium-local" //packages/compiler-cli/...
no_output_timeout: 15m
test_ivy_aot_win:
executor: windows-executor
steps:
- setup_win
- run:
name: Build all windows CI targets
command: bazel build --config=ivy --build_tag_filters=-no-ivy-aot,-fixme-ivy-aot //packages/compiler-cli/...
no_output_timeout: 15m
- run:
name: Test all windows CI targets
command: bazel test --config=ivy --test_tag_filters="-no-ivy-aot,-fixme-ivy-aot,-browser:chromium-local" //packages/compiler-cli/... //packages/localize/...
no_output_timeout: 15m
# Save dependencies to use on subsequent runs.
- save_cache:
key: *cache_key_win
paths:
- ~/.cache/yarn
workflows:
version: 2
default_workflow:
@@ -843,9 +744,6 @@ workflows:
- test:
requires:
- setup
- test_ivy_aot:
requires:
- setup
- build-npm-packages:
requires:
- setup
@@ -883,7 +781,6 @@ workflows:
requires:
# Only publish if tests and integration tests pass
- test
- test_ivy_aot
# Only publish if `aio`/`docs` tests using the locally built Angular packages pass
- test_aio_local
- test_docs_examples
@@ -891,20 +788,15 @@ workflows:
# since the publishing script expects the legacy outputs layout.
- build-npm-packages
- legacy-unit-tests-saucelabs
# TODO(devversion): re-enable once the Angular components repo has been updated to deal
# with partial compilation APF v13 package output (i.e. with the linker processing).
#- components-repo-unit-tests:
# requires:
# - build-npm-packages
- components-repo-unit-tests:
requires:
- build-npm-packages
- test_zonejs:
requires:
- setup
- test_win:
requires:
- setup
- test_ivy_aot_win:
requires:
- setup
monitoring:
jobs:
@@ -918,16 +810,7 @@ workflows:
- aio_monitoring_next:
requires:
- setup
- saucelabs_ivy:
# Testing saucelabs via Bazel currently taking longer than the legacy saucelabs job as it
# each karma_web_test target is provisioning and tearing down browsers which is adding
# a lot of overhead. Running once daily on master only to avoid wasting resources and
# slowing down CI for PRs.
# TODO: Run this job on all branches (including PRs) once karma_web_test targets can
# share provisioned browsers and we can remove the legacy saucelabs job.
requires:
- setup
- saucelabs_view_engine:
- saucelabs:
# Testing saucelabs via Bazel currently taking longer than the legacy saucelabs job as it
# each karma_web_test target is provisioning and tearing down browsers which is adding
# a lot of overhead. Running once daily on master only to avoid wasting resources and
+1 -1
View File
@@ -74,7 +74,7 @@ setPublicVar COMPONENTS_REPO_TMP_DIR "/tmp/angular-components-repo"
setPublicVar COMPONENTS_REPO_URL "https://github.com/angular/components.git"
setPublicVar COMPONENTS_REPO_BRANCH "master"
# **NOTE**: When updating the commit SHA, also update the cache key in the CircleCI `config.yml`.
setPublicVar COMPONENTS_REPO_COMMIT "db18b4093f23ae5c0ef76f6a9699c670ee5d55f7"
setPublicVar COMPONENTS_REPO_COMMIT "83da73fb621720fbe801d3a503d50fd82b3da0c8"
####################################################################################################
+2 -2
View File
@@ -41,8 +41,8 @@ copy .circleci\bazel.windows.rc ${Env:USERPROFILE}\.bazelrc
####################################################################################################
# Install specific version of node.
####################################################################################################
nvm install 14.16.1
nvm use 14.16.1
nvm install 14.17.6
nvm use 14.17.6
# These Bazel prereqs aren't needed because the CircleCI image already includes them.
# choco install yarn --version 1.16.0 --no-progress
+1 -1
View File
@@ -1,7 +1,7 @@
# Image metadata and config.
# Ideally, the Node.js version should match what we use on CI.
# See `executors > default-executor` in `.circleci/config.yml`.
FROM circleci/node:14-browsers
FROM cimg/node:14-browsers
LABEL name="Angular dev environment" \
@@ -1,6 +0,0 @@
---
name: Security Issue Disclosure
about: Report a security issue in Angular Framework, Material, or CLI
---
Please read https://angular.io/guide/security#report-issues on how to disclose security related issues.
@@ -1,11 +0,0 @@
---
name: "Support Request"
about: Questions and requests for support
---
Please do not file questions or support requests on the GitHub issues tracker.
You can get your questions answered using other communication channels. Please see:
https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question
Thank you!
-8
View File
@@ -1,8 +0,0 @@
---
name: "Angular CLI"
about: Issues and feature requests for Angular CLI
---
Please file any Angular CLI issues at: https://github.com/angular/angular-cli/issues/new
For the time being, we keep Angular CLI issues in a separate repository.
@@ -1,8 +0,0 @@
---
name: "Angular Components"
about: Issues and feature requests for Angular Components
---
Please file any Angular Components issues at: https://github.com/angular/components/issues/new
For the time being, we keep Angular Components issues in a separate repository.
+14
View File
@@ -0,0 +1,14 @@
blank_issues_enabled: false
contact_links:
- name: Security issue disclosure
url: https://angular.io/guide/security#report-issues
about: Report a security issue in Angular Framework, CDK, Material, or CLI
- name: Angular CLI
url: https://github.com/angular/angular/issues/new/choose
about: Issues and feature requests for Angular CLI
- name: Angular Material and Components Development Kit (CDK)
url: https://github.com/angular/components/issues/new/choose
about: Issues and feature requests for Angular Material
- name: Support Request
url: https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question
about: Questions and requests for support
+1 -1
View File
@@ -4,7 +4,7 @@
size:
disabled: false
maxSizeIncrease: 2000
circleCiStatusName: 'ci/circleci: test_ivy_aot'
circleCiStatusName: 'ci/circleci: test'
# options for the merge plugin
merge:
+2 -2
View File
@@ -5,10 +5,10 @@ on:
types: [opened, synchronize, reopened]
jobs:
breaking-changes-label:
labels:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: angular/dev-infra/github-actions/breaking-changes-label@861dc90572784e714aeaa9dfb20ceebeb57cdb07
- uses: angular/dev-infra/github-actions/commit-message-based-labels@7b66fb5dc44b92fb4ecbd6a7d52b67a3e15339eb
with:
angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }}
+1 -1
View File
@@ -10,6 +10,6 @@ jobs:
if: github.repository == 'angular/angular'
runs-on: ubuntu-latest
steps:
- uses: angular/dev-infra/github-actions/feature-request@f83903fe1ac848407ef81465f66588e5accb6537
- uses: angular/dev-infra/github-actions/feature-request@7b66fb5dc44b92fb4ecbd6a7d52b67a3e15339eb
with:
angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }}
+1 -1
View File
@@ -10,6 +10,6 @@ jobs:
if: github.repository == 'angular/angular'
runs-on: ubuntu-latest
steps:
- uses: angular/dev-infra/github-actions/lock-closed@7679cff885633cd33bf5ac7922a5304e8971a5a6
- uses: angular/dev-infra/github-actions/lock-closed@7b66fb5dc44b92fb4ecbd6a7d52b67a3e15339eb
with:
lock-bot-key: ${{ secrets.LOCK_BOT_PRIVATE_KEY }}
+1 -1
View File
@@ -1 +1 @@
14.16.1
14.17.6
+8 -5
View File
@@ -544,7 +544,7 @@ groups:
'packages/compiler-cli/src/extract_i18n.ts',
'packages/localize/**',
'aio/content/guide/i18n-overview.md',
'aio/content/guide/i18n-common.md',
'aio/content/guide/i18n-common-overview.md',
'aio/content/guide/i18n-common-add-package.md',
'aio/content/guide/i18n-common-locale-id.md',
'aio/content/guide/i18n-common-format-data-locale.md',
@@ -553,8 +553,8 @@ groups:
'aio/content/guide/i18n-common-merge.md',
'aio/content/guide/i18n-common-deploy.md',
'aio/content/guide/i18n-example.md',
'aio/content/guide/i18n-optional.md',
'aio/content/guide/i18n-optional-manual-source-locale.md',
'aio/content/guide/i18n-optional-overview.md',
'aio/content/guide/i18n-optional-manual-runtime-locale.md',
'aio/content/guide/i18n-optional-import-global-variants.md',
'aio/content/guide/i18n-optional-manage-marked-text.md',
'aio/content/examples/i18n/**'
@@ -983,6 +983,7 @@ groups:
'aio/content/guide/updating.md',
'aio/content/guide/deprecations.md',
'aio/content/guide/migration-legacy-message-id.md',
'aio/content/examples/deprecation-guide/**',
'aio/content/guide/migration-renderer.md',
'aio/content/guide/migration-undecorated-classes.md',
'aio/content/guide/migration-dynamic-flag.md',
@@ -990,7 +991,7 @@ groups:
'aio/content/guide/migration-localize.md',
'aio/content/guide/migration-module-with-providers.md',
'aio/content/guide/static-query-migration.md',
'aio/content/guide/updating-to-version-12.md',
'aio/content/guide/update-to-latest-version.md',
'aio/content/guide/ivy-compatibility.md',
'aio/content/guide/ivy-compatibility-examples.md'
])
@@ -1090,7 +1091,8 @@ groups:
contains_any_globs(files, [
'aio/content/guide/creating-libraries.md',
'aio/content/guide/libraries.md',
'aio/content/guide/using-libraries.md'
'aio/content/guide/using-libraries.md',
'aio/content/guide/angular-package-format.md'
])
reviewers:
users:
@@ -1222,6 +1224,7 @@ groups:
contains_any_globs(files.exclude("goldens/public-api/manage.js"), [
'goldens/public-api/**',
'docs/NAMING.md',
'aio/content/guide/angular-package-format.md',
'aio/content/errors/*.md',
'aio/content/guide/glossary.md',
'aio/content/guide/styleguide.md',
+2 -2
View File
@@ -12,9 +12,9 @@ To use the recommended configurations follow the steps below:
- copy (or link) `.vscode/recommended-tasks.json` to `.vscode/tasks.json`
- restart the editor
If you already have your custom workspace settings you should instead manually merge the file contents.
If you already have your custom workspace settings, you should instead manually merge the file contents.
This isn't an automatic process so you will need to repeat it when settings are updated.
This isn't an automatic process, so you will need to repeat it when settings are updated.
To see the recommended extensions select "Extensions: Show Recommended Extensions" in the [Command Palette](https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette).
-3
View File
@@ -39,7 +39,6 @@
"program": "${workspaceFolder}/node_modules/.bin/bazelisk",
"args": [
"test",
"--config=ivy",
"packages/core/test/acceptance",
"--config=debug"
],
@@ -57,7 +56,6 @@
"program": "${workspaceFolder}/node_modules/.bin/bazelisk",
"args": [
"test",
"--config=ivy",
"packages/core/test/render3",
"--config=debug"
],
@@ -75,7 +73,6 @@
"program": "${workspaceFolder}/node_modules/.bin/bazelisk",
"args": [
"test",
"--config=ivy",
"packages/core/test",
"--config=debug"
],
-4
View File
@@ -9,7 +9,6 @@
"command": "${workspaceFolder}/node_modules/.bin/bazelisk",
"args": [
"test",
"--config=ivy",
"packages/core/test",
"packages/core/test/acceptance",
"packages/core/test/render3",
@@ -42,7 +41,6 @@
"command": "${workspaceFolder}/node_modules/.bin/bazelisk",
"args": [
"test",
"--config=ivy",
"packages/core/test/acceptance",
],
"group": "test",
@@ -71,7 +69,6 @@
"command": "${workspaceFolder}/node_modules/.bin/bazelisk",
"args": [
"test",
"--config=ivy",
"packages/core/test",
],
"group": "test",
@@ -100,7 +97,6 @@
"command": "${workspaceFolder}/node_modules/.bin/bazelisk",
"args": [
"test",
"--config=ivy",
"packages/core/test/render3",
],
"group": "test",
+411 -184
View File
File diff suppressed because it is too large Load Diff
+3 -3
View File
@@ -58,9 +58,9 @@ If you would like to *implement* a new feature, please consider the size of the
### <a name="submit-issue"></a> Submitting an Issue
Before you submit an issue, please search the issue tracker, maybe an issue for your problem already exists and the discussion might inform you of workarounds readily available.
Before you submit an issue, please search the issue tracker. An issue for your problem might already exist and the discussion might inform you of workarounds readily available.
We want to fix all the issues as soon as possible, but before fixing a bug we need to reproduce and confirm it.
We want to fix all the issues as soon as possible, but before fixing a bug, we need to reproduce and confirm it.
In order to reproduce bugs, we require that you provide a minimal reproduction.
Having a minimal reproducible scenario gives us a wealth of important information without going back and forth to you with additional questions.
@@ -259,7 +259,7 @@ The `<type>` and `<summary>` fields are mandatory, the `(<scope>)` field is opti
Must be one of the following:
* **build**: Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm)
* **ci**: Changes to our CI configuration files and scripts (example scopes: Circle, BrowserStack, SauceLabs)
* **ci**: Changes to our CI configuration files and scripts (examples: CircleCi, SauceLabs)
* **docs**: Documentation only changes
* **feat**: A new feature
* **fix**: A bug fix
+4 -10
View File
@@ -8,8 +8,8 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
# Fetch rules_nodejs so we can install our npm dependencies
http_archive(
name = "build_bazel_rules_nodejs",
sha256 = "3635797a96c7bfcd0d265dacd722a07335e64d6ded9834af8d3f1b7ba5a25bba",
urls = ["https://github.com/bazelbuild/rules_nodejs/releases/download/4.3.0/rules_nodejs-4.3.0.tar.gz"],
sha256 = "4501158976b9da216295ac65d872b1be51e3eeb805273e68c516d2eb36ae1fbb",
urls = ["https://github.com/bazelbuild/rules_nodejs/releases/download/4.4.1/rules_nodejs-4.4.1.tar.gz"],
)
# The PKG rules are needed to build tar packages for integration tests. The builtin
@@ -32,7 +32,7 @@ check_rules_nodejs_version(minimum_version_string = "2.2.0")
# Setup the Node.js toolchain
node_repositories(
node_version = "14.16.1",
node_version = "14.17.6",
package_json = ["//:package.json"],
)
@@ -71,13 +71,7 @@ load("//packages/common/locales/generate-locales-tool:cldr-data.bzl", "cldr_data
cldr_data_repository(
name = "cldr_data",
# Since we use the Github archives for CLDR 37, we need to specify a path
# to the available locales. This wouldn't be needed with CLDR 39 as that
# comes with an official JSON archive not containing a version suffix.
available_locales_path = "cldr-core-37.0.0/availableLocales.json",
urls = {
"https://github.com/unicode-cldr/cldr-core/archive/37.0.0.zip": "32b5c49c3874aa342b90412c207b42e7aefb2435295891fb714c34ce58b3c706",
"https://github.com/unicode-cldr/cldr-dates-full/archive/37.0.0.zip": "e1c410dd8ad7d75df4a5393efaf5d28f0d56c0fa126c5d66e171a3f21a988a1e",
"https://github.com/unicode-cldr/cldr-numbers-full/archive/37.0.0.zip": "a921b90cf7f436e63fbdd55880f96e39a203acd9e174b0ceafa20a02c242a12e",
"https://github.com/unicode-org/cldr-json/releases/download/39.0.0/cldr-39.0.0-json-full.zip": "a631764b6bb7967fab8cc351aff3ffa3f430a23646899976dd9d65801446def6",
},
)
@@ -6,4 +6,4 @@ TODO (gkalpak): Add docs. Mention:
Relevant files: `aio/aio-builds-setup/scripts/test.sh`
- Deploying from CI.
Relevant files: `.circleci/config.yml`, `scripts/ci/deploy.sh`, `aio/scripts/build-artifacts.sh`,
`aio/scripts/deploy-to-firebase.js`
`aio/scripts/deploy-to-firebase/index.mjs`
+75
View File
@@ -0,0 +1,75 @@
# Persistent disk cache
Angular CLI saves a number of cachable operations on disk by default.
When you re-run the same build, the build system restores the state of the previous build and re-uses previously performed operations, which decreases the time taken to build and test your applications and libraries.
To amend the default cache settings, add the `cli.cache` object to your [Workspace Configuration](guide/workspace-config).
The object goes under `cli.cache` at the top level of the file, outside the `projects` sections.
```json
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"cli": {
"cache": {
...
}
},
"projects": {}
}
```
For more information, see [cache options](guide/workspace-config#cache-options).
### Enabling and disabling the cache
Caching is enabled by default. To disable caching run the following command:
```bash
ng config cli.cache.enabled false
```
To re-enable caching, set `cli.cache.enabled` to `true`.
### Cache environments
By default, disk cache is only enabled for local environments.
To enable caching for all environments, run the following command:
```bash
ng config cli.cache.environment all
```
For more information, see `environment` in [cache options](guide/workspace-config#cache-options).
<div class="alert is-helpful">
The Angular CLI checks for the presence and value of the `CI` environment variable to determine in which environment it is running.
</div>
### Cache path
By default, `.angular/cache` is used as a base directory to store cache results. To change this path, run the following command:
```bash
ng config cli.cache.path ".cache/ng"
```
### Clearing the cache
To clear the cache, run one of the following commands.
To clear the cache on Unix-based operating systems:
```bash
rm -rf .angular/cache
```
To clear the cache on Windows:
```bash
rmdir /s /q .angular/cache
```
For more information, see [rm command](https://man7.org/linux/man-pages/man1/rm.1.html) and [rmdir command](https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/rmdir).
+3 -3
View File
@@ -27,7 +27,7 @@ ng config --global cli.analyticsSharing.tracking UA-123456-12
To turn off this feature, run the following command:
<code-example language="sh">
ng config --global --remove cli.analyticsSharing
ng config --global cli.analyticsSharing undefined
</code-example>
## Per user tracking
@@ -36,11 +36,11 @@ You can add a custom user ID to the global configuration, in order to identify u
If that user enables CLI analytics for their own project, your analytics display tracks and labels their individual usage.
<code-example language="sh">
ng config --global cli.analyticsSharing.user SOME_USER_NAME
ng config --global cli.analyticsSharing.uuid SOME_USER_NAME
</code-example>
To generate a new random user ID, run the following command:
<code-example language="sh">
ng config --global cli.analyticsSharing.user ""
ng config --global cli.analyticsSharing.uuid ""
</code-example>
+3 -2
View File
@@ -28,8 +28,6 @@
**/tsconfig.json
**/tsconfig.app.json
**/tsconfig.spec.json
# TODO: remove tslint.json after linting has been removed from systemjs examples
**/tslint.json
**/karma-test-shim.js
**/browser-test-shim.js
**/node_modules
@@ -104,3 +102,6 @@ upgrade-phonecat-3-final/rollup-config.js
#angular-compiler-options
!angular-compiler-options/tsconfig.json
!angular-compiler-options/tsconfig.app.json
# deprecated-example
!deprecation-guide/angular.package.json
@@ -9,6 +9,8 @@
"outDir": "./dist/out-tsc",
"forceConsistentCasingInFileNames": true,
"strict": true,
"noImplicitOverride": true,
"noPropertyAccessFromIndexSignature": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"sourceMap": true,
@@ -20,7 +22,7 @@
"target": "es2017",
"module": "es2020",
"lib": [
"es2018",
"es2020",
"dom"
]
// #docregion angular-compiler-options
@@ -36,7 +36,7 @@ export class AppComponent {
// #docregion prepare-router-outlet
prepareRoute(outlet: RouterOutlet) {
return outlet?.activatedRouteData?.animation;
return outlet?.activatedRouteData?.['animation'];
}
// #enddocregion prepare-router-outlet
@@ -10,9 +10,9 @@ import { LoggerService } from './logger.service';
})
export class DateLoggerService extends LoggerService
{
logInfo(msg: any) { super.logInfo(stamp(msg)); }
logDebug(msg: any) { super.logInfo(stamp(msg)); }
logError(msg: any) { super.logError(stamp(msg)); }
override logInfo(msg: any) { super.logInfo(stamp(msg)); }
override logDebug(msg: any) { super.logInfo(stamp(msg)); }
override logError(msg: any) { super.logError(stamp(msg)); }
}
function stamp(msg: any) { return msg + ' at ' + new Date(); }
@@ -153,7 +153,7 @@ export class BethComponent implements Parent {
export class AlexComponent extends Base
// #enddocregion alex-class-signature
{
name = 'Alex';
override name = 'Alex';
}
// #enddocregion alex-1
@@ -40,7 +40,7 @@ export class SortedHeroesComponent extends HeroesBaseComponent {
super(heroService);
}
protected afterGetHeroes() {
protected override afterGetHeroes() {
this.heroes = this.heroes.sort((h1, h2) => {
return h1.name < h2.name ? -1 :
(h1.name > h2.name ? 1 : 0);
@@ -25,8 +25,8 @@ export function superCar() {
}
/////////// example 3 //////////
class MockEngine extends Engine { cylinders = 8; }
class MockTires extends Tires { make = 'YokoGoodStone'; }
class MockEngine extends Engine { override cylinders = 8; }
class MockTires extends Tires { override make = 'YokoGoodStone'; }
export function testCar() {
// Test car with 8 cylinders and YokoGoodStone tires.
@@ -75,7 +75,7 @@ export class Provider4Component {
export class EvenBetterLogger extends Logger {
constructor(private userService: UserService) { super(); }
log(message: string) {
override log(message: string) {
const name = this.userService.user.name;
super.log(`Message to ${name}: ${message}`);
}
@@ -0,0 +1,20 @@
import { AppPage } from './app.po';
import { browser, logging } from 'protractor';
describe('workspace-project App', () => {
let page: AppPage;
beforeEach(() => {
page = new AppPage();
});
// Add your e2e tests here
afterEach(async () => {
// Assert that there are no errors emitted from the browser
const logs = await browser.manage().logs().get(logging.Type.BROWSER);
expect(logs).not.toContain(jasmine.objectContaining({
level: logging.Level.SEVERE,
} as logging.Entry));
});
});
@@ -0,0 +1,6 @@
<select>
<!--#docregion two-way-template-deprecated-->
<option *ngFor="let optionName of options" [(value)]="optionName"></option>
<!--#enddocregion two-way-template-deprecated-->
</select>
@@ -0,0 +1,25 @@
<h1>Deprecation</h1>
<!--#docregion deprecated-example-->
<input [formControl]="control" [(ngModel)]="value">
<!--#enddocregion deprecated-example-->
<!--#docregion reactive-form-example-->
<input [formControl]="control">
<!--#enddocregion reactive-form-example-->
<!--#docregion template-driven-form-example-->
<input [(ngModel)]="value">
<!--#enddocregion template-driven-form-example-->
<select>
<!--#docregion valid-template-bind-->
<option *ngFor="let optionName of options" [value]="optionName"></option>
<!--#enddocregion valid-template-bind-->
</select>
@@ -0,0 +1,20 @@
import { TestBed } from '@angular/core/testing';
import { AppComponent } from './app.component';
describe('AppComponent', () => {
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [
AppComponent
],
}).compileComponents();
});
it('should create the app', () => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.componentInstance;
expect(app).toBeTruthy();
});
// Add your unit tests here
});
@@ -0,0 +1,60 @@
// #docplaster
import { Component, ContentChild, Injector, Input, OnInit, StaticProvider, TemplateRef } from '@angular/core';
import { ReflectiveInjector } from '@angular/core';
import {
FormControl,
} from '@angular/forms';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
title = 'example';
value = 'initial value';
control: FormControl = new FormControl('');
options = [
'repeat-value'
];
/*
// #docregion template-with-input-deprecated
@Input() @ContentChild(TemplateRef) tpldeprecated !: TemplateRef<any>;
// #enddocregion template-with-input-deprecated
*/
// #docregion template-with-input
@Input() tpl !: TemplateRef<any>;
@ContentChild(TemplateRef) inlineTemplate !: TemplateRef<any>;
// #enddocregion template-with-input
ngOnInit() {
// #docregion deprecated-example, template-driven-form-example
this.value = 'some value';
// #enddocregion deprecated-example, template-driven-form-example
this.setValue();
}
setValue(): void {
// #docregion reactive-form-example
this.control.setValue('some value');
// #enddocregion reactive-form-example
}
}
class InjectorExample {}
const Provider = [InjectorExample];
const providers: StaticProvider[] = [Provider];
// #docregion reflective-injector-deprecated-example
ReflectiveInjector.resolveAndCreate(providers);
// #enddocregion reflective-injector-deprecated-example
// #docregion static-injector-example
Injector.create({providers});
// #enddocregion static-injector-example
@@ -0,0 +1,75 @@
// #docplaster
import { BrowserModule } from '@angular/platform-browser';
import { ModuleWithProviders, NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { RouterModule, Routes } from '@angular/router';
import { SubmitButtonComponent } from './submit-button/submit-button.component';
// #docregion lazyload-syntax, lazyload-deprecated-syntax
const routes: Routes = [{
path: 'lazy',
// #enddocregion lazyload-deprecated-syntax
// The new import() syntax
loadChildren: () => import('./lazy/lazy.module').then(m => m.LazyModule)
// #enddocregion lazyload-syntax
/*
// #docregion lazyload-deprecated-syntax
// The following string syntax for loadChildren is deprecated
loadChildren: './lazy/lazy.module#LazyModule',
// #enddocregion lazyload-deprecated-syntax
*/
// #docregion lazyload-syntax, lazyload-deprecated-syntax
}];
// #enddocregion lazyload-syntax, lazyload-deprecated-syntax
@NgModule({
declarations: [
AppComponent,
SubmitButtonComponent
],
// #docregion reactive-form-no-warning
imports: [
// #enddocregion reactive-form-no-warning
RouterModule.forChild(routes),
FormsModule,
BrowserModule,
// #docregion reactive-form-no-warning
ReactiveFormsModule.withConfig({warnOnNgModelWithFormControl: 'never'})
],
// #enddocregion reactive-form-no-warning
providers: [],
bootstrap: [AppComponent],
exports: [RouterModule]
})
export class AppModule { }
class SomeModule { }
class SomeConfig { }
// #docplaster ...
// #docregion ModuleWithProvidersGeneric, ModuleWithProvidersNonGeneric
@NgModule({
// #enddocregion ModuleWithProvidersGeneric, ModuleWithProvidersNonGeneric
// #docregion ModuleWithProvidersGeneric, ModuleWithProvidersNonGeneric
})
// #docplaster
export class MyModule {
// #enddocregion ModuleWithProvidersGeneric, ModuleWithProvidersNonGeneric
/*
// #docregion ModuleWithProvidersNonGeneric
static forRoot(config: SomeConfig): ModuleWithProviders {
// #enddocregion ModuleWithProvidersNonGeneric
*/
// #docregion ModuleWithProvidersGeneric
static forRoot(config: SomeConfig): ModuleWithProviders<SomeModule> {
// #docregion ModuleWithProvidersNonGeneric
return {
ngModule: SomeModule,
providers: [
{provide: SomeConfig, useValue: config}
]
};
}
}
// #enddocregion ModuleWithProvidersGeneric, ModuleWithProvidersNonGeneric
@@ -0,0 +1,10 @@
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
const routes: Routes = [];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class LazyRoutingModule { }
@@ -0,0 +1 @@
<p>lazy works!</p>
@@ -0,0 +1,25 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { LazyComponent } from './lazy.component';
describe('LazyComponent', () => {
let component: LazyComponent;
let fixture: ComponentFixture<LazyComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ LazyComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(LazyComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
@@ -0,0 +1,15 @@
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-lazy',
templateUrl: './lazy.component.html',
styleUrls: ['./lazy.component.css']
})
export class LazyComponent implements OnInit {
constructor() { }
ngOnInit(): void {
}
}
@@ -0,0 +1,17 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { LazyRoutingModule } from './lazy-routing.module';
import { LazyComponent } from './lazy.component';
@NgModule({
declarations: [
LazyComponent
],
imports: [
CommonModule,
LazyRoutingModule
]
})
export class LazyModule { }
@@ -0,0 +1 @@
<p>submit-button works!</p>
@@ -0,0 +1,25 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { SubmitButtonComponent } from './submit-button.component';
describe('SubmitButtonComponent', () => {
let component: SubmitButtonComponent;
let fixture: ComponentFixture<SubmitButtonComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ SubmitButtonComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(SubmitButtonComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
@@ -0,0 +1,53 @@
// #docplaster ...
import { Component, Input } from '@angular/core';
// #docregion submitButton, submitButtonNarrow
@Component({
// #enddocregion submitButton, submitButtonNarrow
// #docplaster
selector: 'app-submit-button',
templateUrl: './submit-button.component.html',
styleUrls: ['./submit-button.component.css']
// #docregion submitButton, submitButtonNarrow
})
export class SubmitButtonComponent {
// #enddocregion submitButtonNarrow
private disabledValue = false;
@Input()
get disabled(): boolean {
return this.disabledValue;
}
set disabled(value: boolean|'') {
this.disabledValue = (value === '') || value;
}
}
// #enddocregion submitButton
@Component({
selector: 'app-submit-button-valid',
templateUrl: './submit-button.component.html',
styleUrls: ['./submit-button.component.css']
})
export class SubmitButtonValidComponent {
// tslint:disable: variable-name
// #docregion submitButtonNarrow
static ngAcceptInputType_disabled: boolean|'';
private disabledValue = false;
@Input()
get disabled(): boolean {
return this.disabledValue;
}
// #enddocregion submitButtonNarrow
/*
// #docregion submitButtonNarrow
set disabled(value: boolean) {
this.disabledValue = (value === '') || value;
}
// #enddocregion submitButtonNarrow
*/
// #docregion submitButtonNarrow
}
// #enddocregion submitButtonNarrow
@@ -0,0 +1,13 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Ponyracer</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
<app-root></app-root>
</body>
</html>
@@ -0,0 +1,12 @@
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
import { environment } from './environments/environment';
if (environment.production) {
enableProdMode();
}
platformBrowserDynamic().bootstrapModule(AppModule)
.catch(err => console.error(err));
@@ -0,0 +1,14 @@
{
"description": "Deprecation Guide",
"files": [
"!**/*.d.ts",
"!**/*.js",
"!**/*.[1,2].*"
],
"tags": [
[
"deprecation",
"guide"
]
]
}
@@ -1,5 +1,5 @@
// #docregion
import { Component, Input, OnInit, ViewChild, ComponentFactoryResolver, OnDestroy } from '@angular/core';
import { Component, Input, OnDestroy, OnInit, ViewChild } from '@angular/core';
import { AdDirective } from './ad.directive';
import { AdItem } from './ad-item';
@@ -18,15 +18,12 @@ import { AdComponent } from './ad.component';
})
// #docregion class
export class AdBannerComponent implements OnInit, OnDestroy {
@Input() ads: AdItem[] = [];
currentAdIndex = -1;
@ViewChild(AdDirective, {static: true}) adHost!: AdDirective;
interval: number | undefined;
constructor(private componentFactoryResolver: ComponentFactoryResolver) { }
interval: number|undefined;
ngOnInit() {
this.loadComponent();
@@ -41,12 +38,10 @@ export class AdBannerComponent implements OnInit, OnDestroy {
this.currentAdIndex = (this.currentAdIndex + 1) % this.ads.length;
const adItem = this.ads[this.currentAdIndex];
const componentFactory = this.componentFactoryResolver.resolveComponentFactory(adItem.component);
const viewContainerRef = this.adHost.viewContainerRef;
viewContainerRef.clear();
const componentRef = viewContainerRef.createComponent<AdComponent>(componentFactory);
const componentRef = viewContainerRef.createComponent<AdComponent>(adItem.component);
componentRef.instance.data = adItem.data;
}
@@ -2,5 +2,5 @@
import { QuestionBase } from './question-base';
export class DropdownQuestion extends QuestionBase<string> {
controlType = 'dropdown';
override controlType = 'dropdown';
}
@@ -2,5 +2,5 @@
import { QuestionBase } from './question-base';
export class TextboxQuestion extends QuestionBase<string> {
controlType = 'textbox';
override controlType = 'textbox';
}
@@ -7,7 +7,7 @@
<div [hidden]="formDir.submitted">
<div class="cross-validation" [class.cross-validation-error]="heroForm.errors?.identityRevealed && (heroForm.touched || heroForm.dirty)">
<div class="cross-validation" [class.cross-validation-error]="heroForm.errors?.['identityRevealed'] && (heroForm.touched || heroForm.dirty)">
<div class="form-group">
<label for="name">Name</label>
@@ -18,13 +18,13 @@
<div *ngIf="name.invalid && (name.dirty || name.touched)"
class="alert alert-danger">
<div *ngIf="name.errors?.required">
<div *ngIf="name.errors?.['required']">
Name is required.
</div>
<div *ngIf="name.errors?.minlength">
<div *ngIf="name.errors?.['minlength']">
Name must be at least 4 characters long.
</div>
<div *ngIf="name.errors?.forbiddenName">
<div *ngIf="name.errors?.['forbiddenName']">
Name cannot be Bob.
</div>
</div>
@@ -38,14 +38,14 @@
<div *ngIf="alterEgo.pending">Validating...</div>
<div *ngIf="alterEgo.invalid" class="alert alert-danger alter-ego-errors">
<div *ngIf="alterEgo.errors?.uniqueAlterEgo">
<div *ngIf="alterEgo.errors?.['uniqueAlterEgo']">
Alter ego is already taken.
</div>
</div>
</div>
<!-- #docregion cross-validation-error-message -->
<div *ngIf="heroForm.errors?.identityRevealed && (heroForm.touched || heroForm.dirty)" class="cross-validation-error-message alert alert-danger">
<div *ngIf="heroForm.errors?.['identityRevealed'] && (heroForm.touched || heroForm.dirty)" class="cross-validation-error-message alert alert-danger">
Name cannot match alter ego.
</div>
<!-- #enddocregion cross-validation-error-message -->
@@ -59,7 +59,7 @@
</select>
<div *ngIf="power.invalid && power.touched" class="alert alert-danger">
<div *ngIf="power.errors?.required">Power is required.</div>
<div *ngIf="power.errors?.['required']">Power is required.</div>
</div>
</div>
@@ -6,7 +6,7 @@
<form #heroForm="ngForm" appIdentityRevealed>
<!-- #enddocregion cross-validation-register-validator -->
<div [hidden]="heroForm.submitted">
<div class="cross-validation" [class.cross-validation-error]="heroForm.errors?.identityRevealed && (heroForm.touched || heroForm.dirty)">
<div class="cross-validation" [class.cross-validation-error]="heroForm.errors?.['identityRevealed'] && (heroForm.touched || heroForm.dirty)">
<div class="form-group">
<label for="name">Name</label>
<!-- #docregion name-with-error-msg -->
@@ -19,13 +19,13 @@
<div *ngIf="name.invalid && (name.dirty || name.touched)"
class="alert">
<div *ngIf="name.errors?.required">
<div *ngIf="name.errors?.['required']">
Name is required.
</div>
<div *ngIf="name.errors?.minlength">
<div *ngIf="name.errors?.['minlength']">
Name must be at least 4 characters long.
</div>
<div *ngIf="name.errors?.forbiddenName">
<div *ngIf="name.errors?.['forbiddenName']">
Name cannot be Bob.
</div>
@@ -45,14 +45,14 @@
<div *ngIf="alterEgo.pending">Validating...</div>
<div *ngIf="alterEgo.invalid" class="alert alter-ego-errors">
<div *ngIf="alterEgo.errors?.uniqueAlterEgo">
<div *ngIf="alterEgo.errors?.['uniqueAlterEgo']">
Alter ego is already taken.
</div>
</div>
</div>
<!-- #docregion cross-validation-error-message -->
<div *ngIf="heroForm.errors?.identityRevealed && (heroForm.touched || heroForm.dirty)" class="cross-validation-error-message alert">
<div *ngIf="heroForm.errors?.['identityRevealed'] && (heroForm.touched || heroForm.dirty)" class="cross-validation-error-message alert">
Name cannot match alter ego.
</div>
<!-- #enddocregion cross-validation-error-message -->
@@ -68,7 +68,7 @@
</select>
<div *ngIf="power.errors && power.touched" class="alert">
<div *ngIf="power.errors.required">Power is required.</div>
<div *ngIf="power.errors['required']">Power is required.</div>
</div>
</div>
@@ -14,13 +14,15 @@ import { ProductListComponent } from './product-list/product-list.component';
import { ProductAlertsComponent } from './product-alerts/product-alerts.component';
// #enddocregion declare-product-alerts
import { ProductDetailsComponent } from './product-details/product-details.component';
// #docregion declare-cart
import { CartComponent } from './cart/cart.component';
// #enddocregion declare-cart
import { ShippingComponent } from './shipping/shipping.component';
// #docregion product-details-route, http-client-module, shipping-route, cart-route, declare-product-alerts
// #docregion product-details-route, http-client-module, shipping-route, cart-route, declare-product-alerts, declare-cart
@NgModule({
// #enddocregion declare-product-alerts
// #enddocregion declare-product-alerts, declare-cart
imports: [
BrowserModule,
// #enddocregion product-details-route, cart-route
@@ -39,7 +41,7 @@ import { ShippingComponent } from './shipping/shipping.component';
])
],
// #enddocregion cart-route
// #docregion declare-product-alerts
// #docregion declare-product-alerts, declare-cart
declarations: [
AppComponent,
TopBarComponent,
@@ -49,11 +51,12 @@ import { ShippingComponent } from './shipping/shipping.component';
ProductDetailsComponent,
// #enddocregion product-details-route
CartComponent,
// #enddocregion declare-cart
// #enddocregion http-client-module
ShippingComponent
// #docregion declare-product-alerts, http-client-module, product-details-route
// #docregion declare-product-alerts, http-client-module, product-details-route, declare-cart
],
// #enddocregion declare-product-alerts, product-details-route
// #enddocregion declare-product-alerts, product-details-route, declare-cart
bootstrap: [
AppComponent
]
@@ -56,6 +56,7 @@ export class TiresService {
})
export class CarService {
id = 'C1';
constructor(
protected engineService: EngineService,
protected tiresService: TiresService) { }
@@ -75,13 +76,15 @@ export class CarService {
providedIn: 'root'
})
export class CarService2 extends CarService {
id = 'C2';
override id = 'C2';
constructor(
protected engineService: EngineService,
protected tiresService: TiresService) {
protected override engineService: EngineService,
protected override tiresService: TiresService) {
super(engineService, tiresService);
}
getCar() {
override getCar() {
const car = super.getCar();
car.name = 'BamBam Motors, BroVan 2000';
return car;
@@ -92,13 +95,15 @@ export class CarService2 extends CarService {
providedIn: 'root'
})
export class CarService3 extends CarService2 {
id = 'C3';
override id = 'C3';
constructor(
protected engineService: EngineService,
protected tiresService: TiresService) {
protected override engineService: EngineService,
protected override tiresService: TiresService) {
super(engineService, tiresService);
}
getCar() {
override getCar() {
const car = super.getCar();
car.name = 'Chizzamm Motors, Calico UltraMax Supreme';
return car;
@@ -30,7 +30,7 @@ export class PackageSearchService {
constructor(
private http: HttpClient,
httpErrorHandler: HttpErrorHandler) {
this.handleError = httpErrorHandler.createHandleError('HeroesService');
this.handleError = httpErrorHandler.createHandleError('PackageSearchService');
}
search(packageName: string, refresh = false): Observable<NpmPackageInfo[]> {
-13
View File
@@ -142,19 +142,6 @@
"scripts": []
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": [
"tsconfig.app.json",
"tsconfig.spec.json",
"e2e/tsconfig.json"
],
"exclude": [
"**/node_modules/**"
]
}
},
"e2e": {
"builder": "@angular-devkit/build-angular:protractor",
"options": {
@@ -28,7 +28,7 @@ export class MyCounterComponent implements OnChanges {
}
// A change to `counter` is the only change we care about
const chng = changes.counter;
const chng = changes['counter'];
const cur = chng.currentValue;
const prev = JSON.stringify(chng.previousValue); // first time is {}; after is integer
this.changeLog.push(`counter: currentValue = ${cur}, previousValue = ${prev}`);
@@ -44,7 +44,7 @@ export class PeekABooComponent extends PeekABooDirective implements
const changesMsgs: string[] = [];
for (const propName in changes) {
if (propName === 'name') {
const name = changes.name.currentValue;
const name = changes['name'].currentValue;
changesMsgs.push(`name ${this.verb} to "${name}"`);
} else {
changesMsgs.push(propName + ' ' + this.verb);
@@ -14,12 +14,12 @@ describe('observables', () => {
});
it('should listen to input changes', () => {
let triggerInputChange!: (e: {keyCode: number}) => void;
let triggerInputChange!: (e: {code: string}) => void;
const input = {
value: 'Test',
addEventListener: jasmine
.createSpy('addEvent')
.and.callFake((eventName: string, cb: (e: {keyCode: number}) => void) => {
.and.callFake((eventName: string, cb: (e: {code: string}) => void) => {
if (eventName === 'keydown') {
triggerInputChange = cb;
}
@@ -29,10 +29,10 @@ describe('observables', () => {
const document = { getElementById: () => input } as unknown as Document;
docRegionFromEvent(document);
triggerInputChange({keyCode: 65});
triggerInputChange({code: 'A'});
expect(input.value).toBe('Test');
triggerInputChange({keyCode: 27});
triggerInputChange({code: 'Escape'});
expect(input.value).toBe('');
});
@@ -55,11 +55,11 @@ function fromEvent<T extends keyof HTMLElementEventMap>(target: HTMLElement, eve
export function docRegionFromEvent(document: Document) {
// #docregion fromevent_use
const ESC_KEY = 27;
const ESC_CODE = 'Escape';
const nameInput = document.getElementById('name') as HTMLInputElement;
const subscription = fromEvent(nameInput, 'keydown').subscribe((e: KeyboardEvent) => {
if (e.keyCode === ESC_KEY) {
if (e.code === ESC_CODE) {
nameInput.value = '';
}
});
@@ -51,5 +51,5 @@ export class FlyingHeroesComponent {
styles: ['#flyers, #all {font-style: italic}', 'button {display: block}', 'input {margin: .25rem .25rem .5rem 0;}'],
})
export class FlyingHeroesImpureComponent extends FlyingHeroesComponent {
title = 'Flying Heroes (impure pipe)';
override title = 'Flying Heroes (impure pipe)';
}
@@ -1,13 +1,15 @@
import { Observable, of } from 'rxjs';
/// <reference types="node" />
import { of } from 'rxjs';
import { docRegionTypeahead } from './typeahead';
describe('typeahead', () => {
let document: Document;
let ajax: jasmine.Spy;
let tick: MockClock['tick'];
let triggertInputChange: (e: { target: { value: string } }) => void;
beforeEach(() => {
jasmine.clock().install();
const input = {
addEventListener: jasmine
.createSpy('addEvent')
@@ -21,40 +23,37 @@ describe('typeahead', () => {
document = { getElementById: (id: string) => input } as unknown as Document;
ajax = jasmine.createSpy('ajax').and.callFake((url: string) => of('foo bar'));
});
afterEach(() => {
jasmine.clock().uninstall();
tick = MockClock.install();
});
it('should make an ajax call to the corrent endpoint', () => {
docRegionTypeahead(document, ajax);
triggertInputChange({ target: { value: 'foo' } });
jasmine.clock().tick(11);
tick(11);
expect(ajax).toHaveBeenCalledWith('/api/endpoint?search=foo');
});
it('should not make an ajax call, when the input length < 3', () => {
docRegionTypeahead(document, ajax);
triggertInputChange({ target: { value: '' } });
jasmine.clock().tick(11);
tick(11);
expect(ajax).not.toHaveBeenCalled();
triggertInputChange({ target: { value: 'fo' } });
jasmine.clock().tick(11);
tick(11);
expect(ajax).not.toHaveBeenCalled();
});
it('should not make an ajax call for intermediate values when debouncing', () => {
docRegionTypeahead(document, ajax);
triggertInputChange({ target: { value: 'foo' } });
jasmine.clock().tick(9);
tick(9);
triggertInputChange({ target: { value: 'bar' } });
jasmine.clock().tick(9);
tick(9);
triggertInputChange({ target: { value: 'baz' } });
jasmine.clock().tick(9);
tick(9);
triggertInputChange({ target: { value: 'qux' } });
expect(ajax).not.toHaveBeenCalled();
jasmine.clock().tick(10);
tick(10);
expect(ajax).toHaveBeenCalledTimes(1);
expect(ajax).toHaveBeenCalledWith('/api/endpoint?search=qux');
});
@@ -62,11 +61,94 @@ describe('typeahead', () => {
it('should not make an ajax call, when the input value has not changed', () => {
docRegionTypeahead(document, ajax);
triggertInputChange({ target: { value: 'foo' } });
jasmine.clock().tick(11);
tick(11);
expect(ajax).toHaveBeenCalled();
ajax.calls.reset();
triggertInputChange({ target: { value: 'foo' } });
jasmine.clock().tick(11);
tick(11);
expect(ajax).not.toHaveBeenCalled();
});
// Helpers
interface MockTask {
id: NodeJS.Timeout;
fn: () => unknown;
delay: number;
recurring: boolean;
nextTriggerTime: number;
}
class MockClock {
private tasks: MockTask[] = [];
private constructor(private now: number) {}
static install(mockTime = 0): MockClock['tick'] {
const mocked = new this(mockTime);
spyOn(global, 'clearInterval').and.callFake(id => mocked.clearTask(id));
spyOn(global, 'clearTimeout').and.callFake(id => mocked.clearTask(id));
spyOn(global, 'setInterval').and.callFake(
(fn, delay, ...args) => mocked.createTask(fn, delay, true, ...args));
spyOn(global, 'setTimeout').and.callFake(
(fn, delay, ...args) => mocked.createTask(fn, delay, false, ...args));
spyOn(Date, 'now').and.callFake(() => mocked.now);
return mocked.tick.bind(mocked);
}
private clearTask(id: MockTask['id']): void {
this.tasks = this.tasks.filter(task => task.id !== id);
}
private createTask(
fn: MockTask['fn'], delay: MockTask['delay'], recurring: MockTask['recurring'],
...args: any[]): MockTask['id'] {
// Avoid infinite loops.
if (recurring && (delay <= 0)) {
delay = 1;
}
const task: MockTask = {
id: {} as MockTask['id'],
fn: fn.bind<null, unknown, unknown>(null, ...args),
delay,
recurring,
nextTriggerTime: this.now + delay,
};
this.queueTask(task);
return task.id;
}
private queueTask(task: MockTask): void {
const firstLaterTaskIdx = this.tasks.findIndex(
otherTask => otherTask.nextTriggerTime > task.nextTriggerTime);
const newTaskIdx = (firstLaterTaskIdx === -1) ? this.tasks.length : firstLaterTaskIdx;
this.tasks.splice(newTaskIdx, 0, task);
}
private tick(millis: number): void {
const finalNow = this.now + millis;
while (this.tasks[0]?.nextTriggerTime <= finalNow) {
const task = this.tasks.shift()!;
this.now = task.nextTriggerTime;
if (task.recurring) {
this.queueTask({...task, nextTriggerTime: this.now + task.delay});
}
try {
task.fn();
} catch (err) {
console.error(err);
}
}
this.now = finalNow;
}
}
});
@@ -127,8 +127,8 @@ describe('Reactive forms', () => {
const formValue = await formValueElement.getText();
const formJson = JSON.parse(formValue.toString().replace('Form Value:', ''));
expect(profile.firstName).toBe(formJson.firstName);
expect(profile.lastName).toBe(formJson.lastName);
expect(profile['firstName']).toBe(formJson.firstName);
expect(profile['lastName']).toBe(formJson.lastName);
expect(formJson.aliases[0]).toBe(aliasText);
});
});
@@ -15,7 +15,7 @@ import { slideInAnimation } from './animations';
// #docregion function-binding
export class AppComponent {
getAnimationData(outlet: RouterOutlet) {
return outlet && outlet.activatedRouteData && outlet.activatedRouteData.animation;
return outlet?.activatedRouteData?.['animation'];
}
}
// #enddocregion function-binding
@@ -12,6 +12,6 @@ import { slideInAnimation } from './animations';
})
export class AppComponent {
getAnimationData(outlet: RouterOutlet) {
return outlet && outlet.activatedRouteData && outlet.activatedRouteData.animation;
return outlet?.activatedRouteData?.['animation'];
}
}
@@ -26,7 +26,7 @@ export class CrisisDetailComponent implements OnInit {
ngOnInit() {
this.route.data
.subscribe(data => {
const crisis: Crisis = data.crisis;
const crisis: Crisis = data['crisis'];
this.editName = crisis.name;
this.crisis = crisis;
});
@@ -10,7 +10,7 @@ export class SelectivePreloadingStrategyService implements PreloadingStrategy {
preloadedModules: string[] = [];
preload(route: Route, load: () => Observable<any>): Observable<any> {
if (route.data && route.data.preload && route.path != null) {
if (route.data?.['preload'] && route.path != null) {
// add the route path to the preloaded module array
this.preloadedModules.push(route.path);
@@ -32,8 +32,8 @@
<h2>Reference variables, forms, and NgForm</h2>
<!-- #docregion ngForm -->
<form #itemForm="ngForm" (ngSubmit)="onSubmit(itemForm)">
<label for="name">Name <input class="form-control" name="name" ngModel required />
</label>
<label for="name">Name</label>
<input type="text" id="name" class="form-control" name="name" ngModel required />
<button type="submit">Submit</button>
</form>
@@ -58,10 +58,10 @@ export class HeroDetailComponent {
})
export class BigHeroDetailComponent extends HeroDetailComponent {
@Input() hero!: Hero;
@Output() deleteRequest = new EventEmitter<Hero>();
@Input() override hero!: Hero;
@Output() override deleteRequest = new EventEmitter<Hero>();
delete() {
override delete() {
this.deleteRequest.emit(this.hero);
}
}
@@ -2,9 +2,15 @@
<!-- #docregion -->
<form (ngSubmit)="onSubmit(heroForm)" #heroForm="ngForm">
<div class="form-group">
<label for="name">Name
<input class="form-control" name="name" required [(ngModel)]="hero.name">
</label>
<label for="name">Name</label>
<input
type="text"
id="name"
class="form-control"
name="name"
required
[(ngModel)]="hero.name"
/>
</div>
<button type="submit" [disabled]="!heroForm.form.valid">Submit</button>
</form>
@@ -8,7 +8,7 @@ import {
///////// Fakes /////////
export class FakeValueService extends ValueService {
value = 'faked service value';
override value = 'faked service value';
}
////////////////////////
describe('demo (no TestBed):', () => {
@@ -372,14 +372,14 @@ describe('demo (with TestBed):', () => {
expect(el.context).toBe(childComp, 'context is the child component');
expect(el.attributes.account).toBe(childComp.id, 'account attribute');
expect(el.attributes.bank).toBe(childComp.bank, 'bank attribute');
expect(el.attributes['account']).toBe(childComp.id, 'account attribute');
expect(el.attributes['bank']).toBe(childComp.bank, 'bank attribute');
expect(el.classes.closed).toBe(true, 'closed class');
expect(el.classes.open).toBeFalsy('open class');
expect(el.classes['closed']).toBe(true, 'closed class');
expect(el.classes['open']).toBeFalsy('open class');
expect(el.styles.color).toBe(comp.color, 'color style');
expect(el.styles.width).toBe(comp.width + 'px', 'width style');
expect(el.styles['color']).toBe(comp.color, 'color style');
expect(el.styles['width']).toBe(comp.width + 'px', 'width style');
// Removed on 12/02/2016 when ceased public discussion of the `Renderer`. Revive in future?
// expect(el.properties['customProperty']).toBe(true, 'customProperty');
@@ -510,11 +510,11 @@ describe('demo (with TestBed):', () => {
expect(comp.children.toArray().length).toBe(4,
'three different child components and an ElementRef with #content');
expect(el.references.nc).toBe(comp, '#nc reference to component');
expect(el.references['nc']).toBe(comp, '#nc reference to component');
// #docregion custom-predicate
// Filter for DebugElements with a #content reference
const contentRefs = el.queryAll( de => de.references.content);
const contentRefs = el.queryAll( de => de.references['content']);
// #enddocregion custom-predicate
expect(contentRefs.length).toBe(4, 'elements w/ a #content reference');
});
@@ -698,5 +698,5 @@ class FakeGrandchildComponent { }
@Injectable()
class FakeValueService extends ValueService {
value = 'faked value';
override value = 'faked value';
}
@@ -30,19 +30,19 @@ export class TestHeroService extends HeroService {
heroes = getTestHeroes();
lastResult!: Observable<any>; // result from last method call
addHero(hero: Hero): Observable<Hero> {
override addHero(hero: Hero): Observable<Hero> {
throw new Error('Method not implemented.');
}
deleteHero(hero: number | Hero): Observable<Hero> {
override deleteHero(hero: number | Hero): Observable<Hero> {
throw new Error('Method not implemented.');
}
getHeroes(): Observable<Hero[]> {
override getHeroes(): Observable<Hero[]> {
return this.lastResult = asyncData(this.heroes);
}
getHero(id: number | string): Observable<Hero> {
override getHero(id: number | string): Observable<Hero> {
if (typeof id === 'string') {
id = parseInt(id, 10);
}
@@ -51,7 +51,7 @@ export class TestHeroService extends HeroService {
return this.lastResult;
}
updateHero(hero: Hero): Observable<Hero> {
override updateHero(hero: Hero): Observable<Hero> {
return this.lastResult = this.getHero(hero.id).pipe(
map(h => {
if (h) {
@@ -71,7 +71,7 @@ describe('HighlightDirective', () => {
it('bare <h2> should not have a customProperty', () => {
expect(bareH2.properties.customProperty).toBeUndefined();
expect(bareH2.properties['customProperty']).toBeUndefined();
});
// #enddocregion selected-tests
-20
View File
@@ -1,20 +0,0 @@
// this tsconfig is used to give intellisense to
// all the examples in this folder
{
"compilerOptions": {
"target": "es6",
"module": "commonjs",
"moduleResolution": "node",
"sourceMap": true,
"experimentalDecorators": true,
"lib": ["es2015", "dom"],
"noImplicitAny": true,
"suppressImplicitAnyIndexErrors": true,
"typeRoots": [
"../../tools/examples/shared/node_modules/@types"
]
},
"include": [
"*/e2e-spec.ts"
]
}
+1
View File
@@ -58,6 +58,7 @@
],
"no-non-null-assertion": false,
"no-redundant-jsdoc": true,
"no-string-literal": false,
"no-switch-case-fall-through": true,
"no-var-requires": false,
"object-literal-key-quotes": [
+4 -10
View File
@@ -64,7 +64,7 @@ When `true`, the compiler does not check the TypeScript version and does not rep
### `enableI18nLegacyMessageIdFormat`
Instructs the Angular template compiler to generate legacy ids for messages that are tagged in templates by the `i18n` attribute.
See [Mark text for translations][AioGuideI18nCommonPrepareMarkTextForTranslations] for more information about marking messages for localization.
See [Mark text for translations][AioGuideI18nCommonPrepareMarkTextInComponentTemplate] for more information about marking messages for localization.
Set this option to `false` unless your project relies upon translations that were previously generated using legacy IDs. Default is `true`.
@@ -74,12 +74,6 @@ These message formats have a number of issues, such as whitespace handling and r
The new message format is more resilient to whitespace changes, is the same across all translation file formats, and can be generated directly from calls to `$localize`.
This allows `$localize` messages in application code to use the same ID as identical `i18n` messages in component templates.
### `enableIvy`
Enables the [Ivy](guide/ivy) compilation and rendering pipeline. Default is `true`, as of version 9. In version 9, you can [opt out of Ivy](guide/ivy#opting-out-of-angular-ivy) to continue using the previous compiler, View Engine.
For library projects generated with the CLI, the production configuration default is `false` in version 9.
### `enableResourceInlining`
When `true`, replaces the `templateUrl` and `styleUrls` property in all `@Component` decorators with inlined contents in `template` and `styles` properties.
@@ -180,7 +174,7 @@ When you use the CLI command `ng new --strict`, it is set to `true` in the gener
### `strictTemplates`
When `true`, enables [strict template type checking](guide/template-typecheck#strict-mode). Strict mode is only available when using [Ivy](guide/ivy) (Angular version 9 and later).
When `true`, enables [strict template type checking](guide/template-typecheck#strict-mode).
Additional strictness flags allow you to enable and disable specific types of strict template type checking. See [troubleshooting template errors](guide/template-typecheck#troubleshooting-template-errors).
@@ -203,8 +197,8 @@ In addition to the configuration file, you can also use [`tsc` command line opti
<!-- links -->
[AioGuideI18nCommonPrepareMarkTextForTranslations]: guide/i18n-common-prepare#mark-text-for-translations "Mark text for translations - Prepare templates for translations | Angular"
[AioGuideI18nCommonPrepareMarkTextInComponentTemplate]: guide/i18n-common-prepare#mark-text-in-component-template "Mark text in component template - Prepare templates for translations | Angular"
<!-- end links -->
@reviewed 2021-09-15
@reviewed 2021-10-13
+366
View File
@@ -0,0 +1,366 @@
# Angular Package Format
This document describes the Angular Package Format (APF).
APF is an Angular specific specification for the structure and format of npm packages that is used by all first-party Angular packages (`@angular/core`, `@angular/material`, etc.) and most third-party Angular libraries.
APF enables a package to work seamlessly under most common scenarios that use Angular.
Packages that use APF are compatible with the tooling offered by the Angular team as well as wider JavaScript ecosystem.
It is recommended that third-party library developers follow the same npm package format.
<div class="alert is-helpful">
APF is versioned along with the rest of Angular, and every major version improves the package format.
You can find the versions of the specification prior to v13 in this [google doc](https://docs.google.com/document/d/1CZC2rcpxffTDfRDs6p1cfbmKNLA6x5O-NtkJglDaBVs/preview).
</div>
## Why specify a package format?
In today's JavaScript landscape, developers will consume packages in many different ways, using many different toolchains (Webpack, rollup, esbuild, etc). These tools may understand and require different inputs - some tools may be able to process the latest ES language version, while others may benefit from directly consuming an older ES version.
The Angular distribution format supports all of the commonly used development tools and workflows, and adds emphasis on optimizations that result either in smaller application payload size or faster development iteration cycle (build time).
Developers can rely on Angular CLI and [ng-packagr](https://github.com/ng-packagr/ng-packagr) (a build tool Angular CLI uses) to produce packages in the Angular package format. See the [Creating Libraries](/guide/creating-libraries) guide for more details.
## File layout
The following example shows a simplified version of the `@angular/core` package's file layout, with an explanation for each file in the package. This table describes the file layout under `node_modules/@angular/core` annotated to describe the purpose of files and directories:
<style>
table tbody>tr>td {
padding: 8px;
vertical-align: middle;
line-height: normal;
}
</style>
<table>
<tbody>
<tr>
<td><pre>README.md</pre>
<td>Package README, used by npmjs web UI</td>
</tr>
<tr>
<td><pre>package.json</pre></td>
<td>Primary package.json, describing the package itself as well as all available entrypoints and code formats. This file contains the "exports" mapping used by runtimes and tools to perform module resolution.</td>
</tr>
<tr>
<td><pre>core.d.ts</pre></td>
<td>Bundled .d.ts for the primary entrypoint (@angular/core)</td>
</tr>
<tr>
<td><pre>esm2020/
core.mjs
index.mjs
public_api.mjs</pre></td>
<td>Tree of @angular/core's sources in unflattened ES2020 format.</td>
</tr>
<tr>
<td><pre>esm2020/testing/</pre></td>
<td>Tree of the @angular/core/testing entrypoint in unflattened ES2020 format.</td>
</tr>
<tr>
<td><pre>fesm2015/
core.mjs
core.mjs.map
testing.mjs
testing.mjs.map</pre></td>
<td>Code for all entrypoints in a flattened (FESM) ES2015 format, along with sourcemaps.</td>
</tr>
<tr>
<td><pre>fesm2020/
core.mjs
core.mjs.map
testing.mjs
testing.mjs.map</pre></td>
<td>Code for all entrypoints in flattened (FESM) ES2020 format, along with sourcemaps.</td>
</tr>
<tr>
<td><pre>testing/</pre></td>
<td>Directory representing the "testing" entrypoint.</td>
</tr>
<tr>
<td><pre>testing/package.json</pre></td>
<td>Defines the @angular/core/testing entrypoint with its typings for TypeScript, which does not support the top level "exports" based module resolution.</td>
</tr>
<tr>
<td><pre>testing/testing.d.ts</pre></td>
<td>Actual .d.ts for the @angular/core/testing entrypoint</td>
</tr>
</tbody>
</table>
## `package.json`
The primary `package.json` contains important package metadata, including the following:
* It [declares](#esm-declaration) the package to be in EcmaScript Module (ESM) format.
* It contains an [`"exports"` field](#exports) which defines the available source code formats of all entrypoints.
* It contains [keys](#legacy-resolution-keys) which define the available source code formats of the primary `@angular/core` entrypoint, for tools which do not understand `"exports"`. These keys are considered deprecated, and will be removed as the support for `"exports"` rolls out across the ecosystem.
* It declares whether the package contains [side-effects](#side-effects).
### ESM declaration
The top-level `package.json` contains the key:
<code-example language="js">
{
"type": "module"
}
</code-example>
This informs resolvers that code within the package is using EcmaScript Modules as opposed to CommonJS modules.
### `"exports"`
The `"exports"` field has the following structure:
<code-example language="js">
"exports": {
"./schematics/*": {
"default": "./schematics/*.js"
},
"./package.json": {
"default": "./package.json"
},
".": {
"types": "./core.d.ts",
"esm2020": "./esm2020/core.mjs",
"es2020": "./fesm2020/core.mjs",
"es2015": "./fesm2015/core.mjs",
"node": "./fesm2015/core.mjs",
"default": "./fesm2020/core.mjs"
},
"./testing": {
"types": "./testing/testing.d.ts",
"esm2020": "./esm2020/testing/testing.mjs",
"es2020": "./fesm2020/testing.mjs",
"es2015": "./fesm2015/testing.mjs",
"node": "./fesm2015/testing.mjs",
"default": "./fesm2020/testing.mjs"
}
}
</code-example>
Of primary interest are the `"."` and the `"./testing"` keys, which define the available code formats for the `@angular/core` primary entrypoint and the `@angular/core/testing` secondary entrypoint, respectively. For each entrypoint, the available formats are:
* Typings (`.d.ts` files)
`.d.ts` files are used by TypeScript when depending on a given package.
* `es2020` - ES2020 code flattened into a single source file.
* `es2015` - ES2015 code flattened into a single source file.
* `esm2020` - ES2020 code in unflattened source files (this format is included for experimentation - see [this discussion of defaults](#note-about-the-defaults-in-packagejson) for details).
Tooling that is aware of these keys may preferentially select a desirable code format from `"exports"`. The remaining 2 keys control the default behavior of tooling:
* `"node"` selects flattened ES2015 code when the package is loaded in Node.
This format is used due to the requirements of `zone.js`, which does not support native `async`/`await` ES2017 syntax. Therefore, Node is instructed to use ES2015 code, where `async`/`await` structures have been downleveled into Promises.
* `"default"` selects flattened ES2020 code for all other consumers.
### Legacy resolution keys
In addition to `"exports"`, the top-level `package.json` also defines legacy module resolution keys for resolvers that don't support `"exports"`. For `@angular/core` these are:
<code-example language="js">
{
"fesm2020": "./fesm2020/core.mjs",
"fesm2015": "./fesm2015/core.mjs",
"esm2020": "./esm2020/core.mjs",
"typings": "./core.d.ts",
"module": "./fesm2015/core.mjs",
"es2020": "./fesm2020/core.mjs",
}
</code-example>
As above, a module resolver can use these keys to load a specific code format. Note that instead of `"default"`, `"module"` selects the format both for Node as well as any tooling not configured to use a specific key. As with `"node"`, ES2015 code is selected due to the constraints of ZoneJS.
### Side effects
The last function of `package.json` is to declare whether the package has [side-effects](#sideeffects-flag).
<code-example language="js">
{
"sideEffects": false
}
</code-example>
Most Angular packages should not depend on top-level side effects, and thus should include this declaration.
### Secondary `package.json`s
In addition to the top-level `package.json`, secondary entrypoints have a corresponding directory with its own `package.json`. For example, in `@angular/core` the `@angular/core/testing` entrypoint is represented by `testing/package.json`.
This secondary `package.json` is required for legacy resolvers which do not support `"exports"`. We expect these files to be removed in a future version of the Angular Package Format, once support for `"exports"` is consistent across the ecosystem.
## Entrypoints and Code Splitting
Packages in the Angular Package Format contain one primary entrypoint and zero or more secondary entrypoints (e.g. `@angular/common/http`). Entrypoints serve several functions.
1. They define the module specifiers from which users import code (for example, `@angular/core` and `@angular/core/testing`).
Users typically perceive these entrypoints as distinct groups of symbols, with different purposes or functionality.
Specific entrypoints might only be used for special purposes, such as testing. Such APIs can be separated out from the primary entrypoint to reduce the chance of them being used accidentally or incorrectly.
2. They define the granularity at which code can be lazily loaded.
Many modern build tools are only capable of "code splitting" (aka lazy loading) at the ES Module level. Since the Angular Package Format uses primarily a single "flat" ES Module per entrypoint, this means that most build tooling will not be able to split code in a single entrypoint into multiple output chunks.
The general rule for APF packages is to use entrypoints for the smallest sets of logically connected code possible. For example, the Angular Material package publishes each logical component or set of components as a separate entrypoint - one for Button, one for Tabs, etc. This allows each Material component to be lazily loaded separately, if desired.
Not all libraries require such granularity. Most libraries with a single logical purpose should be published as a single entrypoint. `@angular/core` for example uses a single entrypoint for the runtime, because the Angular runtime is generally used as a single entity.
### Resolution of Secondary Entrypoints
Secondary entrypoints may be resolved by tooling in one of two ways:
* via the `"exports"` field of the primary `package.json` for the package
* by Node Module Resolution rules, via a `package.json` in a subdirectory corresponding to the entrypoint's module ID. For example, the `testing/package.json` file for the `@angular/core/testing` secondary entrypoint.
## README.md
The readme file in the markdown format that is used to display description of a package on npm and github.
Example readme content of @angular/core package:
<code-example language="html">
Angular
=======
The sources for this package are in the main [Angular](https://github.com/angular/angular) repo. Please file issues and pull requests against that repo.
License: MIT
</code-example>
## Partial Compilation
Libraries in the Angular Package Format must be published in "partial compilation" mode. This is a compilation mode for `ngc` which produces compiled Angular code that is not tied to a specific Angular runtime version, in contrast to the full compilation used for applications, where the Angular compiler and runtime versions must match exactly.
To partially compile Angular code, use the `"compilationMode"` flag in `"angularCompilerOptions"` in your `tsconfig.json`:
<code-example language="js">
{
...
"angularCompilerOptions": {
"compilationMode": "partial",
}
}
</code-example>
Partially compiled library code is then converted to fully compiled code during the application build process by the Angular CLI.
If your build pipeline does not use the Angular CLI then refer to the [Consuming partial ivy code outside the Angular CLI](/guide/creating-libraries#consuming-partial-ivy-code-outside-the-angular-cli) guide.
## Optimizations
### Flattening of ES Modules
The Angular Package Format specifies that code be published in "flattened" ES module format. This significantly reduces the build time of Angular applications as well as download and parse time of the final application bundle. Please check out the excellent post ["The cost of small modules"](https://nolanlawson.com/2016/08/15/the-cost-of-small-modules/) by Nolan Lawson.
The Angular compiler has support for generating index ES module files that can then be used to generate flattened modules using tools like Rollup, resulting in a file format we call Flattened ES Module or FESM.
FESM is a file format created by flattening all ES Modules accessible from an entrypoint into a single ES Module. It’s formed by following all imports from a package and copying that code into a single file while preserving all public ES exports and removing all private imports.
The shortened name “FESM” (pronounced “phesom”) can have a number after it such as “FESM5” or “FESM2015”. The number refers to the language level of the JavaScript inside the module. So a FESM5 file would be ESM+ES5 (import/export statements and ES5 source code).
To generate a flattened ES Module index file, use the following configuration options in your tsconfig.json file:
<code-example language="js">
{
"compilerOptions": {
...
"module": "esnext",
"target": "es2020",
...
},
"angularCompilerOptions": {
...
"flatModuleOutFile": "my-ui-lib.js",
"flatModuleId": "my-ui-lib"
}
}
</code-example>
Once the index file (e.g. `my-ui-lib.js`) is generated by ngc, bundlers and optimizers like Rollup can be used to produce the flattened ESM file.
#### Note about the defaults in package.json
As of webpack v4 the flattening of ES modules optimization should not be necessary for webpack users, and in fact theoretically we should be able to get better code-splitting without flattening of modules in webpack. In practice we still see size regressions when using unflattened modules as input for webpack v4. This is why `"module"` and `"es2020"` package.json entries still point to fesm files. We are investigating this issue and expect that we'll switch the `"module"` and `"es2020"` package.json entry points to unflattened files when the size regression issue is resolved. The APF currently includes unflattened ESM2020 code for the purpose of validating such a future change.
### "sideEffects" flag
By default, EcmaScript Modules are side-effectful: importing from a module ensures that any code at the top level of that module will execute. This is often undesirable, as most side-effectful code in typical modules is not truly side-effectful, but instead only affects specific symbols. If those symbols are not imported and used, it's often desirable to remove them in an optimization process known as tree-shaking, and the side-effectful code can prevent this.
Build tools such as Webpack support a flag which allows ackages to declare that they do not depend on side-effectful code at the top level of their modules, giving the tools more freedom to tree-shake code from the package. The end result of these optimizations should be smaller bundle size and better code distribution in bundle chunks after code-splitting. This optimization can break your code if it contains non-local side-effects - this is however not common in Angular applications and it's usually a sign of bad design. Our recommendation is for all packages to claim the side-effect free status by setting the `sideEffects` property to `false`, and that developers follow the [Angular Style Guide](https://angular.io/guide/styleguide) which naturally results in code without non-local side-effects.
More info: [webpack docs on side-effects](https://github.com/webpack/webpack/tree/master/examples/side-effects)
### ES2020 Language Level
ES2020 Language level is now the default language level that is consumed by Angular CLI and other tooling. The Angular CLI will downlevel the bundle to a language level that is supported by all targeted browsers at application build time.
### d.ts bundling / type definition flattening
As of APF v8 we now prefer to run [API Extractor](https://api-extractor.com/), to bundle TypeScript definitions so that the entire API appears in a single file.
In prior APF versions each entry point would have a `src` directory next to the .d.ts entry point and this directory contained individual d.ts files matching the structure of the original source code. While this distribution format is still allowed and supported, it is highly discouraged because it confuses tools like IDEs that then offer incorrect autocompletion, and allows users to depend on deep-import paths which are typically not considered to be public API of a library or a package.
### Tslib
As of APF v10, we recommend adding tslib as a direct dependency of your primary entry-point. This is because the tslib version is tied to the TypeScript version used to compile your library.
## Examples
* [@angular/core package](https://unpkg.com/browse/@angular/core@13.0.0-rc.0/)
* [@angular/material package](https://unpkg.com/browse/@angular/material@13.0.0-rc.0/)
## Definition of Terms
The following terms are used throughout this document very intentionally. In this section we define all of them to provide additional clarity.
<style>
dt {
font-size: larger;
font-weight: bold;
padding: 16px 0px;
}
</style>
<dl>
<dt>Package</dt>
<dd>The smallest set of files that are published to NPM and installed together, for example @angular/core. This package includes a manifest called package.json, compiled source code, typescript definition files, source maps, metadata, etc. The package is installed with npm install @angular/core.</dd>
<dt>Symbol</dt>
<dd>A class, function, constant or variable contained in a module and optionally made visible to the external world via a module export.</dd>
<dt>Module</dt>
<dd>Short for ECMAScript Modules. A file containing statements that import and export symbols. This is identical to the definition of modules in the ECMAScript spec.</dd>
<dt>ESM</dt>
<dd>Short for ECMAScript Modules (see above)</dd>
<dt>FESM</dt>
<dd>Short for Flattened ES Modules and consists of a file format created by flattening all ES Modules accessible from an entry point into a single ES Module.
</dd>
<dt>Module ID</dt>
<dd>The identifier of a module used in the import statements, e.g. `@angular/core`. The ID often maps directly to a path on the filesystem, but this is not always the case due to various module resolution strategies.</dd>
<dt>Module Specifier</dt>
<dd>A module identifier (see above)</dd>
<dt>Module Resolution Strategy</dt>
<dd>Algorithm used to convert Module IDs to paths on the filesystem. Node.js has one that is well specified and widely used, TypeScript supports several module resolution strategies, Closure has yet another strategy.</dd>
<dt>Module Format</dt>
<dd>Specification of the module syntax that covers at minimum the syntax for the importing and exporting from a file. Common module formats are CommonJS (CJS, typically used for Node.js applications) or ECMAScript Modules (ESM). The module format indicates only the packaging of the individual modules, but not the JavaScript language features used to make up the module content. Because of this, the Angular team often uses the language level specifier as a suffix to the module format, e.g. ESM+ES5 specifies that the module is in ESM format and contains code down-leveled to ES5. Other commonly used combos: ESM+ES2015, CJS+ES5, and CJS+ES2015.</dd>
<dt>Bundle</dt>
<dd>An artifact in the form of a single JS file, produced by a build tool, e.g. WebPack or Rollup, that contains symbols originating in one or more modules. Bundles are a browser-specific workaround that reduce network strain that would be caused if browsers were to start downloading hundreds if not tens of thousands of files. Node.js typically doesn't use bundles. Common bundle formats are UMD and System.register.</dd>
<dt>Language Level</dt>
<dd>The language of the code (ES5 or ES2015). Independent of the module format.</dd>
<dt>Entry Point</dt>
<dd>A module intended to be imported by the user. It is referenced by a unique module ID and exports the public API referenced by that module ID. An example is @angular/core or @angular/core/testing. Both entry points exist in the @angular/core package, but they export different symbols. A package can have many entry points.</dd>
<dt>Deep Import</dt>
<dd>A process of retrieving symbols from modules that are not Entry Points. These module IDs are usually considered to be private APIs that can change over the lifetime of the project or while the bundle for the given package is being created.</dd>
<dt>Top-Level Import</dt>
<dd>An import coming from an entry point. The available top-level imports are what define the public API and are exposed in “@angular/name” modules, such as @angular/core or @angular/common.</dd>
<dt>Tree-shaking</dt>
<dd>The process of identifying and removing code not used by an application - also known as dead code elimination. This is a global optimization performed at the application level using tools like Rollup, Closure Compiler, or Uglify.</dd>
<dt>AOT Compiler</dt>
<dd>The Ahead of Time Compiler for Angular.</dd>
<dt>Flattened Type Definitions</dt>
<dd>The bundled TypeScript definitions generated from api-extractor.</dd>
</dl>
+2 -2
View File
@@ -263,7 +263,7 @@ What it does
</tr>
<tr>
<td><code>[state](api/animations/state)()</code></td>
<td><code><a href="api/animations/state" class="code-anchor">state</a>()</code></td>
<td>Creates a named set of CSS styles that should be applied on successful transition to a given state. The state can then be referenced by name within other animation functions.</td>
</tr>
@@ -283,7 +283,7 @@ What it does
</tr>
<tr>
<td><code>[group](api/animations/group)()</code></td>
<td><code><a href="api/animations/group" class="code-anchor">group</a>()</code></td>
<td>Specifies a group of animation steps (<em>inner animations</em>) to be run in parallel. Animation continues only after all inner animation steps have completed. Used within <code>sequence()</code> or <code>transition()</code>.</td>
</tr>
-12
View File
@@ -551,18 +551,6 @@ In the template type-checking phase, the Angular template compiler uses the Type
Enable this phase explicitly by adding the compiler option `"fullTemplateTypeCheck"` in the `"angularCompilerOptions"` of the project's TypeScript configuration file
(see [Angular Compiler Options](guide/angular-compiler-options)).
<div class="alert is-helpful">
In [Angular Ivy](guide/ivy), the template type checker has been completely rewritten to be more capable as well as stricter, meaning it can catch a variety of new errors that the previous type checker would not detect.
As a result, templates that previously compiled under View Engine can fail type checking under Ivy. This can happen because Ivy's stricter checking catches genuine errors, or because application code is not typed correctly, or because the application uses libraries in which typings are inaccurate or not specific enough.
This stricter type checking is not enabled by default in version 9, but can be enabled by setting the `strictTemplates` configuration option.
For more information about type-checking options, and about improvements to template type checking in version 9 and above, see [Template type checking](guide/template-typecheck).
</div>
Template validation produces error messages when a type error is detected in a template binding
expression, similar to how type errors are reported by the TypeScript compiler against code in a `.ts`
file.
-29
View File
@@ -319,35 +319,6 @@ Autoprefixer looks for the `browserslist` configuration when it prefixes your CS
See the [browserslist repo](https://github.com/browserslist/browserslist) for more examples of how to target specific browsers and versions.
### Backward compatibility with Lighthouse
If you want to produce a progressive web application and are using [Lighthouse](https://developers.google.com/web/tools/lighthouse/) to grade the project, add the following `browserslist` entry to your `package.json` file, in order to eliminate the [old flexbox](https://developers.google.com/web/tools/lighthouse/audits/old-flexbox) prefixes:
```
"browserslist": [
"last 2 versions",
"not ie <= 10",
"not ie_mob <= 10"
]
```
### Backward compatibility with CSS grid
CSS grid layout support in Autoprefixer, which was previously on by default, is off by default in Angular 8 and higher.
To use CSS grid with Internet Explorer 10/11, you must explicitly enable it using the `autoplace` option.
To do this, add the following to the top of the global styles file (or within a specific css selector scope):
```
/* autoprefixer grid: autoplace */
```
or
```
/* autoprefixer grid: no-autoplace */
```
For more information, see [Autoprefixer documentation](https://autoprefixer.github.io/).
{@a proxy}
## Proxying to a backend server
@@ -443,3 +443,5 @@ and verify that the history meets expectations:
[Back to top](guide/component-interaction#top)
@reviewed 2021-09-17
+21 -105
View File
@@ -10,7 +10,7 @@ A simple example might be a button that sends users to your company website, tha
Use the Angular CLI to generate a new library skeleton in a new workspace with the following commands.
<code-example language="bash">
ng new my-workspace --create-application=false
ng new my-workspace --no-create-application
cd my-workspace
ng generate library my-lib
</code-example>
@@ -71,9 +71,9 @@ Use an NgModule to expose services and components.
Your library should supply documentation (typically a README file) for installation and maintenance.
## Refactoring parts of an app into a library
## Refactoring parts of an application into a library
To make your solution reusable, you need to adjust it so that it does not depend on app-specific code.
To make your solution reusable, you need to adjust it so that it does not depend on application-specific code.
Here are some things to consider in migrating application functionality to a library.
* Declarations such as components and pipes should be designed as stateless, meaning they don’t rely on or alter external variables. If you do rely on state, you need to evaluate every case and decide whether it is application state or state that the library would manage.
@@ -122,7 +122,7 @@ If that form needs additional customization by the developer who is using your l
However, if the form will always be the same and not need much customization by developers, then you could create a dynamic component that takes the configuration and generates the form.
In general, the more complex the customization, the more useful the schematic approach.
To learn more, see [Schematics Overview](guide/schematics) and [Schematics for Libraries](guide/schematics-for-libraries).
For more information, see [Schematics Overview](guide/schematics) and [Schematics for Libraries](guide/schematics-for-libraries).
## Publishing your library
@@ -149,56 +149,19 @@ npm publish
## Managing assets in a library
Starting with version 9.x of the [ng-packagr](https://github.com/ng-packagr/ng-packagr/blob/master/README.md) tool, you can configure the tool to automatically copy assets into your library package as part of the build process.
Use this feature when your library needs to publish optional theming files, Sass mixins, or documentation (like a changelog).
* Learn how to [copy assets into your library as part of the build](https://github.com/ng-packagr/ng-packagr/blob/master/docs/copy-assets.md).
* Learn more about how to use the tool to [embed assets in CSS](https://github.com/ng-packagr/ng-packagr/blob/master/docs/embed-assets-css.md).
## Linked libraries
While working on a published library, use [npm link](https://docs.npmjs.com/cli/link) to avoid reinstalling the library on every build.
The library must be rebuilt on every change.
When linking a library, make sure that the build step runs in watch mode, and that the library's `package.json` configuration points at the correct entry points.
For example, `main` should point at a JavaScript file, not a TypeScript file.
### Use TypeScript path mapping for peer dependencies
In your Angular library, the distributable can include additional assets like theming files, Sass mixins, or documentation (like a changelog).
For more information [copy assets into your library as part of the build](https://github.com/ng-packagr/ng-packagr/blob/master/docs/copy-assets.md) and [embed assets in component styles](https://github.com/ng-packagr/ng-packagr/blob/master/docs/embed-assets-css.md).
## Peer dependencies
Angular libraries should list any `@angular/*` dependencies the library depends on as peer dependencies.
This ensures that when modules ask for Angular, they all get the exact same module.
If a library lists `@angular/core` in `dependencies` instead of `peerDependencies`, it might get a different Angular module instead, which would cause your application to break.
While developing a library, you must install all peer dependencies through `devDependencies` to ensure that the library compiles properly.
A linked library then has its own set of Angular libraries that it uses for building, located in its `node_modules` folder.
However, this can cause problems while building or running your application.
## Using your own library in applications
To get around this problem use TypeScript path mapping to tell TypeScript that it should load some modules from a specific location.
List all the peer dependencies that your library uses in the workspace TypeScript configuration file `./tsconfig.json`, and point them at the local copy in the application's `node_modules` folder.
You don't have to publish your library to the npm package manager to use it the same workspace, but you do have to build it first.
```
{
"compilerOptions": {
// ...
// paths are relative to `baseUrl` path.
"paths": {
"@angular/*": [
"./node_modules/@angular/*"
]
}
}
}
```
This mapping ensures that your library always loads the local copies of the modules it needs.
## Using your own library in apps
You don't have to publish your library to the npm package manager to use it in your own applications, but you do have to build it first.
To use your own library in an app:
To use your own library in an application:
* Build the library. You cannot use a library before it is built.
<code-example language="bash">
@@ -217,15 +180,17 @@ For instance, if you clone your git repository and run `npm install`, your edito
<div class="alert is-helpful">
When you import something from a library in an Angular app, Angular looks for a mapping between the library name and a location on disk.
When you import something from a library in an Angular application, Angular looks for a mapping between the library name and a location on disk.
When you install a library package, the mapping is in the `node_modules` folder. When you build your own library, it has to find the mapping in your `tsconfig` paths.
Generating a library with the Angular CLI automatically adds its path to the `tsconfig` file.
The Angular CLI uses the `tsconfig` paths to tell the build system where to find the library.
For more information, see [Path mapping overview](https://www.typescriptlang.org/docs/handbook/module-resolution.html#path-mapping).
</div>
If you find that changes to your library are not reflected in your application, your app is probably using an old build of the library.
If you find that changes to your library are not reflected in your application, your application is probably using an old build of the library.
You can rebuild your library whenever you make changes to it, but this extra step takes time.
*Incremental builds* functionality improves the library-development experience.
@@ -254,83 +219,32 @@ TypeScript path mappings should *not* point to the library source `.ts` files.
{@a ivy-libraries}
## Building libraries with Ivy
## Publishing libraries
There are three distribution formats to use when publishing a library:
There are two distribution formats to use when publishing a library:
* View Engine _(deprecated)_&mdash;legacy format, slated for removal in Angular version 13.
Only use this format if you must support View Engine applications.
* partial-Ivy **(recommended)**&mdash;contains portable code that can be consumed by Ivy applications built with any version of Angular from v12 onwards.
* full-Ivy&mdash;contains private Angular Ivy instructions, which are not guaranteed to work across different versions of Angular. This format requires that the library and application are built with the _exact_ same version of Angular. This format is useful for environments where all library and application code is built directly from source.
New libraries created with Angular CLI default to partial-Ivy format.
If you are creating a new library with `ng generate library`, Angular uses Ivy by default with no further action on your part.
### Transitioning libraries to partial-Ivy format
Existing libraries, which are configured to generate the View Engine format, do not change when upgrading to later versions of Angular that use Ivy.
If you intend to publish your library to npm, compile with partial-Ivy code by setting `"compilationMode": "partial"` in `tsconfig.prod.json`.
A library that uses View Engine, rather than Ivy, has a `tsconfig.prod.json` file that contains the following:
<code-example>
"angularCompilerOptions": {
"enableIvy": false
}
</code-example>
To convert such libraries to use the partial-Ivy format, change the `tsconfig.prod.json` file by removing the `enableIvy` option and adding the `compilationMode` option.
Enable partial-Ivy compilation by replacing `"enableIvy": false` with `"compilationMode": "partial"` as follows:
<code-example>
"angularCompilerOptions": {
"compilationMode": "partial"
}
</code-example>
For publishing to npm use the partial-Ivy format as it is stable between patch versions of Angular.
Avoid compiling libraries with full-Ivy code if you are publishing to npm because the generated Ivy instructions are not part of Angular's public API, and so might change between patch versions.
Partial-Ivy code is not backward compatible with View Engine.
If you use the library in a View Engine application, you must compile the library into the View Engine format by setting `"enableIvy": false` in the `tsconfig.json` file.
Ivy applications can still consume the View Engine format because the Angular compatibility compiler, or `ngcc`, can convert it to Ivy.
## Ensuring library version compatibility
The Angular version used to build an application should always be the same or greater than the Angular versions used to build any of its dependent libraries.
For example, if you had a library using Angular version 12, the application that depends on that library should use Angular version 12 or later.
For example, if you had a library using Angular version 13, the application that depends on that library should use Angular version 13 or later.
Angular does not support using an earlier version for the application.
<div class="alert is-helpful">
The Angular CLI uses Ivy to build applications and no longer uses View Engine.
A library or an application built with View Engine cannot consume a partial-Ivy library.
</div>
Because this process happens during the application build, it uses the same version of the Angular compiler, ensuring that the application and all of its libraries use a single version of Angular.
If you intend to publish your library to npm, compile with partial-Ivy code by setting `"compilationMode": "partial"` in `tsconfig.prod.json`.
This partial format is stable between different versions of Angular, so is safe to publish to npm.
This partial format is stable between different versions of Angular, so is safe to publish to npm. Code with this format is processed during the application build using the same version of the Angular compiler, ensuring that the application and all of its libraries use a single version of Angular.
Avoid compiling libraries with full-Ivy code if you are publishing to npm because the generated Ivy instructions are not part of Angular's public API, and so might change between patch versions.
Partial-Ivy code is not backward compatible with View Engine.
If you use the library in a View Engine application, you must compile the library into the View Engine format by setting `"enableIvy": false` in the `tsconfig.json` file.
Ivy applications can still consume the View Engine format because the Angular compatibility compiler, or `ngcc`, can convert it to Ivy in the Angular CLI.
If you've never published a package in npm before, you must create a user account. Read more in [Publishing npm Packages](https://docs.npmjs.com/getting-started/publishing-npm-packages).
## Consuming partial-Ivy code outside the Angular CLI
An application installs many Angular libraries from npm into its `node_modules` directory.
@@ -351,3 +265,5 @@ The Angular linker Babel plugin supports build caching, meaning that libraries o
The Angular CLI integrates the linker plugin automatically, so if consumers of your library are using the CLI, they can install Ivy-native libraries from npm without any additional configuration.
</div>
@reviewed 2021-10-29
+138 -310
View File
@@ -33,45 +33,44 @@ v12 - v15
v13 -> v16
-->
| Area | API or Feature | May be removed in |
|:--- |:--- |:--- |
| `@angular/common` | [`ReflectiveInjector`](#reflectiveinjector) | <!--v8--> v11 |
| `@angular/common` | [`CurrencyPipe` - `DEFAULT_CURRENCY_CODE`](api/common/CurrencyPipe#currency-code-deprecation) | <!--v9--> v11 |
| `@angular/common/http` | [`XhrFactory`](api/common/http/XhrFactory) | <!--v12--> v15 |
| `@angular/core` | [`DefaultIterableDiffer`](#core) | <!--v7--> v11 |
| `@angular/core` | [`ReflectiveKey`](#core) | <!--v8--> v11 |
| `@angular/core` | [`RenderComponentType`](#core) | <!--v7--> v11 |
| `@angular/core` | [Factory-based signature of `ApplicationRef.bootstrap`](#core) | <!--v13--> v15 |
| `@angular/core` | [`PlatformRef.bootstrapModuleFactory`](#core) | <!--v13--> v15 |
| `@angular/core` | [`getModuleFactory`](#core) | <!--v13--> v16 |
| `@angular/core` | [`ModuleWithComponentFactories`](#core) | <!--v13--> v16 |
| `@angular/core` | [`Compiler`](#core) | <!--v13--> v16 |
| `@angular/core` | [`CompilerFactory`](#core) | <!--v13--> v16 |
| `@angular/core` | [`NgModuleFactory`](#core) | <!--v13--> v16 |
| `@angular/platform-browser-dynamic` | [`JitCompilerFactory`](#platform-browser-dynamic) | <!--v13--> v16 |
| `@angular/forms` | [`ngModel` with reactive forms](#ngmodel-reactive) | <!--v6--> v11 |
| `@angular/upgrade` | [`@angular/upgrade`](#upgrade) | <!--v8--> v11 |
| `@angular/upgrade` | [`getAngularLib`](#upgrade-static) | <!--v8--> v11 |
| `@angular/upgrade` | [`setAngularLib`](#upgrade-static) | <!--v8--> v11 |
| template syntax | [`<template>`](#template-tag) | <!--v7--> v11 |
| polyfills | [reflect-metadata](#reflect-metadata) | <!--v8--> v11 |
| npm package format | [`esm5` and `fesm5` entry-points in @angular/* npm packages](guide/deprecations#esm5-fesm5) | <!-- v9 --> v11 |
| `@angular/compiler-cli` | [Input setter coercion](#input-setter-coercion) | <!--v13--> v15 |
| `@angular/compiler-cli` | [`fullTemplateTypeCheck`](#full-template-type-check) | <!--v13--> v15 |
| `@angular/core` | [`defineInjectable`](#core) | <!--v8--> v11 |
| `@angular/core` | [`entryComponents`](api/core/NgModule#entryComponents) | <!--v9--> v11 |
| `@angular/core` | [`ANALYZE_FOR_ENTRY_COMPONENTS`](api/core/ANALYZE_FOR_ENTRY_COMPONENTS) | <!--v9--> v11 |
| `@angular/core` | [Factory-based signature of `ViewContainerRef.createComponent`](api/core/ViewContainerRef#createComponent) | <!--v13--> v15 |
| `@angular/core/testing` | [`TestBed.get`](#testing) | <!--v9--> v12 |
| `@angular/core/testing` | [`async`](#testing) | <!--v9--> v12 |
| `@angular/core/testing` | [`aotSummaries` argument in `TestBed.initTestEnvironment`](#testing) | <!--v13--> v14 |
| `@angular/core/testing` | [`aotSummaries` field of the `TestModuleMetadata` type](#testing) | <!--v13--> v14 |
| `@angular/forms` | [`FormBuilder.group` legacy options parameter](api/forms/FormBuilder#group) | <!--v11--> v14 |
| `@angular/router` | [`ActivatedRoute` params and `queryParams` properties](#activatedroute-props) | unspecified |
| `@angular/service-worker` | [`SwUpdate#activated`](api/service-worker/SwUpdate#activated) | <!--v13--> v16 |
| `@angular/service-worker` | [`SwUpdate#available`](api/service-worker/SwUpdate#available) | <!--v13--> v16 |
| template syntax | [`/deep/`, `>>>`, and `::ng-deep`](#deep-component-style-selector) | <!--v7--> unspecified |
| template syntax | [`bind-`, `on-`, `bindon-`, and `ref-`](#bind-syntax) | <!--v13--> v15 |
| Area | API or Feature | May be removed in |
| :---------------------------------- | :--------------------------------------------------------------------------------------------------------- | :-------------------- |
| `@angular/common` | [`ReflectiveInjector`](#reflectiveinjector) | <!--v8--> v11 |
| `@angular/common` | [`CurrencyPipe` - `DEFAULT_CURRENCY_CODE`](api/common/CurrencyPipe#currency-code-deprecation) | <!--v9--> v11 |
| `@angular/common/http` | [`XhrFactory`](api/common/http/XhrFactory) | <!--v12--> v15 |
| `@angular/core` | [`DefaultIterableDiffer`](#core) | <!--v7--> v11 |
| `@angular/core` | [`ReflectiveKey`](#core) | <!--v8--> v11 |
| `@angular/core` | [`RenderComponentType`](#core) | <!--v7--> v11 |
| `@angular/core` | [Factory-based signature of `ApplicationRef.bootstrap`](#core) | <!--v13--> v15 |
| `@angular/core` | [`PlatformRef.bootstrapModuleFactory`](#core) | <!--v13--> v15 |
| `@angular/core` | [`getModuleFactory`](#core) | <!--v13--> v16 |
| `@angular/core` | [`ModuleWithComponentFactories`](#core) | <!--v13--> v16 |
| `@angular/core` | [`Compiler`](#core) | <!--v13--> v16 |
| `@angular/core` | [`CompilerFactory`](#core) | <!--v13--> v16 |
| `@angular/core` | [`NgModuleFactory`](#core) | <!--v13--> v16 |
| `@angular/platform-browser-dynamic` | [`JitCompilerFactory`](#platform-browser-dynamic) | <!--v13--> v16 |
| `@angular/forms` | [`ngModel` with reactive forms](#ngmodel-reactive) | <!--v6--> v11 |
| `@angular/upgrade` | [`@angular/upgrade`](#upgrade) | <!--v8--> v11 |
| `@angular/upgrade` | [`getAngularLib`](#upgrade-static) | <!--v8--> v11 |
| `@angular/upgrade` | [`setAngularLib`](#upgrade-static) | <!--v8--> v11 |
| template syntax | [`<template>`](#template-tag) | <!--v7--> v11 |
| polyfills | [reflect-metadata](#reflect-metadata) | <!--v8--> v11 |
| `@angular/compiler-cli` | [Input setter coercion](#input-setter-coercion) | <!--v13--> v15 |
| `@angular/compiler-cli` | [`fullTemplateTypeCheck`](#full-template-type-check) | <!--v13--> v15 |
| `@angular/core` | [`defineInjectable`](#core) | <!--v8--> v11 |
| `@angular/core` | [`entryComponents`](api/core/NgModule#entryComponents) | <!--v9--> v11 |
| `@angular/core` | [`ANALYZE_FOR_ENTRY_COMPONENTS`](api/core/ANALYZE_FOR_ENTRY_COMPONENTS) | <!--v9--> v11 |
| `@angular/core` | [Factory-based signature of `ViewContainerRef.createComponent`](api/core/ViewContainerRef#createComponent) | <!--v13--> v15 |
| `@angular/core/testing` | [`TestBed.get`](#testing) | <!--v9--> v12 |
| `@angular/core/testing` | [`async`](#testing) | <!--v9--> v12 |
| `@angular/core/testing` | [`aotSummaries` argument in `TestBed.initTestEnvironment`](#testing) | <!--v13--> v14 |
| `@angular/core/testing` | [`aotSummaries` field of the `TestModuleMetadata` type](#testing) | <!--v13--> v14 |
| `@angular/forms` | [`FormBuilder.group` legacy options parameter](api/forms/FormBuilder#group) | <!--v11--> v14 |
| `@angular/platform-server` | [`renderModuleFactory`](#platform-server) | <!--v13--> v15 |
| `@angular/service-worker` | [`SwUpdate#activated`](api/service-worker/SwUpdate#activated) | <!--v13--> v16 |
| `@angular/service-worker` | [`SwUpdate#available`](api/service-worker/SwUpdate#available) | <!--v13--> v16 |
| template syntax | [`/deep/`, `>>>`, and `::ng-deep`](#deep-component-style-selector) | <!--v7--> unspecified |
| template syntax | [`bind-`, `on-`, `bindon-`, and `ref-`](#bind-syntax) | <!--v13--> v15 |
For information about Angular CDK and Angular Material deprecations, see the [changelog](https://github.com/angular/components/blob/master/CHANGELOG.md).
@@ -90,7 +89,7 @@ This section contains a complete list all of the currently-deprecated APIs, with
### @angular/common
| API | Replacement | Deprecation announced | Notes |
| :--- |:--- |:--- |:--- |
| :-------------------------------------------------------------------------------------------- | :-------------------------------------------------- | :-------------------- | :-------------------------------------------------------------------------------------------------------- |
| [`CurrencyPipe` - `DEFAULT_CURRENCY_CODE`](api/common/CurrencyPipe#currency-code-deprecation) | `{provide: DEFAULT_CURRENCY_CODE, useValue: 'USD'}` | v9 | From v11 the default code will be extracted from the locale data given by `LOCALE_ID`, rather than `USD`. |
{@a common-http}
@@ -98,57 +97,65 @@ This section contains a complete list all of the currently-deprecated APIs, with
### @angular/common/http
| API | Replacement | Deprecation announced | Notes |
|:--- |:--- |:--- |:--- |
| :----------------------------------------- | :-------------------------------- | :-------------------- | :--------------------------------------------------------------------------- |
| [`XhrFactory`](api/common/http/XhrFactory) | `XhrFactory` in `@angular/common` | v12 | The `XhrFactory` has moved from `@angular/common/http` to `@angular/common`. |
{@a core}
### @angular/core
| API | Replacement | Deprecation announced | Notes |
|:--- |:--- |:--- |:--- |
| [`DefaultIterableDiffer`](api/core/DefaultIterableDiffer) | n/a | v4 | Not part of public API. |
| [`ReflectiveInjector`](api/core/ReflectiveInjector) | `{@link Injector#create Injector.create()}` | v5 | See [`ReflectiveInjector`](#reflectiveinjector) |
| [`ReflectiveKey`](api/core/ReflectiveKey) | none | v5 | none |
| [`defineInjectable`](api/core/defineInjectable) | `ɵɵdefineInjectable` | v8 | Used only in generated code. No source code should depend on this API. |
| [`entryComponents`](api/core/NgModule#entryComponents) | none | v9 | See [`entryComponents`](#entryComponents) |
| [`ANALYZE_FOR_ENTRY_COMPONENTS`](api/core/ANALYZE_FOR_ENTRY_COMPONENTS) | none | v9 | See [`ANALYZE_FOR_ENTRY_COMPONENTS`](#entryComponents) |
| [`async`](api/core/testing/async) | [`waitForAsync`](api/core/testing/waitForAsync) | v11 | The [`async`](api/core/testing/async) function from `@angular/core/testing` has been renamed to `waitForAsync` in order to avoid confusion with the native JavaScript <code class="no-auto-link">async</code> syntax. The existing function is deprecated and will be removed in a future version. |
| [`getModuleFactory`](api/core/getModuleFactory) | [`getNgModuleById`](api/core/getNgModuleById) | v13 | Ivy allows working with NgModule classes directly, without retrieving corresponding factories. |
| `ViewChildren.emitDistinctChangesOnly` / `ContentChildren.emitDistinctChangesOnly` | none (was part of [issue #40091](https://github.com/angular/angular/issues/40091)) | | This is a temporary flag introduced as part of bugfix of [issue #40091](https://github.com/angular/angular/issues/40091) and will be removed. |
| Factory-based signature of [`ApplicationRef.bootstrap`](api/core/ApplicationRef#bootstrap) | Type-based signature of [`ApplicationRef.bootstrap`](api/core/ApplicationRef#bootstrap) | v13 | With Ivy, there is no need to resolve Component factory and Component Type can be provided directly. |
| [`PlatformRef.bootstrapModuleFactory`](api/core/PlatformRef#bootstrapModuleFactory) | [`PlatformRef.bootstrapModule`](api/core/PlatformRef#bootstrapModule) | v13 | With Ivy, there is no need to resolve NgModule factory and NgModule Type can be provided directly. |
| [`ModuleWithComponentFactories`](api/core/ModuleWithComponentFactories) | none | v13 | Ivy JIT mode doesn't require accessing this symbol. See [JIT API changes due to ViewEngine deprecation](#jit-api-changes) for additional context. |
| [`Compiler`](api/core/Compiler) | none | v13 | Ivy JIT mode doesn't require accessing this symbol. See [JIT API changes due to ViewEngine deprecation](#jit-api-changes) for additional context. |
| [`CompilerFactory`](api/core/CompilerFactory) | none | v13 | Ivy JIT mode doesn't require accessing this symbol. See [JIT API changes due to ViewEngine deprecation](#jit-api-changes) for additional context. |
| [`NgModuleFactory`](api/core/NgModuleFactory) | Use non-factory based framework APIs like [PlatformRef.bootstrapModule](api/core/PlatformRef#bootstrapModule) and [createNgModuleRef](api/core/createNgModuleRef) | v13 | Ivy JIT mode doesn't require accessing this symbol. See [JIT API changes due to ViewEngine deprecation](#jit-api-changes) for additional context. |
| [Factory-based signature of `ViewContainerRef.createComponent`](api/core/ViewContainerRef#createComponent) | [Type-based signature of `ViewContainerRef.createComponent`](api/core/ViewContainerRef#createComponent) | v13 | Angular no longer requires component factories to dynamically create components. Use different signature of the `createComponent` method, which allows passing Component class directly. |
{@a platform-browser-dynamic}
### @angular/platform-browser-dynamic
| API | Replacement | Deprecation announced | Notes |
|:--- |:--- |:--- |:--- |
| [`JitCompilerFactory`](api/platform-browser-dynamic/JitCompilerFactory) | none | v13 | Ivy JIT mode doesn't require accessing this symbol. See [JIT API changes due to ViewEngine deprecation](#jit-api-changes) for additional context. |
| API | Replacement | Deprecation announced | Notes |
| :--------------------------------------------------------------------------------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------- | :-------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [`DefaultIterableDiffer`](api/core/DefaultIterableDiffer) | n/a | v4 | Not part of public API. |
| [`ReflectiveInjector`](api/core/ReflectiveInjector) | `{@link Injector#create Injector.create()}` | v5 | See [`ReflectiveInjector`](#reflectiveinjector) |
| [`ReflectiveKey`](api/core/ReflectiveKey) | none | v5 | none |
| [`defineInjectable`](api/core/defineInjectable) | `ɵɵdefineInjectable` | v8 | Used only in generated code. No source code should depend on this API. |
| [`entryComponents`](api/core/NgModule#entryComponents) | none | v9 | See [`entryComponents`](#entryComponents) |
| [`ANALYZE_FOR_ENTRY_COMPONENTS`](api/core/ANALYZE_FOR_ENTRY_COMPONENTS) | none | v9 | See [`ANALYZE_FOR_ENTRY_COMPONENTS`](#entryComponents) |
| [`async`](api/core/testing/async) | [`waitForAsync`](api/core/testing/waitForAsync) | v11 | The [`async`](api/core/testing/async) function from `@angular/core/testing` has been renamed to `waitForAsync` in order to avoid confusion with the native JavaScript <code class="no-auto-link">async</code> syntax. The existing function is deprecated and will be removed in a future version. |
| [`getModuleFactory`](api/core/getModuleFactory) | [`getNgModuleById`](api/core/getNgModuleById) | v13 | Ivy allows working with NgModule classes directly, without retrieving corresponding factories. |
| `ViewChildren.emitDistinctChangesOnly` / `ContentChildren.emitDistinctChangesOnly` | none (was part of [issue #40091](https://github.com/angular/angular/issues/40091)) | | This is a temporary flag introduced as part of bugfix of [issue #40091](https://github.com/angular/angular/issues/40091) and will be removed. |
| Factory-based signature of [`ApplicationRef.bootstrap`](api/core/ApplicationRef#bootstrap) | Type-based signature of [`ApplicationRef.bootstrap`](api/core/ApplicationRef#bootstrap) | v13 | With Ivy, there is no need to resolve Component factory and Component Type can be provided directly. |
| [`PlatformRef.bootstrapModuleFactory`](api/core/PlatformRef#bootstrapModuleFactory) | [`PlatformRef.bootstrapModule`](api/core/PlatformRef#bootstrapModule) | v13 | With Ivy, there is no need to resolve NgModule factory and NgModule Type can be provided directly. |
| [`ModuleWithComponentFactories`](api/core/ModuleWithComponentFactories) | none | v13 | Ivy JIT mode doesn't require accessing this symbol. See [JIT API changes due to ViewEngine deprecation](#jit-api-changes) for additional context. |
| [`Compiler`](api/core/Compiler) | none | v13 | Ivy JIT mode doesn't require accessing this symbol. See [JIT API changes due to ViewEngine deprecation](#jit-api-changes) for additional context. |
| [`CompilerFactory`](api/core/CompilerFactory) | none | v13 | Ivy JIT mode doesn't require accessing this symbol. See [JIT API changes due to ViewEngine deprecation](#jit-api-changes) for additional context. |
| [`NgModuleFactory`](api/core/NgModuleFactory) | Use non-factory based framework APIs like [PlatformRef.bootstrapModule](api/core/PlatformRef#bootstrapModule) and [createNgModuleRef](api/core/createNgModuleRef) | v13 | Ivy JIT mode doesn't require accessing this symbol. See [JIT API changes due to ViewEngine deprecation](#jit-api-changes) for additional context. |
| [Factory-based signature of `ViewContainerRef.createComponent`](api/core/ViewContainerRef#createComponent) | [Type-based signature of `ViewContainerRef.createComponent`](api/core/ViewContainerRef#createComponent) | v13 | Angular no longer requires component factories to dynamically create components. Use different signature of the `createComponent` method, which allows passing Component class directly. |
{@a testing}
### @angular/core/testing
| API | Replacement | Deprecation announced | Notes |
|:--- |:--- |:--- |:--- |
| [`TestBed.get`](api/core/testing/TestBed#get) | [`TestBed.inject`](api/core/testing/TestBed#inject) | v9 | Same behavior, but type safe. |
| [`async`](api/core/testing/async) | [`waitForAsync`](api/core/testing/waitForAsync) | v10 | Same behavior, but rename to avoid confusion. |
| [`aotSummaries` argument in `TestBed.initTestEnvironment`](api/core/testing/TestBed#inittestenvironment) | No replacement needed | v13 | Summary files are unused in Ivy. |
| [`aotSummaries` field of the `TestModuleMetadata` type](api/core/testing/TestModuleMetadata) | No replacement needed | v13 | Summary files are unused in Ivy. |
| API | Replacement | Deprecation announced | Notes |
| :------------------------------------------------------------------------------------------------------- | :-------------------------------------------------- | :-------------------- | :-------------------------------------------- |
| [`TestBed.get`](api/core/testing/TestBed#get) | [`TestBed.inject`](api/core/testing/TestBed#inject) | v9 | Same behavior, but type safe. |
| [`async`](api/core/testing/async) | [`waitForAsync`](api/core/testing/waitForAsync) | v10 | Same behavior, but rename to avoid confusion. |
| [`aotSummaries` argument in `TestBed.initTestEnvironment`](api/core/testing/TestBed#inittestenvironment) | No replacement needed | v13 | Summary files are unused in Ivy. |
| [`aotSummaries` field of the `TestModuleMetadata` type](api/core/testing/TestModuleMetadata) | No replacement needed | v13 | Summary files are unused in Ivy. |
{@a platform-browser-dynamic}
### @angular/platform-browser-dynamic
| API | Replacement | Deprecation announced | Notes |
| :---------------------------------------------------------------------- | :---------- | :-------------------- | :-------------------------------------------------------------------------------------------------------------------------------- |
| [`JitCompilerFactory`](api/platform-browser-dynamic/JitCompilerFactory) | none | v13 | This symbol is no longer necessary. See [JIT API changes due to ViewEngine deprecation](#jit-api-changes) for additional context. |
{@a platform-server}
### @angular/platform-server
| API | Replacement | Deprecation announced | Notes |
| :--------------------------------------------------------------- | :------------------------------------------------- | :-------------------- | :-------------------------------------------------------------------------------------------------------------------------------- |
| [`renderModuleFactory`](api/platform-server/renderModuleFactory) | [`renderModule`](api/platform-server/renderModule) | v13 | This symbol is no longer necessary. See [JIT API changes due to ViewEngine deprecation](#jit-api-changes) for additional context. |
{@a forms}
### @angular/forms
| API | Replacement | Deprecation announced | Notes |
|:--- |:--- |:--- |:--- |
| :-------------------------------------------------------------------------- | :--------------------------------------------------------------------------- | :-------------------- | :---- |
| [`ngModel` with reactive forms](#ngmodel-reactive) | [`FormControlDirective`](api/forms/FormControlDirective) | v6 | none |
| [`FormBuilder.group` legacy options parameter](api/forms/FormBuilder#group) | [`AbstractControlOptions` parameter value](api/forms/AbstractControlOptions) | v11 | none |
@@ -156,17 +163,17 @@ This section contains a complete list all of the currently-deprecated APIs, with
### @angular/service-worker
| API | Replacement | Deprecation announced | Notes
|:--- |:--- |:--- |:---
| [`SwUpdate#activated`](api/service-worker/SwUpdate#activated) | [`SwUpdate#activateUpdate()` return value](api/service-worker/SwUpdate#activateUpdate) | v13 | The return value of `SwUpdate#activateUpdate()` indicates whether an update was successfully activated. |
| [`SwUpdate#available`](api/service-worker/SwUpdate#available) | [`SwUpdate#versionUpdates`](api/service-worker/SwUpdate#versionUpdates) | v13 | The behavior of `SwUpdate#available` can be rebuilt by filtering for `VersionReadyEvent` events on [`SwUpdate#versionUpdates`](api/service-worker/SwUpdate#versionUpdates) |
| API | Replacement | Deprecation announced | Notes |
| :------------------------------------------------------------ | :------------------------------------------------------------------------------------- | :-------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [`SwUpdate#activated`](api/service-worker/SwUpdate#activated) | [`SwUpdate#activateUpdate()` return value](api/service-worker/SwUpdate#activateUpdate) | v13 | The return value of `SwUpdate#activateUpdate()` indicates whether an update was successfully activated. |
| [`SwUpdate#available`](api/service-worker/SwUpdate#available) | [`SwUpdate#versionUpdates`](api/service-worker/SwUpdate#versionUpdates) | v13 | The behavior of `SwUpdate#available` can be rebuilt by filtering for `VersionReadyEvent` events on [`SwUpdate#versionUpdates`](api/service-worker/SwUpdate#versionUpdates) |
{@a upgrade}
### @angular/upgrade
| API | Replacement | Deprecation announced | Notes |
|:--- |:--- |:--- |:--- |
| :------------------------------ | :---------------------------------------------- | :-------------------- | :--------------------------------------------- |
| [All entry points](api/upgrade) | [`@angular/upgrade/static`](api/upgrade/static) | v5 | See [Upgrading from AngularJS](guide/upgrade). |
{@a upgrade-static}
@@ -174,7 +181,7 @@ This section contains a complete list all of the currently-deprecated APIs, with
### @angular/upgrade/static
| API | Replacement | Deprecation announced | Notes |
|:--- |:--- |:--- |:--- |
| :-------------------------------------------------- | :------------------------------------------------------------ | :-------------------- | :--------------------------------------------- |
| [`getAngularLib`](api/upgrade/static/getAngularLib) | [`getAngularJSGlobal`](api/upgrade/static/getAngularJSGlobal) | v5 | See [Upgrading from AngularJS](guide/upgrade). |
| [`setAngularLib`](api/upgrade/static/setAngularLib) | [`setAngularJSGlobal`](api/upgrade/static/setAngularJSGlobal) | v5 | See [Upgrading from AngularJS](guide/upgrade). |
@@ -232,17 +239,9 @@ Support for using the `ngModel` input property and `ngModelChange` event with re
Now deprecated:
<code-example language="html">
<code-example path="deprecation-guide/src/app/app.component.html" region="deprecated-example" language="html"></code-example>
&lt;input [formControl]="control" [(ngModel)]="value"&gt;
</code-example>
<code-example language="typescript">
this.value = 'some value';
</code-example>
<code-example path="deprecation-guide/src/app/app.component.ts" region="deprecated-example"></code-example>
This support was deprecated for several reasons. First, developers found this pattern confusing. It seems like the actual `ngModel` directive is being used, but in fact it's an input/output property named `ngModel` on the reactive form directive that approximates some, but not all, of the directive's behavior.
It allows getting and setting a value and intercepting value events, but some of `ngModel`'s other features, such as delaying updates with`ngModelOptions` or exporting the directive, don't work.
@@ -254,41 +253,19 @@ To update your code before support is removed, you'll want to decide whether to
**After** (choice 1 - use reactive forms):
<code-example language="html">
<code-example path="deprecation-guide/src/app/app.component.html" region="reactive-form-example" language="html"></code-example>
&lt;input [formControl]="control"&gt;
</code-example>
<code-example language="typescript">
this.control.setValue('some value');
</code-example>
<code-example path="deprecation-guide/src/app/app.component.ts" region="reactive-form-example"></code-example>
**After** (choice 2 - use template-driven forms):
<code-example language="html">
<code-example path="deprecation-guide/src/app/app.component.html" region="template-driven-form-example" language="html"></code-example>
&lt;input [(ngModel)]="value"&gt;
</code-example>
<code-example language="typescript">
this.value = 'some value';
</code-example>
<code-example path="deprecation-guide/src/app/app.component.ts" region="template-driven-form-example"></code-example>
By default, when you use this pattern, you will see a deprecation warning once in dev mode. You can choose to silence this warning by configuring `ReactiveFormsModule` at import time:
<code-example language="typescript">
imports: [
ReactiveFormsModule.withConfig({warnOnNgModelWithFormControl: 'never'});
]
</code-example>
<code-example path="deprecation-guide/src/app/app.module.ts" region="reactive-form-no-warning"></code-example>
Alternatively, you can choose to surface a separate warning for each instance of this pattern with a configuration value of `"always"`. This may help to track down where in the code the pattern is being used as the code is being updated.
@@ -300,19 +277,11 @@ In v5, Angular replaced the `ReflectiveInjector` with the `StaticInjector`. The
**Before**:
<code-example language="typescript">
ReflectiveInjector.resolveAndCreate(providers);
</code-example>
<code-example path="deprecation-guide/src/app/app.component.ts" language="typescript" region="reflective-injector-deprecated-example"></code-example>
**After**:
<code-example language="typescript">
Injector.create({providers});
</code-example>
<code-example path="deprecation-guide/src/app/app.component.ts" language="typescript" region="static-injector-example"></code-example>
{@a loadChildren}
@@ -324,27 +293,11 @@ In version 8, the string syntax for the [`loadChildren`](api/router/LoadChildren
**Before**:
<code-example language="typescript">
const routes: Routes = [{
path: 'lazy',
// The following string syntax for loadChildren is deprecated
loadChildren: './lazy/lazy.module#LazyModule'
}];
</code-example>
<code-example path="deprecation-guide/src/app/app.module.ts" language="typescript" region="lazyload-deprecated-syntax"></code-example>
**After**:
<code-example language="typescript">
const routes: Routes = [{
path: 'lazy',
// The new import() syntax
loadChildren: () => import('./lazy/lazy.module').then(m => m.LazyModule)
}];
</code-example>
<code-example path="deprecation-guide/src/app/app.module.ts" language="typescript" region="lazyload-syntax"></code-example>
<div class="alert is-helpful">
@@ -358,18 +311,6 @@ const routes: Routes = [{
</div>
{@a activatedroute-props}
### ActivatedRoute params and queryParams properties
[ActivatedRoute](api/router/ActivatedRoute) contains two [properties](api/router/ActivatedRoute#properties) that are less capable than their replacements and may be deprecated in a future Angular version.
| Property | Replacement |
| -------- | ----------- |
| `params` | `paramMap` |
| `queryParams` | `queryParamMap` |
For more information see the [Getting route information](guide/router-reference#activated-route) section of the [Router guide](guide/router).
{@a reflect-metadata}
@@ -393,21 +334,12 @@ See the [dedicated migration guide for static queries](guide/static-query-migrat
The following pattern is deprecated:
<code-example language="typescript">
@Input() @ContentChild(TemplateRef) tpl !: TemplateRef&lt;any&gt;;
</code-example>
<code-example path="deprecation-guide/src/app/app.component.ts" language="typescript" region="template-with-input-deprecated"></code-example>
Rather than using this pattern, separate the two decorators into their own
properties and add fallback logic as in the following example:
<code-example language="typescript">
@Input() tpl !: TemplateRef&lt;any&gt;;
@ContentChild(TemplateRef) inlineTemplate !: TemplateRef&lt;any&gt;;
</code-example>
<code-example path="deprecation-guide/src/app/app.component.ts" language="typescript" region="template-with-input"></code-example>
{@a cant-assign-template-vars}
@@ -416,19 +348,11 @@ properties and add fallback logic as in the following example:
In the following example, the two-way binding means that `optionName`
should be written when the `valueChange` event fires.
<code-example language="html">
&lt;option *ngFor="let optionName of options" [(value)]="optionName"&gt;&lt;/option&gt;
</code-example>
<code-example path="deprecation-guide/src/app/app.component.1.html" region="two-way-template-deprecated"></code-example>
However, in practice, Angular ignores two-way bindings to template variables. Starting in version 8, attempting to write to template variables is deprecated. In a future version, we will throw to indicate that the write is not supported.
<code-example language="html">
&lt;option *ngFor="let optionName of options" [value]="optionName"&gt;&lt;/option&gt;
</code-example>
<code-example path="deprecation-guide/src/app/app.component.html" region="valid-template-bind"></code-example>
{@a binding-to-innertext}
@@ -469,39 +393,11 @@ For example:
**Before**
<code-example language="typescript">
@NgModule({...})
export class MyModule {
static forRoot(config: SomeConfig): ModuleWithProviders {
return {
ngModule: SomeModule,
providers: [
{provide: SomeConfig, useValue: config}
]
};
}
}
</code-example>
<code-example path="deprecation-guide/src/app/app.module.ts" language="typescript" region="ModuleWithProvidersNonGeneric"></code-example>
**After**:
<code-example language="typescript">
@NgModule({...})
export class MyModule {
static forRoot(config: SomeConfig): ModuleWithProviders<SomeModule> {
return {
ngModule: SomeModule,
providers: [
{provide: SomeConfig, useValue: config }
]
};
}
}
</code-example>
<code-example path="deprecation-guide/src/app/app.module.ts" language="typescript" region="ModuleWithProvidersGeneric"></code-example>
<!--
### Internet Explorer 11
@@ -527,41 +423,11 @@ This means that input coercion fields are no longer needed, as their effects can
For example, the following directive:
```typescript
@Component({...})
class SubmitButton {
private _disabled: boolean;
@Input()
get disabled(): boolean {
return this._disabled;
}
set disabled(value: boolean) {
this._disabled = (value === '') || value;
}
static ngAcceptInputType_disabled: boolean|'';
}
```
<code-example path="deprecation-guide/src/app/submit-button/submit-button.component.ts" language="typescript" region="submitButtonNarrow"></code-example>
can be refactored as follows:
```typescript
@Component({...})
class SubmitButton {
private _disabled: boolean;
@Input()
get disabled(): boolean {
return this._disabled;
}
set disabled(value: boolean|'') {
this._disabled = (value === '') || value;
}
}
```
<code-example path="deprecation-guide/src/app/submit-button/submit-button.component.ts" language="typescript" region="submitButton"></code-example>
{@a full-template-type-check}
### `fullTemplateTypeCheck`
@@ -608,89 +474,39 @@ Important note: this deprecation doesn't affect JIT mode in Ivy (JIT remains ava
This section contains a complete list all of the currently deprecated CLI flags.
### @angular/cli
| API/Option | May be removed in | Notes |
| ----------------- | ----------------- | ----------------------------------------- |
| `--prod` | <!--v12--> v14 | Use `--configuration production` instead. |
| `ng update --all` | <!--v11--> v14 | No longer has an effect. |
### @angular-devkit/build-angular
| API/Option | May be removed in | Notes |
| ------------------------- | ----------------- | -------------------------------------------------------------------------------------------------------------- |
| `extractCss` | <!--v11--> v13 | No longer required to disable CSS extraction during development. |
| `i18nFormat` | <!--v9--> v12 | Format is now automatically detected. |
| `i18nLocale` | <!--v9--> v12 | New [localization option][AioGuideI18nCommonMergeDefineLocalesInTheBuildConfiguration] in version 9 and later. |
| `hmrWarning` | <!--v11--> v13 | No longer has an effect. |
| `servePathDefaultWarning` | <!--v11--> v13 | No longer has an effect. |
| API/Option | May be removed in | Notes |
| -------------------------- | ----------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `deployUrl` | <!--v13--> v15 | Use `baseHref` option, `APP_BASE_HREF` DI token or a combination of both instead. For more information, see [the deploy url](guide/deployment#the-deploy-url). |
| `showCircularDependencies` | <!--v12--> v14 | The recommended method to detect circular dependencies in project code is to use either a lint rule or other external tooling. |
| Protractor builder | <!--v12--> v14 | Deprecate as part of the Protractor deprecation. |
### @schematics/angular
### @angular-devkit/build-optimizer
| API/Option | May be removed in | Notes |
| ------------------------------- | ----------------- |-------------------------------------------------------------------------------- |
| `lintFix` | <!--v11--> v12 | Deprecated as part of TSLint deprecation. |
The entire NPM package is deprecated. It has always been experimental (never hit `1.0.0`) and has
been an internal package for the Angular CLI. All the relevant functionality has been moved to
`@angular-devkit/build-angular`.
{@a removed}
## Removed APIs
The following APIs have been removed starting with version 11.0.0*:
The following APIs have been removed starting with version 11.0.0\*:
| Package | API | Replacement | Notes |
| ---------------- | -------------- | ----------- | ----- |
| `@angular/router` | `preserveQueryParams` | [`queryParamsHandling`](api/router/UrlCreationOptions#queryParamsHandling) | |
| Package | API | Replacement | Notes |
| ----------------- | --------------------- | -------------------------------------------------------------------------- | ----- |
| `@angular/router` | `preserveQueryParams` | [`queryParamsHandling`](api/router/UrlCreationOptions#queryParamsHandling) | |
\* To see APIs removed in version 10, check out this guide on the [version 10 docs site](https://v10.angular.io/guide/deprecations#removed).
{@a esm5-fesm5}
### `esm5` and `fesm5` code formats in @angular/* npm packages
As of Angular v8, the CLI primarily consumes the `fesm2015` variant of the code distributed as part of `@angular/*` npm packages.
This renders the `esm5` and `fesm5` distributions obsolete and unnecessary, adding bloat to the package size and slowing down npm installations.
This removal has no impact on CLI users, unless they modified their build configuration to explicitly consume these code distributions.
Any application still relying on the `esm5` and `fesm5` as the input to its build system will need to ensure that the build pipeline is capable of accepting JavaScript code conforming to ECMAScript 2015 (ES2015) language specification.
Note that this change doesn't make existing libraries distributed in this format incompatible with the Angular CLI.
The CLI will fall back and consume libraries in less desirable formats if others are not available.
However, we do recommend that libraries ship their code in ES2015 format in order to make builds faster and build output smaller.
In practical terms, the `package.json` of all `@angular` packages has changed in the following way:
**Before**:
<code-example language="json" header="package.app.json">
{
"name": "@angular/core",
"version": "9.0.0",
"main": "./bundles/core.umd.js",
"module": "./fesm5/core.js",
"es2015": "./fesm2015/core.js",
"esm5": "./esm5/core.js",
"esm2015": "./esm2015/core.js",
"fesm5": "./fesm5/core.js",
"fesm2015": "./fesm2015/core.js",
...
}
</code-example>
**After**:
<code-example language="json" header="package.app.json">
{
"name": "@angular/core",
"version": "10.0.0",
"main": "./bundles/core.umd.js",
"module": "./fesm2015/core.js",
"es2015": "./fesm2015/core.js",
"esm2015": "./esm2015/core.js",
"fesm2015": "./fesm2015/core.js",
...
}
</code-example>
For more information about the npm package format, see the [Angular Package Format spec](https://goo.gl/jB3GVv).
{@a style-sanitization}
### Style Sanitization for `[style]` and `[style.prop]` bindings
@@ -706,6 +522,18 @@ Find more information about the replacement in the [`LoadChildrenCallback` docum
The supporting classes `NgModuleFactoryLoader`, `SystemJsNgModuleLoader` and `SystemJsNgModuleLoaderConfig` classes were removed from `@angular/core`, as well as `SpyNgModuleFactoryLoader` from `@angular/router`.
### `WrappedValue`
The purpose of `WrappedValue` was to allow the same object instance to be treated as different for the purposes of change detection.
It was commonly used with the `async` pipe in the case where the `Observable` produces the same instance of the value.
Given that this use case is relatively rare and special handling impacted application performance, the `WrappedValue` API has been removed in Angular 13.
If you rely on the behavior that the same object instance should cause change detection, you have two options:
- Clone the resulting value so that it has a new identity.
- Explicitly call [`ChangeDetectorRef.detectChanges()`](api/core/ChangeDetectorRef#detectchanges) to force the update.
<!-- links -->
[AioGuideI18nCommonMergeDefineLocalesInTheBuildConfiguration]: guide/i18n-common-merge#define-locales-in-the-build-configuration "Define locales in the build configuration - Common Internationalization task #6: Merge translations into the application | Angular"
@@ -1,8 +1,6 @@
# Dynamic component loader
Component templates are not always fixed. An application might need to load new components at runtime.
This cookbook shows you how to use `ComponentFactoryResolver` to add components dynamically.
Component templates are not always fixed. An application might need to load new components at runtime. This cookbook shows you how to add components dynamically.
See the <live-example name="dynamic-component-loader"></live-example>
of the code in this cookbook.
@@ -113,10 +111,6 @@ value to select an `adItem` from the array.
After `loadComponent()` selects an ad, it uses `ComponentFactoryResolver`
to resolve a `ComponentFactory` for each specific component.
The `ComponentFactory` then creates an instance of each component.
Next, you're targeting the `viewContainerRef` that
exists on this specific instance of the component. How do you know it's
this specific instance? Because it's referring to `adHost` and `adHost` is the
+2 -9
View File
@@ -123,21 +123,14 @@ The recently-developed [custom elements](https://developer.mozilla.org/en-US/doc
</tr>
</table>
In browsers that support Custom Elements natively, the specification requires developers use ES2015 classes to define Custom Elements - developers can opt-in to this by setting the `target: "es2015"` property in their project's [TypeScript configuration file](/guide/typescript-configuration). As Custom Element and ES2015 support might not be available in all browsers, developers can instead choose to use a polyfill to support older browsers and ES5 code.
Use the [Angular CLI](cli) to automatically set up your project with the correct polyfill:
Use the [Angular CLI](cli) to add the `@angular/elements` package to your workspace.
<code-example language="sh">
ng add @angular/elements --project=*your_project_name*
npm install @angular/elements --save
</code-example>
- For more information about polyfills, see [polyfill documentation](https://www.webcomponents.org/polyfills).
- For more information about Angular browser support, see [Browser Support](guide/browser-support).
## Example: A Popup Service
Previously, when you wanted to add a component to an application at runtime, you had to define a _dynamic component_, and then you would have to load it, attach it to an element in the DOM, and wire up all of the dependencies, change detection, and event handling, as described in [Dynamic Component Loader](guide/dynamic-component-loader).
+3 -2
View File
@@ -2,8 +2,9 @@
<div class="alert is-helpful">
Entry components have been deprecated with the [Ivy rendering engine](guide/ivy).
For more information, see [entryComponents deprecation](guide/deprecations#entrycomponents-and-analyze_for_entry_components-no-longer-required) in the [Deprecated APIs and features](guide/deprecations).
Entry components are deprecated, for more information, see
[entryComponents deprecation](guide/deprecations#entrycomponents-and-analyze_for_entry_components-no-longer-required)
in the [Deprecated APIs and features](guide/deprecations).
</div>
+1 -1
View File
@@ -55,7 +55,7 @@ of some of the things they contain:
<tr>
<td><code>HttpClientModule</code></td>
<td><code>@angular/common/http</code></td>
<td>When you want to talk to a server</td>
<td>When you want to communicate with a server using the HTTP protocol</td>
</tr>
</table>
+14 -5
View File
@@ -34,6 +34,14 @@ An Angular [component](#component) packaged as a [custom element](#custom-elemen
Learn more in [Angular Elements Overview](guide/elements).
{@a apf}
## Angular package format (APF)
An Angular specific specification for layout of npm packages that is used by all first-party Angular packages, and most third-party Angular libraries.
Learn more in the [Angular Package Format specification](guide/angular-package-format).
{@a annotation}
## annotation
@@ -495,10 +503,9 @@ Read more in the [Interpolation](guide/interpolation) guide.
## Ivy
Ivy is the code name for Angular's [next-generation compilation and rendering pipeline](https://blog.angular.io/a-plan-for-version-8-0-and-ivy-b3318dfc19f7).
With the version 9 release of Angular, the new compiler and runtime instructions are used by default instead of the older compiler and runtime, known as [View Engine](#ve).
See [Angular Ivy](guide/ivy).
Ivy is the historical code name for Angular's current
[compilation and rendering pipeline](https://blog.angular.io/a-plan-for-version-8-0-and-ivy-b3318dfc19f7).
It is now the only supported engine, so everything uses Ivy.
{@a J}
@@ -1061,7 +1068,9 @@ View hierarchies can be loaded and unloaded dynamically as the user navigates th
## View Engine
The compilation and rendering pipeline used by Angular before version 9. Compare [Ivy](#ivy).
A previous compilation and rendering pipeline used by Angular. It has since been replaced by
[Ivy](#ivy) and is no longer in use. View Engine was deprecated in version 9 and removed in version
13.
{@a view-tree}
@@ -1072,7 +1072,7 @@ the service becomes available only in the `VillainsListComponent` and its sub-co
`VillainService` is a singleton with respect to `VillainsListComponent`
because that is where it is declared. As long as `VillainsListComponent`
does not get destroyed it will be the same instance of `VillainService`
but if there are multilple instances of `VillainsListComponent`, then each
but if there are multiple instances of `VillainsListComponent`, then each
instance of `VillainsListComponent` will have its own instance of `VillainService`.
+15 -8
View File
@@ -1,28 +1,35 @@
# Add the localize package
{@a setting-up-cli}
{@a add-localize}
To take advantage of the localization features of Angular, use the [Angular CLI][AioCliMain] to add the `@angular/localize` package to your project.
To take advantage of the localization features of Angular, use the Angular CLI to add the `@angular/localize` package to your project.
To add the `@angular/localize` package, use the following command to update the `package.json` and `polyfills.ts` files in your project.
<code-example path="i18n/doc-files/commands.sh" region="add-localize" language="sh"></code-example>
This command updates the `package.json` and `polyfills.ts` files of your project to import the `@angular/localize` package.
<div class="alert is-helpful">
For more information about `package.json` and polyfill packages, see [Workspace npm dependencies][AioGuideNpmPackages].
For more information about `package.json` and `polyfill.ts` files, see [Workspace npm dependencies][AioGuideNpmPackages].
</div>
If `@angular/localize` is not installed, the Angular CLI may generate an error when you try to build a localized version of your application.
If `@angular/localize` is not installed and you try to build a localized version of your project, the [Angular CLI][AioCliMain] generates an error.
<!--todo: add example error -->
## What's next
* [Refer to locales by ID][AioGuideI18nCommonLocaleId]
<!-- links -->
[AioCliMain]: cli "CLI Overview and Command Reference | Angular"
[AioGuideI18nCommonLocaleId]: guide/i18n-common-locale-id "Refer to locales by ID | Angular"
[AioGuideNpmPackages]: guide/npm-packages "Workspace npm dependencies | Angular"
<!-- external links -->
<!-- end links -->
@reviewed 2021-09-15
@reviewed 2021-10-07
+14 -10
View File
@@ -1,36 +1,38 @@
# Deploy multiple locales
{@a deploy-locales}
If `myapp` is the directory containing the distributable files of your application, you would typically make available different versions for different locales in locale directories such as `myapp/fr` for the French version and `myapp/es` for the Spanish version.
If `myapp` is the directory that contains the distributable files of your project, you typically make different versions available for different locales in locale directories. For example, your French version is located in the `myapp/fr` directory and the Spanish version is located in the `myapp/es` directory.
The HTML `base` tag with the `href` attribute specifies the base URI, or URL, for relative links.
If you set the `"localize"` option in `angular.json` to `true` or to an array of locale IDs, the CLI adjusts the base `href` for each version of the application.
If you set the `"localize"` option in [`angular.json`][AioGuideWorkspaceConfig] workspace build configuration file to `true` or to an array of locale IDs, the CLI adjusts the base `href` for each version of the application.
To adjust the base `href` for each version of the application, the CLI adds the locale to the configured `"baseHref"`.
Specify the `"baseHref"` for each locale in your workspace configuration file (`angular.json`).
Specify the `"baseHref"` for each locale in your [`angular.json`][AioGuideWorkspaceConfig] workspace build configuration file.
The following example displays `"baseHref"` set to an empty string.
<code-example language="json" header="angular.json" path="i18n/angular.json" region="i18n-baseHref" ></code-example>
Also, to declare the base `href` at compile time, use the CLI `--baseHref` option with [`ng build`][AioCliBuild].
### Configuring servers
## Configure a server
Typical deployment of multiple languages serve each language from a different subdirectory.
Users are redirected to the preferred language defined in the browser using the `Accept-Language` HTTP header.
If the user has not defined a preferred language, or if the preferred language is not available, then the server falls back to the default language.
To change the language, see another subdirectory.
To change the language, change your current location to another subdirectory.
The change of subdirectory often occurs using a menu implemented in the application.
<div class="alert is-helpful">
For more information on how to deploy apps to a remote server, see [Deployment][AioGuideDeployment].
#### Nginx
</div>
### Nginx example
The following example displays an Nginx configuration.
<code-example path="i18n/doc-files/nginx.conf" language="nginx"></code-example>
#### Apache
### Apache example
The following example displays an Apache configuration.
@@ -42,8 +44,10 @@ The following example displays an Apache configuration.
[AioGuideDeployment]: guide/deployment "Deployment | Angular"
[AioGuideWorkspaceConfig]: guide/workspace-config "Angular workspace configuration | Angular"
<!-- external links -->
<!-- end links -->
@reviewed 2021-09-15
@reviewed 2021-10-07
@@ -1,18 +1,49 @@
# Format data based on locale
{@a i18n-pipes}
Angular provides the following built-in data transformation [pipes][AioGuideGlossaryPipe]. The data transformation pipes use the [`LOCALE_ID`][AioApiCoreLocaleId] token to format data based on rules of each locale.
* [`DatePipe`][AioApiCommonDatepipe]: Formats a date value.
* [`CurrencyPipe`][AioApiCommonCurrencypipe]: Transforms a number to a currency string.
* [`DecimalPipe`][AioApiCommonDecimalpipe]: Transforms a number into a decimal number string.
* [`PercentPipe`][AioApiCommonPercentpipe]: Transforms a number to a percentage string.
| Data transformation pipe | Details |
|:--- |:--- |
| [`DatePipe`][AioApiCommonDatepipe] | Formats a date value. |
| [`CurrencyPipe`][AioApiCommonCurrencypipe] | Transforms a number into a currency string. |
| [`DecimalPipe`][AioApiCommonDecimalpipe] | Transforms a number into a decimal number string. |
| [`PercentPipe`][AioApiCommonPercentpipe] | Transforms a number into a percentage string. |
For example, `{{today | date}}` uses `DatePipe` to display the current date in the format for the locale in `LOCALE_ID`.
## Use DatePipe to display the current date
To override the value of `LOCALE_ID`, add the `locale` parameter.
For example, to force the currency to use `en-US` no matter which language-locale you set for `LOCALE_ID`, use this form: `{{amount | currency : 'en-US'}}`.
To display the current date in the format for the current locale, use the following format for the `DatePipe`.
<!--todo: replace with code-example -->
<code-example format="typescript" language="typescript">
{{ today | date }}
</code-example>
## Override current locale for CurrencyPipe
Add the `locale` parameter to the pipe to override the current value of `LOCALE_ID` token.
To force the currency to use American English (`en-US`), use the following format for the `CurrencyPipe`
<!--todo: replace with code-example -->
<code-example format="typescript" language="typescript">
{{ amount | currency : 'en-US' }}
</code-example>
<div class="alert is-helpful">
**NOTE**: The locale specified for the `CurrencyPipe` overrides the global `LOCALE_ID` token of your application.
</div>
## What's next
* [Prepare templates for translations][AioGuideI18nCommonPrepare]
<!-- links -->
@@ -24,8 +55,10 @@ For example, to force the currency to use `en-US` no matter which language-local
[AioGuideGlossaryPipe]: guide/glossary#pipe "pipe - Glossary | Angular"
[AioGuideI18nCommonPrepare]: guide/i18n-common-prepare "Prepare templates for translations | Angular"
<!-- external links -->
<!-- end links -->
@reviewed 2021-09-15
@reviewed 2021-10-28

Some files were not shown because too many files have changed in this diff Show More