Currently writing schematics that support both NgModule-based and standalone projects is tricky, because they have different layouts. These changes introduce two new APIs that work both on NgModule and standalone projects and can be used by library authors to create their `ng add` schematics. Example rule for adding a `ModuleWithProviders`-style library:
```ts
import { Rule } from '@angular-devkit/schematics';
import { addRootImport } from '@schematics/angular/utility';
export default function(): Rule {
return addRootImport('default', ({code, external}) => {
return code`${external('MyModule', '@my/module')}.forRoot({})`;
});
}
```
This rulle will add `imports: [MyModule.forRoot({})]` to an NgModule app and `providers: [importProvidersFrom(MyModule.forRoot({}))]` to a standalone one. It also adds all of the necessary imports.
The E2E schematic will now (as it did previously) skip adding dependencies
if they already exist within the `package.json` regardless of the specifier.
This is accomplished with the `existing` option for the `addDependency` rule
which allows defining the behavior for when a dependency already exists.
Currently the two option behaviors are skip and replace with replace being
the default to retain behavior for existing rule usages.
When using the `addDependency` rule from `@schematics/angular/utility` a new option is now
available that supports controlling the rule's behavior when scheduling the `NodePackageInstallTask`.
Previously, the behavior was automatic and the rule would only schedule the task if it was not already
scheduled by a previous `addDependency` rule usage for the `package.json`. This behavior is still the
default behavior. However, it can now be customized per rule invocation via the `install` rule option
which can be either `InstallBehavior.None`, `InstallBehavior.Auto`, or `InstallBehavior.Always`.
The `@schematics/angular` package now contains a defined set of package `exports` including a `utility` subpath export.
A wildcard export is also temporarily defined to support transition away from existing deep-import usage.
The `@schematics/angular/utility` subpath export will contain supported utility methods used by the first-party schematics
contained within the `@schematics/angular` package and can be considered public API that will follow SemVer stability constraints.
The first group of utilities introduced in this change are used to modify the `angular.json` workspace file
within the schematics and include the `updateWorkspace` rule and `readWorkspace`/`writeWorkspace` helpers.