feat(docs): add more guides

This commit is contained in:
Victor Savkin 2019-02-03 17:49:55 -05:00
parent 0e1e5ce81b
commit 5f756bf16f
25 changed files with 480 additions and 649 deletions

View File

@ -19,7 +19,7 @@ To see how Nx delivers all of these, start with an empty Nx workspace:
## Monorepos with Nx
```
```console
apps/
libs/
tools/
@ -48,7 +48,7 @@ Out of the box, Nx comes with two schematics for creating applications.
Creating a new Angular application will result in something like this:
```
```console
apps/
myapp/
src/
@ -98,7 +98,7 @@ Nx comes with a schematic for creating libraries.
Creating a new TypeScript library will result in something like this:
```
```console
apps/
...
libs/
@ -159,7 +159,7 @@ It can also help you answer questions like "what apps will have to be redeployed
Because Nx understands how our applications and libraries depend on each other, it can verify that a code change to a reusable library does not break any applications and libraries depending on it.
```
```bash
yarn affected:apps --base=master # prints the apps affected by a PR
yarn affected:build --base=master # reruns build for all the projects affected by a PR
@ -181,7 +181,7 @@ To help with that Nx uses code analyses to make sure projects can only depend on
For instance, with this configuration, when you import private client code from the admin part of our repo, you will get an error.
```
```json
"nx-enforce-module-boundaries": [
true,
{
@ -232,7 +232,7 @@ yarn format:check # checks that the formatting is correct (used in CI)
You rarely have to look at `nx.json`, but it is still important to understand what it contains.
```
```json
{
"npmScope": "myorg",
"implicitDependencies": {
@ -245,25 +245,25 @@ You rarely have to look at `nx.json`, but it is still important to understand wh
"projects": {
"mylib": {
"tags": [],
"implictDependencies": []
"implicitDependencies": []
},
"myapp": {
"tags": ["shared"],
"implictDependencies": ["myapp-e2e"]
"implicitDependencies": ["myapp-e2e"]
},
"myapp-e2e": {
"tags": [],
"implictDependencies": []
},
"implicitDependencies": []
}
}
}
```
The `npmScope` property is used when importing libraries. In this example, when Nx sees `@myorg/mylib`, it will know that you are trying to import the `mylib` library from the same workspace.
The `implicitDependencies` map is used to define what projects global files affect. In this example, any change to `package.json` will affect all the projects in the workspace, so all of them will have to be rebuilt and retested.
The `implicitDependencies` map is used to define what projects are affected by global files. In this example, any change to `package.json` will affect all the projects in the workspace, so all of them will have to be rebuilt and retested.
```
```json
{
"implicitDependencies": {
"angular.json": "*",
@ -271,22 +271,24 @@ The `implicitDependencies` map is used to define what projects global files affe
"tsconfig.json": "*",
"tslint.json": "*",
"nx.json": "*"
},
}
}
```
In this example, any change to `package.json` will only affected `mylib`.
In this example, any change to `package.json` will only affect `mylib`.
```
"myapp": {
"tags": ['shared'],
"implictDependencies": ["myapp-e2e"]
},
```json
{
"myapp": {
"tags": ["shared"],
"implicitDependencies": ["myapp-e2e"]
}
}
```
The `tags` array is used to impose constraints on the dependency graph. Read more about it [here](TODO).
Nx uses its advanced code analysis to construct a dependency graph of all applications and libraries. Some dependencies, however, cannot be determined statically. You can use the `implictDependencies` array to list the dependencies that cannot be determined statically.
Nx uses its advanced code analysis to construct a dependency graph of all applications and libraries. Some dependencies, however, cannot be determined statically. You can use the `implicitDependencies` array to list the dependencies that cannot be determined statically.
## Summary

View File

@ -8,7 +8,7 @@ Start with implementing the frontend.
The easier way to add a frontend app to an Nx workspace is to run `ng g application frontend`, which will create:
```
```console
apps/
frontend/
src/
@ -78,7 +78,7 @@ export class AppComponent {
Next, create the api. You can do it by running `ng g node-application api --frontend-project=frontend` (`--frontend-project=frontend` set ups the proxy configuration such that the frontend application can access the api).
```
```console
apps/
frontend/
...
@ -195,7 +195,7 @@ Normally sharing code between the backend and the frontend would have required d
Create a new lib by running `ng g library data --framework=none`.
```
```console
apps/
frontend/
...

View File

@ -21,13 +21,13 @@ Many conventions and best practices used in Angular applications can be also be
To create a new Nest application, run:
```
```bash
ng g node-application api # you can also be explicit and pass `--framework=nestjs`
```
This will create the following:
```
```console
apps/
api/
src/
@ -68,7 +68,7 @@ You can run:
Adding a Nest app will also add Nest schematics to the workspace, which you can run as follows:
```
```bash
ng generate @nestjs/schematics:controller mycontroller --sourceRoot=apps/nestapp/src --path=app
```
@ -103,7 +103,7 @@ By default, when creating a new Angular application, Nx will use Cypress to crea
So running `ng g application frontend` will create:
```
```console
apps/
frontend/
...
@ -154,7 +154,7 @@ Jest is a fast 0-setup testing framework from Facebook.
By default, Nx uses Jest for both Angular and Node.js applications. So if you run `ng g application frontend`, you will get:
```
```console
apps/
frontend/
src/
@ -198,7 +198,7 @@ To use Karma instead of Jest, run `ng g application frontend --unit-test-runner=
Prettier is an opinionated code formatter. An Nx workspace comes with Prettier preconfigured.
```
```cosnole
apps/
libs/
tools/

View File

@ -68,7 +68,7 @@ ng g application myapp
The result will look like this:
```
```console
apps/
myapp/
src/

View File

@ -68,31 +68,33 @@ To help with that Nx uses code analyses to make sure projects can only depend on
For instance, with this configuration, when you import private client code from the admin part of our repo, you will get an error.
```
"nx-enforce-module-boundaries": [
true,
{
"allow": [],
"depConstraints": [
{
```json
{
"nx-enforce-module-boundaries": [
true,
{
"allow": [],
"depConstraints": [
{
"sourceTag": "shared",
"onlyDependOnLibsWithTags": ["shared"]
},
{
},
{
"sourceTag": "admin",
"onlyDependOnLibsWithTags": ["shared", "admin" ]
},
{
"onlyDependOnLibsWithTags": ["shared", "admin"]
},
{
"sourceTag": "client",
"onlyDependOnLibsWithTags": ["shared", "client" ]
},
{
"onlyDependOnLibsWithTags": ["shared", "client"]
},
{
"sourceTag": "*",
"onlyDependOnLibsWithTags": ["*"]
}
]
}
]
}
]
}
]
}
```
![Lint Error](./lint-error.png)
@ -101,7 +103,7 @@ For instance, with this configuration, when you import private client code from
To be productive in a monorepo, you need to be able to check that your change is safe, and rebuilding and retesting everything on every change wont scale. Nx uses code analysis to determine what needs to be rebuilt and retested.
```
```bash
yarn affected:build --base=master # reruns build for all the projects affected by a PR
yarn affected:test --base=master # reruns unit tests for all the projects affected by a PR
@ -133,13 +135,13 @@ Adding these tools to the dev workflow is challenging in a regular CLI project.
When using Nx, adding Cypress or Jest is easy:
```
```bash
ng g application myapp --e2eTestRunner=cypress --unitTestRunner=jest
```
Tests can then be run just like you would run them normally:
```
```bash
ng test myapp
ng e2e myapp
```

View File

@ -1,184 +0,0 @@
# Rebuilding and Retesting What is Affected
As with a regular CLI project, you can build and test apps and libs.
```console
ng g app myapp
ng g app myapp2 --directory=mydirectory
ng g lib mylib
ng g lib mylib2 --directory=mydirectory
ng build myapp
ng build mydirectory-myapp2
ng build mylib # work if the lib is marked as publishable
ng build mydirectory-mylib2 # work if the lib is marked as publishable
ng test myapp # runs unit tests for myapp
ng test mylib # runs unit tests for mylib
ng e2e myapp-e2e # runs e2e tests for myapp
```
Now imagine, `myapp` depends on `mylib`. If we make a change to `mylib`,
we need to make sure nothing in the workspace is affected.
Typically, you would do it like this:
```console
ng build mylib
ng test mylib
ng build myapp
ng test myapp
```
In many organizations, you would have dozens or hundreds of apps and libs.
To be productive in a monorepo, you need to be able to check that your
change is safe, and rebuilding and retesting everything on every change
won't scale, tracing the dependencies manually (as shown above) wont's
scale either. Nx uses code analysis to determine what needs to be rebuild
and retested, and it provides the following three commands you can use:
`affected:build`, `affected:test`, and `affected:e2e`.
- Rerunning build for all the projects affected by a PR
```console
yarn affected:build --base=master --head=HEAD
```
- Rerunning unit tests for all the projects affected by a PR
```console
yarn affected:test --base=master --head=HEAD
```
- Rerunning e2e tests for all the projects affected by a PR
```console
yarn affected:e2e --base=master --head=HEAD
```
When executing these commands, Nx will topologically sort the projects,
and will run what it can in parallel. But we can also explicitly pass
`--parallel` like so:
```console
yarn affected:build --base=master --parallel
yarn affected:test --base=master --parallel
yarn affected:e2e --base=master --parallel
```
We can also pass `--maxParallel` to specify the number of parallel processes.
## affected:build
Run `npm run affected:build -- --help` or `yarn affected:build --help` to see
the available options:
```console
Build applications affected by changes
Run command using --base=[SHA1] (affected by the committed, uncommitted and
untracked changes):
--base Base of the current branch (usually master) [string]
or using --base=[SHA1] --head=[SHA2] (affected by the committed changes):
--base Base of the current branch (usually master) [string]
--head Latest commit of the current branch (usually HEAD) [string]
or using:
--files A list of files delimited by commas [array]
--uncommitted Uncommitted changes
--untracked Untracked changes
Options:
--help Show help [boolean]
--version Show version number [boolean]
--parallel Parallelize the command [boolean] [default: false]
--maxParallel Max number of parallel processes [number] [default: 3]
--all All projects
--exclude Exclude certain projects from being processed
[array] [default: []]
--only-failed Isolate projects which previously failed
[boolean] [default: false]
```
- `npm run affected:build -- --base=[SHA1] --base=[SHA2]` or `yarn affected:build --base=[SHA1] --base=[SHA2]`. Nx will calculate what changed between the two SHAs, and will build the apps affected by the change. For instance, `yarn affected:build --base=origin/master --base=HEAD` will rebuild what is affected by a PR.
- `npm run affected:build -- --files=libs/mylib/src/index.ts,libs/mylib2/src/index.ts` or `yarn affected:build --files=libs/mylib/src/index.ts,libs/mylib2/src/index.ts`. Nx will build what is affected by changing the two index files.
- `npm run affected:build -- --uncommitted` or `yarn affected:build --uncommitted`. Nx will build what is affected by the uncommitted files (this is useful during development).
- `npm run affected:build -- --untracked` or `yarn affected:build --untracked`. Nx will build what is affected by the untracked files (this is useful during development).
All other options will be passed into the underlying build command (e.g., `yarn affected:build --base=origin/master --base=HEAD --prod`).
## affected:test
Run `npm run affected:test -- --help` or `yarn affected:test --help` to see the available options:
```console
Test applications affected by the change
Run command using --base=[SHA1] (affected by the committed, uncommitted and
untracked changes):
--base Base of the current branch (usually master) [string]
or using --base=[SHA1] --head=[SHA2] (affected by the committed changes):
--base Base of the current branch (usually master) [string]
--head Latest commit of the current branch (usually HEAD) [string]
or using:
--files A list of files delimited by commas [array]
--uncommitted Uncommitted changes
--untracked Untracked changes
Options:
--help Show help [boolean]
--version Show version number [boolean]
--parallel Parallelize the command [boolean] [default: false]
--maxParallel Max number of parallel processes [number] [default: 3]
--all All projects
--exclude Exclude certain projects from being processed
[array] [default: []]
--only-failed Isolate projects which previously failed
[boolean] [default: false]
```
- `npm run affected:test -- --base=[SHA1] --base=[SHA2]` or `yarn affected:test --base=[SHA1] --base=[SHA2]`. Nx will calculate what changed between the two SHAs, and will test the projects affected by the change. For instance, `yarn affected:test --base=origin/master --base=HEAD` will retest what is affected by a PR.
- `npm run affected:test -- --files=libs/mylib/src/index.ts,libs/mylib2/src/index.ts` or `yarn affected:test --files=libs/mylib/src/index.ts,libs/mylib2/src/index.ts`. Nx will test what is affected by changing the two index files.
- `npm run affected:test -- --uncommitted` or `yarn affected:test --uncommitted`. Nx will test what is affected by the uncommitted files (this is useful during development).
- `npm run affected:test -- --untracked` or `yarn affected:test --untracked`. Nx will test what is affected by the untracked files (this is useful during development).
All other options will be passed into the underlying test command (e.g., `yarn affected:test --base=origin/master --base=HEAD --sm=false`).
## affected:e2e
Run `npm run affected:e2e -- --help` or `yarn affected:e2e --help` to see the available options:
```console
Run e2e tests for the applications affected by changes
Run command using --base=[SHA1] (affected by the committed, uncommitted and
untracked changes):
--base Base of the current branch (usually master) [string]
or using --base=[SHA1] --head=[SHA2] (affected by the committed changes):
--base Base of the current branch (usually master) [string]
--head Latest commit of the current branch (usually HEAD) [string]
or using:
--files A list of files delimited by commas [array]
--uncommitted Uncommitted changes
--untracked Untracked changes
Options:
--help Show help [boolean]
--version Show version number [boolean]
--all All projects
--exclude Exclude certain projects from being processed
[array] [default: []]
--only-failed Isolate projects which previously failed
[boolean] [default: false]
```
- `npm run affected:e2e -- --base=[SHA1] --base=[SHA2]` or `yarn affected:e2e --base=[SHA1] --base=[SHA2]`. Nx will calculate what changed between the two SHAs, and will run e2e test for the apps affected by the change. For instance, `yarn affected:test --base=origin/master --base=HEAD` will retest what is affected by a PR.
- `npm run affected:e2e -- --files=libs/mylib/src/index.ts,libs/mylib2/src/index.ts` or `yarn affected:e2e --files=libs/mylib/src/index.ts,libs/mylib2/src/index.ts`. Nx will run e2e tests for what is affected by changing the two index files.
- `npm run affected:e2e -- --uncommitted` or `yarn affected:e2e --uncommitted`. Nx will run e2e tests for what is affected by the uncommitted files (this is useful during development).
- `npm run affected:e2e -- --untracked` or `yarn affected:e2e --untracked`. Nx will run e2e tests for what is affected by the untracked files (this is useful during development).
All other options will be passed into the underlying test command (e.g., `yarn affected:test --base=origin/master --base=HEAD --sm=false`).

BIN
docs/guides/affected.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

View File

@ -1,50 +0,0 @@
# Creating an App
Adding new apps to an Nx Workspace is done by using the Angular CLI generate command. Nx has a schematic named `app` that can be used to add a new app to our workspace:
```bash
ng g app myapp
ng generate app myapp # same thing
ng generate application myapp # same thing
```
This will create a new app, will place it in the `apps` directory, and will configure the `angular.json` and `nx.json` files to support the new app. It will also configure the root `NgModule` to import the `NxModule` code so we can take advantage of things like `DataPersistence`.
# Available options
Run `ng generate app --help` to see the list of available options:
```
usage: ng generate app <name> [options]
options:
--directory
The directory of the new application.
--dry-run (-d)
Run through without making any changes.
--force (-f)
Forces overwriting of files.
--inline-style (-s)
Specifies if the style will be in the ts file.
--inline-template (-t)
Specifies if the template will be in the ts file.
--prefix (-p)
The prefix to apply to generated HTML selector of components.
--routing
Generates a routing module.
--skip-package-json
Do not add dependencies to package.json.
--skip-tests (-S)
Skip creating spec files.
--style
The file extension to be used for style files.
--tags
Add tags to the application (used for linting)
--view-encapsulation
Specifies the view encapsulation strategy.
```
Most of these options are identical to the ones supported by the default CLI application, but the following are new or different: `directory`, `routing`, and `tags`.
- `ng generate app myapp --directory=myteam` will create a new application in `apps/myteam/myapp`.
- `ng generate app myapp --routing` will configure the root `NgModule` to wire up routing, as well as add a `<router-outlet>` to the AppComponent template to help get us started.
- `ng generate app myapp --tags=shared,experimental` will annotate the created app with the two tags, which can be used for advanced code analysis. Read more below.

View File

@ -1,46 +0,0 @@
# Analysing & visualizing dependencies
To be able to support the monorepo-style development, the tools must know how different projects in your workspace depend on each other. Nx uses advanced code analysis to build this dependency graph.
You can visualize it by running `npm run dep-graph` or `yarn dep-graph`.
![dependency-graph](//images.ctfassets.net/8eyogtwep6d2/7M6FSiQ75K8gu8G4QqSsSa/111f85a98ed129c53a86c0edf4bd2912/dependency-graph.png)
You can also visualize what is affected by your change, by using the `affected:dep-graph` command.
![dependency-graph-affected](//images.ctfassets.net/8eyogtwep6d2/1375oQexPaKikmICIAa2q4/904272360ba3f2a3469fbeeab62efdb1/dependency-graph-affected.png)
# Available options
Run `npm run affected:dep-graph -- --help` or `yarn affected:dep-graph --help` to see the available options:
```
Graph dependencies affected by changes
Run command using --base=[SHA1] --head=[SHA2]:
--base Base of the current branch (usually master) [string]
--head Latest commit of the current branch (usually HEAD) [string]
or using:
--files A list of files delimited by commas [array]
--uncommitted Uncommitted changes
--untracked Untracked changes
Options:
--help Show help [boolean]
--version Show version number [boolean]
--file output file (e.g. --file=.vis/output.json)
```
First, you need to tell Nx what you changed, and you can do it in one of the following ways:
- `npm run affected:dep-graph -- --base=[SHA1] --base=[SHA2]` or `yarn affected:dep-graph --base=[SHA1] --base=[SHA2]`. Nx will calculate what changed between the two SHAs, and will graph what is affected by the change. For instance, `yarn affected:dep-graph --base=origin/master --base=HEAD` will show what is affected by a PR.
- `npm run affected:dep-graph -- --files=libs/mylib/src/index.ts,libs/mylib2/src/index.ts` or `yarn affected:dep-graph --files=libs/mylib/src/index.ts,libs/mylib2/src/index.ts`. Nx will graph what is affected by changing the two index files.
- `npm run affected:dep-graph -- --uncommitted` or `yarn affected:dep-graph --uncommitted`. Nx will graph what is affected by the uncommitted files (this is useful during development).
- `npm run affected:dep-graph -- --untracked` or `yarn affected:dep-graph --untracked`. Nx will graph what is affected by the untracked files (this is useful during development).
By default, the `dep-graph` and `affected:dep-graph` commands will open the browser to show the graph, but you can also output the graph into a file by running:
- `npm run dep-graph -- --file=graph.json` or `yarn dep-graph --file=graph.json` will emit a json file.
- `npm run dep-graph -- --file=graph.dot` or `yarn dep-graph --file=graph.dot` will emit a dot file.
- `npm run dep-graph -- --file=graph.svg` or `yarn dep-graph --file=graph.svg` will emit an svg file.

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

View File

@ -1,15 +0,0 @@
# Different types of libraries
There are many different types of libraries in a workspace.
In order to maintain a certain sense of order, we recommend
having only the below four types of libraries:
- Feature libraries: Developers should consider feature libraries
as libraries that implement smart UI (with injected services) for
specific business use cases or pages in an application.
- UI libraries: A UI library contains only presentational components.
- Data-access libraries: A data-access library contains services and
utilities for interacting with a back-end system.
- Utility libraries: A utility library contains common utilities and
services used by many libraries and applications. It also includes
all the code related to State management.

View File

@ -1,80 +0,0 @@
# Enforcing quality
## Imposing Constraints on the Dependency Graph
If you partition your code into well-defined cohesive units, even a
small organization will end up with a dozen apps and dozens or
hundreds of libs. If all of them can depend on each other freely,
the chaos will ensue and the workspace will become unmanageable.
To help with that Nx uses code analyses to make sure projects can only
depend on each other's well-defined public API. It also allows you to
declaratively impose constraints on how projects can depend on each other.
Enterprise development teams love this capability to constrain library
dependencies. With it developers can define which projects are team-specific
and which are shared.
For instance, with this configuration, when we import private client code from
the admin part of our repo, we will get an error.
```javascript
"nx-enforce-module-boundaries": [
true,
{
"allow": [],
"depConstraints": [
{
"sourceTag": "shared",
"onlyDependOnLibsWithTags": ["shared"]
},
{
"sourceTag": "admin",
"onlyDependOnLibsWithTags": ["shared", "admin" ]
},
{
"sourceTag": "client",
"onlyDependOnLibsWithTags": ["shared", "client" ]
},
{
"sourceTag": "*",
"onlyDependOnLibsWithTags": ["*"]
}
]
}
]
```
![dependency-graph-constraints-lint-error](https://images.ctfassets.net/8eyogtwep6d2/31Aiw0uwFy2mGGsWOcWYII/0ab4f1e30b93ce757a0653fc8b1d4a24/dependency-graph-contraints-lint-error.png)
With these dependency constraints, another team won't create a
dependency on your internal library.
You can define which projects contain components, NgRx code, and features,
so you, for instance, can disallow projects containing dumb UI components
depend on NgRx. You can define which projects are experimental and which
are stable, so stable applications cannot depend on experimental projects etc.
## Implicit Dependencies
Nx uses its built-in intelligence to create the dependency graph of the
apps and libs, and that gets used to figure out what needs to be rebuilt and
retested. There are certain files, however, that Nx cannot analyze.
Thats why Nx has support for implicit dependencies. They are defined in `nx.json`.
```json
{
"npmScope": "mycompany",
"implicitDependencies": {
"package.json": "*",
"angular.json": "*",
"tsconfig.json": "*",
"tslint.json": "*",
"nx.json": "*"
},
"projects": {}
}
```
These tell Nx that a change to files in this list will affect every single project.

View File

@ -1,21 +0,0 @@
# A recommended Git Strategy
We recommend the following:
- Always use Pull Requests when merging code. A PR has two purposes:
- To initiate a conversation and to get feedback on the implementation
- To initiate a build and to run tests and lint checks to ensure that
we dont break the build
- Avoid long-running branches and dont merge branches locally
- Enforce a git merging strategy that ensures that feature branches are
up-to-date before merging. This ensures that these branches are tested
with the latest code before the merge.
The website [trunkbaseddevelopment.com](trunkbaseddevelopment.com) contains a
lot of very helpful information on trunk-based development and is a great resource.
The following sections are the most pertinent:
- [Feature flags](https://trunkbaseddevelopment.com/feature-flags/)
- [Strategy for migrating code](https://trunkbaseddevelopment.com/branch-by-abstraction/)
- [Feature branches](https://trunkbaseddevelopment.com/short-lived-feature-branches/#breaking-the-contract)

View File

@ -1,70 +0,0 @@
# Creating a Lib
Adding new libs to an Nx Workspace is done by using the Angular CLI generate command, just like adding a new app.
```bash
ng generate lib mylib
ng generate library mylib # same thing
```
This will create a new lib, will place it in the libs directory, and will configure the `angular.json` and `nx.json` files to support the new lib.
# Available options
Run `ng generate lib --help` to see the list of available options:
```
usage: ng generate lib <name> [options]
options:
--directory
A directory where the app is placed
--dry-run (-d)
Run through without making any changes.
--force (-f)
Forces overwriting of files.
--lazy
Add RouterModule.forChild when set to true, and a simple array of routes when set to false.
--parent-module
Update the router configuration of the parent module using loadChildren or children, depending on what `lazy` is set to.
--prefix (-p)
The prefix to apply to generated HTML selector of components.
--publishable
Generate a simple TS library when set to true.
--routing
Add router configuration. See lazy for more information.
--skip-package-json
Do not add dependencies to package.json.
--skip-ts-config
Do not update tsconfig.json for development experience.
--tags
Add tags to the library (used for linting)
```
Most of these options are identical to the ones supported by the default CLI library, but the following are new or different: `directory`, `routing`, `lazy`, `parent-module`, `publishable`, and `tags`.
- `ng generate lib mylib --directory=myteam` will create a new application in `libs/myteam/mylib`.
- `ng generate lib mylib --routing` will configure the lib's `NgModule` to wire up routing to be loaded eagerly.
- `ng generate lib mylib --routing --lazy` will configure the lib's `NgModule` to wire up routing to be loaded lazily.
- `ng generate lib mylib --routing --parent-module=apps/myapp/src/app/app.module.ts` will configure the lib's `NgModule` to wire up routing and will configure `app.module.ts` to load the library.
- `ng generate lib mylib --routing --lazy --parent-module=apps/myapp/src/app/app.module.ts` will configure the lib's `NgModule` to wire up routing and will configure `app.module.ts` to load the library.
- `ng generate lib mylib --publishable` will generate a few extra files configuring for `ng-packagr`. You can then run `ng build mylib` to create an npm package you can publish to a npm registry. This is very rarely needed when developing in a monorepo. In this case the clients of the library are in the same repository, so no packaging and publishing step is required.
- `ng generate lib mylib --tags=shared,experimental` will annotate the created lib with the two tags, which can be used for advanced code analysis. Read more below.
Note when creating lazy-loaded libraries, you need to add an entry to the tsconfig.app.json file of the parent module app, so TypeScript knows to build it as well:
```javascript
{
. . .
"include": [
"**/*.ts"
/* add all lazy-loaded libraries here: "../../../libs/my-lib/index.ts" */
, "../../../libs/mymodule/src/index.ts"
]
}
```
In most cases, Nx will do it by default. Sometime, you need to manually add this entry.
This is great, but is not sufficient to enable the monorepo-style development. Nx adds an extra layer of tooling to make this possible.

View File

@ -1,4 +1,4 @@
# Managing state
# Using DataPersistence
Managing state is a hard problem. We need to coordinate multiple backends, web workers, and UI components, all of which update the state concurrently.

View File

@ -1,4 +1,4 @@
# Setting Up NgRx in Nx
# Setting Up NgRx
Leveraging [NgRx](https://github.com/ngrx/platform) for state management in an Angular application involves
@ -33,7 +33,7 @@ You can generate new **feature** state (NgRx files) which are registered with th
> Feature state libraries can be lazy loaded and support feature state slices that are independent of other feature states.
```sh
```bash
ng generate ngrx <FeatureName> --module="" [options]
ng g ngrx <FeatureName> --module="" [options]
```
@ -67,7 +67,7 @@ Specifies the name of the NgRx feature (e.g., Products, Users, etc.).
* Do not use `State` a suffix.
* We recommend developers use the plural forms for feature 'name'; e.g. Products, Users, Cars, etc.
```sh
```bash
ng g ngrx <FeatureName> [options]
```
@ -79,7 +79,7 @@ Specifies the path to Angular `ngModule`. This option is **always** required and
- Type: `string`
- Required: true
```sh
```bash
ng g ngrx <FeatureName> --module=<xxx> [options]
```
@ -97,7 +97,7 @@ Specify this flag to generate NgRx Facade class(es) along with the standard NgRx
- Type: `boolean`
- Required: false; defaults to `false`
```sh
```bash
ng g ngrx <FeatureName> -module=<xxx> --facade [options]
```
@ -134,7 +134,7 @@ We can run the generate command for ngrx with the module and root options to cre
- Type: `boolean`
- Required: false; defaults to `false`
```sh
```bash
ng generate ngrx app --module=apps/<appname>/src/app/app.module.ts --root
```
@ -154,7 +154,7 @@ Also, app.module.ts will have StoreModule.forRoot and EffectsModule.forRoot conf
We can run the generate command for ngrx with the module and onlyEmptyRoot option to only add the StoreModule.forRoot and EffectsModule.forRoot calls without generating any new files.
```console
```bash
ng generate ngrx app --module=apps/<appname>/src/app/app.module.ts --onlyEmptyRoot
```
@ -164,7 +164,7 @@ This can be useful in the cases where we don't have a need for any state at the
We can run the generate command for ngrx with the module option to create a new feature level store and corresponding pieces needed:
```console
```bash
ng generate ngrx products --module=libs/<libname>/src/mymodule.module.ts
```
@ -198,7 +198,7 @@ This can be useful when we want to start building out our state without wiring i
Consider a command to generate a `Comments` NgRx feature set and register it within an application root ngModule.
```sh
```bash
ng generate NgRx Comments --root --module=apps/myapp/src/app/app.module.ts
```
@ -208,7 +208,7 @@ ng generate NgRx Comments --root --module=apps/myapp/src/app/app.module.ts
Better yet, let's generate a `Comments` feature set within a `state` library and register it with the `comments-state.module.ts` file in the same `comments/state` folder.
```sh
```bash
ng g ngrx Comments --module=libs/comments/state/src/lib/comments-state.module.ts
```
@ -228,41 +228,41 @@ The files generated are shown below and include placeholders for the _comments_
###### comments.actions.ts
```ts
```typescript
import {Action} from "@ngrx/store";
export enum CommentsActionTypes {
LoadComments = "[Comments] Load Comments",
CommentsLoaded = "[Comments] Comments Loaded"
CommentsLoadError = "[Comments] Comments Load Error"
LoadComments = "[Comments] Load Comments",
CommentsLoaded = "[Comments] Comments Loaded"
CommentsLoadError = "[Comments] Comments Load Error"
}
export class LoadComments implements Action {
readonly type = CommentsActionTypes.LoadComments;
readonly type = CommentsActionTypes.LoadComments;
}
export class CommentsLoadError implements Action {
readonly type = CommentsActionTypes.LoadComments;
readonly type = CommentsActionTypes.LoadComments;
}
export class CommentsLoaded implements Action {
readonly type = CommentsActionTypes.CommentsLoaded;
constructor(public payload: any[]) { }
readonly type = CommentsActionTypes.CommentsLoaded;
constructor(public payload: any[]) { }
}
export type CommentsAction = LoadComments | CommentsLoaded | CommentsLoadError;
export const fromCommentsActions = {
LoadComments,
CommentsLoaded,
CommentsLoadError
LoadComments,
CommentsLoaded,
CommentsLoadError
}
```
###### comments.selectors.ts
```ts
```typescript
import { createFeatureSelector, createSelector } from '@ngrx/store';
import { CommentsState } from './comments.reducer';
@ -287,7 +287,7 @@ export const commentsQuery = {
###### comments.reducer.ts
```ts
```typescript
import { CommentsAction, CommentsActionTypes } from './comments.actions';
import { Comments, CommentsState } from './comments.reducer';
@ -331,7 +331,7 @@ export function commentsReducer(
###### comments.effects.ts
```ts
```typescript
import { Injectable } from '@angular/core';
import { Effect, Actions } from '@ngrx/effects';
import { DataPersistence } from '@nrwl/nx';
@ -374,7 +374,7 @@ export class CommentsEffects {
If you are register the Comments NgRx as part of the `.forRoot()` state, then:
e.g.
```console
```bash
ng generate ngrx Comments --root --module=apps/myapp/src/app/app.module.ts
```
@ -384,7 +384,7 @@ will update the root ngModule with NgRx configurations:
###### apps/myapp/src/app/app.module.ts
```ts
```typescript
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { RouterModule } from '@angular/router';
@ -432,7 +432,7 @@ Otherwise you are registering your Comments state management as a feature librar
The command:
```console
```bash
ng g ngrx Comments --module=libs/comments/state/src/lib/comments-state.module.ts
```
@ -442,7 +442,7 @@ which will update the feature library ngModule with NgRx Comments configurations
###### libs/comments/state/src/lib/comments-state.module.ts
```ts
```typescript
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
@ -476,7 +476,7 @@ Finally, we update the <Feature> library's barrel `index.ts` to export the updat
###### libs/comments/comments-state/src/lib/index.ts
```ts
```typescript
export * from './lib/+state/comments.selectors';
export * from './lib/+state/comments.reducer';
@ -484,7 +484,3 @@ export { CommentsStateModule } from './lib/comments-state.module';
```
<br/>
---
For developers interested in generating NgRx Facades, see [Building NgRx Facades](guide-ngrx-with-facades.md).

View File

@ -1,4 +1,46 @@
# Creating an AngularJS Downgrade Module
# Upgrading AngularJS Applications
There are two main ways to incrementally upgrade your AngularJS application: using UpgradeModule and using downgradeModule. Nx helps you use both.
## Using UpgradeModule
NgUpgrade is a library put together by the Angular team, which we can use in our application to mix and match AngularJS and Angular components and bridge the AngularJS and Angular dependency injection systems. We can call such an application a “hybrid application”, and the code required to bootstrap it an "upgrade module".
Setting up an Upgrade Module manually involves several steps and is easy to misconfigure. **Nx** provides a command that does it for you.
```console
ng generate upgrade-module legacyApp --app=myapp
```
This will add and set up `UpgradeModule`, configure `legacyApp`, and will add all the needed dependencies to `package.json`.
Open the generated `legacy-app-setup.ts` and you will find all the code needed to bridge the AngularJS and Angular applications.
### Testing Hybrid Applications
For a lot of applications, just running one command is sufficient to convert your application into a hybrid application. That's not always the case--sometimes changes are required. To make this iterative process easier, Nx creates `hybrid.spec.ts`, which you can use to make sure the upgrade module works.
### After Upgrade Module
Nx sets up the upgrade module for you to help you get started with your upgrade process. To learn more on how to upgrade your application, once an upgrade module is set up, check out the following resources:
#### Talk: Upgrading Enterprise Angular Applications
In this talk at NgConf, Victor Savkin shows how to upgrade your application gradually, component by component, module by module using NgUpgrade and the Angular Router. He discusses the common problems developers face during such migrations and the patterns that can be used to remedy them.
<a href="https://www.youtube.com/embed/izpqQpD8RQ0" class="embedly-card" data-card-width="100%" data-card-controls="0">Embedded content: https://www.youtube.com/embed/izpqQpD8RQ0</a>
#### Blog: Upgrading Angular Applications
In this blog post series Victor Savkin covers similar topics but more in depth. He dives deep into NgUpgrade, including the mental model, implementation, subtleties of the API. Then he talks about different strategies for upgrading large AngularJS applications.
- [NgUpgrade in Depth](https://blog.nrwl.io/ngupgrade-in-depth-436a52298a00)
- [Upgrade Shell](https://blog.nrwl.io/upgrading-angular-applications-upgrade-shell-4d4f4a7e7f7b)
- [Two Approaches to Upgrading Angular Applications](https://blog.nrwl.io/two-approaches-to-upgrading-angular-apps-6350b33384e3)
- [Managing Routers and URL](https://blog.nrwl.io/upgrading-angular-applications-managing-routers-and-url-ca5588290aaa)
- [Using NgUpgrade like a Pro: Lazy Loading AngularJS Applications](https://blog.nrwl.io/using-ngupgrade-like-a-pro-lazy-loading-angularjs-applications-469819f5c86)
## Using downgradeModule
While NgUpgrade provides a way to run Angular and AngularJS code side by side and bridge the dependency injection systems, it does take a bit of a performance hit. Reason being, you end up having both change detection systems running at the same time regardless of if you are hitting Angular or AngularJS code.
@ -16,35 +58,17 @@ This will configure the `AppModule` to not bootstrap the `AppComponent` and inst
Open `main.ts` and you will find all the code needed to run AngularJS and include Angular code.
## Schematic
**downgrade-module** _&lt;name&gt; &lt;options ...&gt;_
### Required
- **name** (`string`)
The name of the main AngularJS module.
### Options
- **app** (`string`)
The name of the application to add it to.
- **angularJsImport** (`string`)
Import expression of the AngularJS application (e.g., --angularJsImport=node_modules/my_app).
- **skipPackageJson** (`boolean`)
Do not add @angular/upgrade to package.json (e.g., --skipPackageJson). Default is `false`.
## After Downgrade Module
### After Downgrade Module
Nx sets up the downgrade module for you to help you get started with your conversion process to Angular. Check out the blog post on [Using Nrwl/Nx to Upgrade You AngularJS Applications to Angular](https://blog.nrwl.io/using-nrwl-nx-to-upgrade-you-angularjs-applications-to-angular-f5b8adf188aa) to learn more about the differences between Upgrade and Downgrade Module.
From there, a good next step is to pick a slicing strategy for taking on incremental upgrades. To learn about the vertical and horizontal slicing strategies check out [Two Approaches to Upgrading Angular Applications](https://blog.nrwl.io/two-approaches-to-upgrading-angular-apps-6350b33384e3).
### Upgrading/Downgrading Injectables and Components
#### Upgrading/Downgrading Injectables and Components
Once you have decided on a slicing strategy you will move forward with converting AngularJS components (directives) and injectables to Angular and downgrading them to use them in the AngularJS bits as well as upgrading some of the AngularJS bits to be able to run in the Angular ones. The blog post [NgUpgrade in Depth](https://blog.nrwl.io/ngupgrade-in-depth-436a52298a00) includes information on handling injectable and component conversions to Angular, which are the same way to do it for the Downgrade Module approach. Take a look at the sections on **Dependency Injection** and **Component Integration** to learn how to upgrade/downgrade injectables and components for use in AngularJS and Angular.
### Controlling Change Detection
#### Controlling Change Detection
The other piece of the puzzle that you will need to handle is manually triggering change detection if your component tree consists of a combination of AngularJS and Angular components.

View File

@ -11,18 +11,17 @@ Cypress is an e2e test runner built for modern web. It has a lot of great featur
- Network traffic control
- Screenshots and videos
## How to Use Cypress
### Generating Applications
By default, when creating a new Angular application, Nx will use Cypress to create the e2e tests project.
```
```bash
ng g application frontend
```
```
```console
apps/
frontend/
...
@ -57,7 +56,6 @@ Older versions of Nx used Protractor as a default e2e test runner. For those wor
> Unfortunately, the cypress api and its ecosystem are different from Protractor. So Nx cannot provide a reliable migration from Protractor to Cypress tests in an existing application.
### Testing Applications
Simply run `ng e2e frontend-e2e` to execute e2e tests with Cypress.
@ -68,7 +66,7 @@ Screenshots and Videos will be accessible respectively in `/dist/apps/frontend/s
### Watching for Changes
With, `ng e2e frontend-e2e --watch` Cypress will start in the application mode. Change your tests or your application code, and Cypress will rerun the tests.
With, `ng e2e frontend-e2e --watch` Cypress will start in the application mode. Change your tests or your application code, and Cypress will rerun the tests.
Running Cypress with `--watch` is a great way to enhance dev workflow. Write your e2e tests, and then start working on your app while Cypress is rerunning the tests.
@ -80,14 +78,13 @@ If you want to run the Cypress tests in headless mode (e.g., on CI), you can do
You can run your e2e test against a production build like this: `ng e2e my-app-e2e --prod`.
## Configuration
### Specifying a Custom Url to Test
The `baseUrl` property provides you the ability to test an application hosted on a specific domain.
```
```bash
ng e2e my-app-e2e --baseUrl=https://my-app.com
```

View File

@ -17,7 +17,7 @@
By default, Nx will use Jest when creating applications and libraries.
```
```console
apps/
frontend/
src/
@ -51,7 +51,6 @@ tslint.json
Older versions of Nx used Karam as a default test runner. For those workspace, you have provide the `--unit-test-runner=jest` option when creating applications or libraries.
### Running Tests
```bash

View File

@ -0,0 +1,201 @@
# Rebuilding and Retesting What is Affected
As with a regular CLI project, when using Nx you can build and test apps and libs.
```console
ng g app client
ng g app admin
ng g lib client-feature-main
ng g lib admin-feature-permissions
ng g lib components-shared
ng build client
ng build client-feature-main # works if the lib is marked as publishable
ng test client
ng test admin
ng test client-feature-main
ng e2e client-e2e
```
Now imagine, `admin` depends on `admin-feature-permissions`. If we make a change to `admin-feature-permissions`, we need to make sure nothing in the workspace is affected.
Typically, you would do it like this:
```console
ng test admin-feature-permissions
ng build admin
ng test admin
ng e2e admin-e2e
```
In many organizations, you would have dozens or hundreds of apps and libs. To be productive in a monorepo, you need to be able to check that your change is safe, and rebuilding and retesting everything on every change won't scale, tracing the dependencies manually (as shown above) won't scale either.
Nx uses code analysis to construct a dependency graph of all projects in the workspace. It then uses the dependency graph to determine what needs to be rebuilt and retested.
## Viewing Dep Graph
Run `npm run dep-graph` or `yarn dep-graph` to see the dependency graph.
![dependency-graph](./dependency-graph.png)
## Affected
To calculate the project affected by your change, Nx needs to know what file you changed. The most direct way to do it is by passing `--files`:
```
npm run affected:dep-graph -- --files=libs/admin-feature-permissions/src/index.ts
```
![dependency-graph-affected](./affected.png)
If you use git, you can use it to determine what files have changed.
```
npm run affected:dep-graph -- --base=master --head=HEAD
```
The `--head` defaults to `HEAD`, so when running it locally you can usually omit it:
```
npm run affected:dep-graph -- --base=master
```
Nx will find the most common ancestor of the base and head SHAs and will use it to determine what has changed between it and head.
## Building/Testing/Printing Affected Projects
```
npm run affected:apps -- --base=master # prints affected apps
npm run affected:libs -- --base=master # prints affected libs
npm run affected:build -- --base=master # builds affected apps and libs
npm run affected:lint -- --base=master # lints affected apps and libs
npm run affected:test -- --base=master # tests affected apps and libs
npm run affected:e2e -- --base=master # e2e tests affected apps
```
All of these are just shortcuts for the following:
```
npm run affected -- --target=ANYTARGET --base=master # run ANYTARGET for all affected apps and libs
```
Other options will forwarded to the underlying target (e.g., `yarn affected:test --base=origin/master --base=HEAD --sm=false`).
## CI
The SHAs you pass must be defined in the git repository. The `master` and `HEAD` SHAs are what you normally use while developing. Most likely you will want to provision other SHAs in your CI environment.
```
npm run affected:build -- --base=origin/master --head=$PR_BRANCH_NAME # where PR_BRANCH_NAME is defined by your CI system
npm run affected:build -- --base=origin/master~1 --head=origin/master # rerun what is affected by the last commit in master
```
## Running Targets in Parallel
Running targets in parallel can significantly speed up your CI time.
```
npm run affected:build -- --base=master --parallel
npm run affected:build -- --base=master --parallel --maxParallel=5
```
## Rerunning All Targets
You should never do it in CI, but it is sometimes useful to rerun all targets locally.
```
npm run affected:build -- --all
```
## Running Failed
After you run any affected command, Nx remembers which targets fail. So if you want to rerun only the failed once, pass: `--only-failed`;
```
npm run affected:build -- --only-failed
```
## Excluding Projects
Finally, you can exclude projects like this:
```
npm run affected:test -- --all --exlude=admin # retests everthing except admin
```
## When Nx Can't Understand Your Repository
Nx uses its advanced code analysis to construct a dependency graph of all applications and libraries. Some dependencies, however, cannot be determined statically. You can define them yourself in `nx.json`.
```json
{
"npmScope": "myorg",
"implicitDependencies": {
"angular.json": "*",
"package.json": "*",
"tsconfig.json": "*",
"tslint.json": "*",
"nx.json": "*"
},
"projects": {
"client": {
"tags": [],
"implicitDependencies": ["client-e2e"]
},
"client-e2e": {
"tags": [],
"implicitDependencies": []
},
"admin": {
"tags": [],
"implicitDependencies": ["admin-e2e"]
},
"admin-e2e": {
"tags": [],
"implicitDependencies": []
},
"client-feature-main": {
"tags": [],
"implicitDependencies": []
},
"admin-feature-permissions": {
"tags": [],
"implicitDependencies": []
},
"components-shared": {
"tags": [],
"implicitDependencies": []
}
}
}
```
The `implicitDependencies` map is used to define what projects are affected by global files. In this example, any change to `package.json` will affect all the projects in the workspace, so all of them will have to be rebuilt and retested. You can replace `*` with a list of projects.
```json
{
"implicitDependencies": {
"angular.json": "*",
"package.json": ["admin", "client"],
"tsconfig.json": "*",
"tslint.json": "*",
"nx.json": "*"
}
}
```
You can also specify dependencies between projects. For instance, if `admin-e2e` tests both the `admin` and `client` applications, you can express this as follows:
```json
{
"client": {
"tags": [],
"implicitDependencies": ["client-e2e", "admin-e2e"]
},
"admin": {
"tags": [],
"implicitDependencies": ["admin-e2e"]
}
}
```

View File

@ -0,0 +1,15 @@
# Analysing & Visualizing Workspaces
To be able to support the monorepo-style development, the tools must know how different projects in your workspace depend on each other. Nx uses advanced code analysis to construct this dependency graph.
You can visualize it by running `npm run dep-graph` or `yarn dep-graph`.
![dependency-graph](./dependency-graph.png)
You can also visualize what is affected by your change, by using the `npm run affected:dep-graph -- --base=master` command.
![dependency-graph-affected](./affected.png)
## Angular Console
Angular Console is the UI for the Angular CLI. Since Nx is just a set of power-ups for the CLI, you can use Angular Console for Nx repositories. In particular, you can use Console to interact with the dependency diagram of the workspace. You can download Angular Console at [angularconsole.com](https://angularconsole.com).

View File

@ -0,0 +1,101 @@
# Imposing Constraints on the Dependency Graph
If you partition your code into well-defined cohesive units, even a small organization will end up with a dozen apps and dozens or hundreds of libs. If all of them can depend on each other freely,
the chaos will ensue and the workspace will become unmanageable.
To help with that Nx uses code analyses to make sure projects can only depend on each other's well-defined public API. It also allows you to declaratively impose constraints on how projects can depend on each other.
## Tags
Nx comes with a generic mechanism for expressing constraints: tags.
First, use `nx.json` to annotate your projects with tags. In this example, we will use three tags: `scope:client`. `scope:admin`, `scope:shared`.
```json
{
"npmScope": "myorg",
"implicitDependencies": {
"angular.json": "*",
"package.json": "*",
"tsconfig.json": "*",
"tslint.json": "*",
"nx.json": "*"
},
"projects": {
"client": {
"tags": ["scope:client"],
"implicitDependencies": ["client-e2e"]
},
"client-e2e": {
"tags": ["scope:client"],
"implicitDependencies": []
},
"admin": {
"tags": ["scope:admin"],
"implicitDependencies": ["admin-e2e"]
},
"admin-e2e": {
"tags": ["scope:admin"],
"implicitDependencies": []
},
"client-feature-main": {
"tags": ["scope:client"],
"implicitDependencies": []
},
"admin-feature-permissions": {
"tags": ["scope:admin"],
"implicitDependencies": []
},
"components-shared": {
"tags": ["scope:shared"],
"implicitDependencies": []
}
}
}
```
Next open the top level `tslint.json` to add the constraints.
```json
{
"nx-enforce-module-boundaries": [
true,
{
"allow": [],
"depConstraints": [
{
"sourceTag": "scope:shared",
"onlyDependOnLibsWithTags": ["scope:shared"]
},
{
"sourceTag": "scope:admin",
"onlyDependOnLibsWithTags": ["scope:shared", "scope:admin"]
},
{
"sourceTag": "scope:client",
"onlyDependOnLibsWithTags": ["scope:shared", "scope:client"]
}
]
}
]
}
```
With these constrains in place, `scope:client` projects can only depend on other `scope:client` projects or on `scope:shared` projects. And `scope:admin` projects can only depend on other `scope:admin` projects or on `scope:shared` projects. Projects without any tags cannot depend on any other projects.
If you add the following, projects without any tags will be able to depend on any other project.
```json
{
"sourceTag": "*",
"onlyDependOnLibsWithTags": ["*"]
}
```
If you try to violate the constrains, you will get an err:
![dependency-graph-constraints-lint-error](../fundamentals/lint-error.png)
## Multiple Dimensions
The example above shows using a single dimension: `scope`. It's the most commonly used done. But there are other dimensions that you can find useful. You can define which projects contain components, NgRx code, and features, so you, for instance, can disallow projects containing dumb UI components depend on NgRx. You can define which projects are experimental and which are stable, so stable applications cannot depend on experimental projects etc. You can define which projects have server-side code and which have client-side code to make sure your node app doesn't bundle in Angular.

View File

@ -1,63 +0,0 @@
# Creating an AngularJS Upgrade Module
NgUpgrade is a library put together by the Angular team, which we can use in our application to mix and match AngularJS and Angular components and bridge the AngularJS and Angular dependency injection systems. We can call such an application a “hybrid application”, and the code required to bootstrap it an "upgrade module".
Setting up an Upgrade Module manually involves several steps and is easy to misconfigure. **Nx** provides a command that does it for you.
```console
ng generate upgrade-module legacyApp --app=myapp
```
This will add and set up `UpgradeModule`, configure `legacyApp`, and will add all the needed dependencies to `package.json`.
Open the generated `legacy-app-setup.ts` and you will find all the code needed to bridge the AngularJS and Angular applications.
## Testing Hybrid Applications
For a lot of applications, just running one command is sufficient to convert your application into a hybrid application. That's not always the case--sometimes changes are required. To make this iterative process easier, Nx creates `hybrid.spec.ts`, which you can use to make sure the upgrade module works.
## Schematic
**upgrade-module** _&lt;name&gt; &lt;options ...&gt;_
### Required
- **name** (`string`)
The name of the main AngularJS module.
### Options
- **app** (`string`)
The name of the application to add it to.
- **angularJsImport** (`string`)
Import expression of the AngularJS application (e.g., --angularJsImport=node_modules/my_app).
- **angularJsCmpSelector** (`string`)
The selector of an AngularJS component (e.g., --angularJsCmpSelector=myComponent).
- **skipPackageJson** (`boolean`)
Do not add @angular/upgrade to package.json (e.g., --skipPackageJson). Default is `false`.
- **router** (`boolean`)
Sets up router synchronization (e.g., --router). Default is `false`.
## After Upgrade Module
Nx sets up the upgrade module for you to help you get started with your upgrade process. To learn more on how to upgrade your application, once an upgrade module is set up, check out the following resources:
### Talk: Upgrading Enterprise Angular Applications
In this talk at NgConf, Victor Savkin shows how to upgrade your application gradually, component by component, module by module using NgUpgrade and the Angular Router. He discusses the common problems developers face during such migrations and the patterns that can be used to remedy them.
<a href="https://www.youtube.com/embed/izpqQpD8RQ0" class="embedly-card" data-card-width="100%" data-card-controls="0">Embedded content: https://www.youtube.com/embed/izpqQpD8RQ0</a>
### Blog: Upgrading Angular Applications
In this blog post series Victor Savkin covers similar topics but more in depth. He dives deep into NgUpgrade, including the mental model, implementation, subtleties of the API. Then he talks about different strategies for upgrading large AngularJS applications.
- [NgUpgrade in Depth](https://blog.nrwl.io/ngupgrade-in-depth-436a52298a00)
- [Upgrade Shell](https://blog.nrwl.io/upgrading-angular-applications-upgrade-shell-4d4f4a7e7f7b)
- [Two Approaches to Upgrading Angular Applications](https://blog.nrwl.io/two-approaches-to-upgrading-angular-apps-6350b33384e3)
- [Managing Routers and URL](https://blog.nrwl.io/upgrading-angular-applications-managing-routers-and-url-ca5588290aaa)
- [Using NgUpgrade like a Pro: Lazy Loading AngularJS Applications](https://blog.nrwl.io/using-ngupgrade-like-a-pro-lazy-loading-angularjs-applications-469819f5c86)
### Book: Upgrading Angular Applications
You can also get a book written by Victor Savkin on the subject [here](https://leanpub.com/ngupgrade/).

View File

@ -41,13 +41,36 @@
"itemList": [
{
"name": "Using Cypress",
"id": "cypress"
"id": "modernize-cypress"
},
{
"name": "Using Jest",
"id": "jest"
"id": "modernize-jest"
},
{
"name": "Rebuilding and Retesting What is Affected",
"id": "affected"
},
{
"name": "Analysing & Visualizing Workspaces",
"id": "dependency-diagrams"
},
{
"name": "Imposing Constraints on the Dependency Graph",
"id": "tags"
},
{
"name": "Setting Up NgRx",
"id": "misc-ngrx"
},
{
"name": "Using DataPersistence",
"id": "misc-data-persistence"
},
{
"name": "Upgrading AngularJS Applications",
"id": "misc-upgrade"
}
]
}
]