docs: add documentation for Angular linker (#41485)

PR Close #41485
This commit is contained in:
Kapunahele Wong 2021-04-06 13:26:14 -04:00 committed by Misko Hevery
parent d64fa4fec8
commit 931d40b18a
1 changed files with 109 additions and 10 deletions

View File

@ -118,7 +118,15 @@ To learn more, see [Schematics Overview](guide/schematics) and [Schematics for L
Use the Angular CLI and the npm package manager to build and publish your library as an npm package.
Before publishing a library to NPM, build it using the `production` configuration which uses the older compiler and runtime known as View Engine instead of Ivy.
Angular CLI uses a tool called [ng-packagr](https://github.com/ng-packagr/ng-packagr/blob/master/README.md) to create packages
from your compiled code that can be published to npm.
See [Building libraries with Ivy](guide/creating-libraries#ivy-libraries) for information on the
distribution formats supported by `ng-packagr` and guidance on how
to choose the right format for your library.
You should always build libraries for distribution using the `production` configuration.
This ensures that generated output uses the appropriate optimizations and the correct package format for npm.
<code-example language="bash">
ng build my-lib
@ -126,15 +134,7 @@ cd dist/my-lib
npm publish
</code-example>
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).
<div class="alert is-important">
For now, it is not recommended to publish Ivy libraries to NPM because Ivy generated code is not backward compatible with View Engine, so apps using View Engine will not be able to consume them. Furthermore, the internal Ivy instructions are not yet stable, which can potentially break consumers using a different Angular version from the one used to build the library.
When a published library is used in an Ivy app, the Angular CLI will automatically convert it to Ivy using a tool known as the Angular compatibility compiler (`ngcc`). Thus, publishing your libraries using the View Engine compiler ensures that they can be transparently consumed by both View Engine and Ivy apps.
</div>
{@a lib-assets}
@ -147,7 +147,6 @@ You can use this feature when your library needs to publish optional theming fil
* 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, you can use [npm link](https://docs.npmjs.com/cli/link) to avoid reinstalling the library on every build.
@ -243,3 +242,103 @@ For this reason, an app that depends on a library should only use TypeScript pat
TypeScript path mappings should *not* point to the library source `.ts` files.
</div>
{@a ivy-libraries}
## Building libraries with Ivy
There are three distribution formats that you can 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 may 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.
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.
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.
However, the code in these libraries cannot be bundled directly along with the built application as it is not fully compiled.
To finish compilation, you can use the Angular linker.
For applications that don't use the Angular CLI, the linker is available as a Babel plugin.
You can use the Babel plugin using the module `@angular/compiler-cli/linker/babel` to incorporate into your builds.
For example, you can integrate the plugin into a custom Webpack build by registering the linker as a plugin for `babel-loader`.
Previously, if you ran `yarn install` or `npm install` you had to re-run `ngcc`.
Now, libraries only need to be processed by the linker a single time, regardless of other npm operations.
The Angular linker Babel plugin supports build caching, meaning that libraries only need to be processed by the linker a single time, regardless of other npm operations.
<div class="alert is-helpful">
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>