docs(angular): update tutorial and docs with angular v20 changes (#31356)
Updates the Angular Monorepo tutorials to reflect the changes in Angular v20.
This commit is contained in:
parent
2d33862c43
commit
73e2c506bb
@ -88,23 +88,27 @@ The single-project workspace setup follows a similar structure to what the Angul
|
||||
|
||||
```plaintext
|
||||
└─ myngapp
|
||||
├─ ...
|
||||
├─ public
|
||||
│ └─ favicon.ico
|
||||
├─ src
|
||||
│ ├─ app
|
||||
│ │ ├─ app.component.css
|
||||
│ │ ├─ app.component.html
|
||||
│ │ ├─ app.component.spec.ts
|
||||
│ │ ├─ app.component.ts
|
||||
│ │ └─ app.module.ts
|
||||
│ ├─ assets
|
||||
│ ├─ favicon.ico
|
||||
│ │ ├─ app.config.ts
|
||||
│ │ ├─ app.css
|
||||
│ │ ├─ app.html
|
||||
│ │ ├─ app.routes.ts
|
||||
│ │ ├─ app.spec.ts
|
||||
│ │ ├─ app.ts
|
||||
│ │ └─ nx-welcome.ts
|
||||
│ ├─ index.html
|
||||
│ ├─ main.ts
|
||||
│ └─ styles.css
|
||||
│ ├─ styles.css
|
||||
│ └─ test-setup.ts
|
||||
├─ nx.json
|
||||
├─ package.json
|
||||
├─ project.json
|
||||
├─ ...
|
||||
├─ tsconfig.app.json
|
||||
├─ tsconfig.json
|
||||
└─ tsconfig.spec.json
|
||||
```
|
||||
|
||||
### project.json vs angular.json
|
||||
|
||||
@ -28,7 +28,7 @@
|
||||
"x-priority": "internal"
|
||||
}
|
||||
},
|
||||
"examplesFile": "## Examples\n\n{% tabs %}\n\n{% tab label=\"Basic Usage\" %}\n\nThis generator allows you to convert an Inline SCAM to a Standalone Component. It's important that the SCAM you wish to convert has it's NgModule within the same file for the generator to be able to correctly convert the component to Standalone.\n\n```bash\n\nnx g @nx/angular:scam-to-standalone --component=libs/mylib/src/lib/myscam/myscam.component.ts --project=mylib\n\n```\n\n{% /tab %}\n\n{% /tabs %}\n",
|
||||
"examplesFile": "## Examples\n\n{% tabs %}\n\n{% tab label=\"Basic Usage\" %}\n\nThis generator allows you to convert an Inline SCAM to a Standalone Component. It's important that the SCAM you wish to convert has it's NgModule within the same file for the generator to be able to correctly convert the component to Standalone.\n\n```bash\n\nnx g @nx/angular:scam-to-standalone --component=libs/mylib/src/lib/myscam/myscam.ts --project=mylib\n\n```\n\n{% /tab %}\n\n{% /tabs %}\n",
|
||||
"presets": []
|
||||
},
|
||||
"description": "Convert an existing Single Component Angular Module (SCAM) to a Standalone Component.",
|
||||
|
||||
@ -88,23 +88,27 @@ The single-project workspace setup follows a similar structure to what the Angul
|
||||
|
||||
```plaintext
|
||||
└─ myngapp
|
||||
├─ ...
|
||||
├─ public
|
||||
│ └─ favicon.ico
|
||||
├─ src
|
||||
│ ├─ app
|
||||
│ │ ├─ app.component.css
|
||||
│ │ ├─ app.component.html
|
||||
│ │ ├─ app.component.spec.ts
|
||||
│ │ ├─ app.component.ts
|
||||
│ │ └─ app.module.ts
|
||||
│ ├─ assets
|
||||
│ ├─ favicon.ico
|
||||
│ │ ├─ app.config.ts
|
||||
│ │ ├─ app.css
|
||||
│ │ ├─ app.html
|
||||
│ │ ├─ app.routes.ts
|
||||
│ │ ├─ app.spec.ts
|
||||
│ │ ├─ app.ts
|
||||
│ │ └─ nx-welcome.ts
|
||||
│ ├─ index.html
|
||||
│ ├─ main.ts
|
||||
│ └─ styles.css
|
||||
│ ├─ styles.css
|
||||
│ └─ test-setup.ts
|
||||
├─ nx.json
|
||||
├─ package.json
|
||||
├─ project.json
|
||||
├─ ...
|
||||
├─ tsconfig.app.json
|
||||
├─ tsconfig.json
|
||||
└─ tsconfig.spec.json
|
||||
```
|
||||
|
||||
### project.json vs angular.json
|
||||
|
||||
@ -45,11 +45,11 @@ declare const MY_API_URL: string;
|
||||
|
||||
The above would allow you to use the `MY_API_URL` variable in your application code as in the following example:
|
||||
|
||||
```ts {% fileName="apps/my-app/src/app/api.service.ts" highlightLines=[6] %}
|
||||
```ts {% fileName="apps/my-app/src/app/api-http-client.ts" highlightLines=[6] %}
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class ApiService {
|
||||
export class ApiHttpClient {
|
||||
constructor() {
|
||||
console.log('API URL:', MY_API_URL);
|
||||
}
|
||||
@ -92,11 +92,11 @@ You could also add the Node.js types to your `tsconfig.json` file, but this woul
|
||||
|
||||
And then use the variable in your application code:
|
||||
|
||||
```ts {% fileName="apps/my-app/src/app/api.service.ts" highlightLines=[6] %}
|
||||
```ts {% fileName="apps/my-app/src/app/api-http-client.ts" highlightLines=[6] %}
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class ApiService {
|
||||
export class ApiHttpClient {
|
||||
constructor() {
|
||||
console.log('API URL:', process.env.MY_API_URL);
|
||||
}
|
||||
@ -169,11 +169,11 @@ Alternatively, you can also [set environment variables when running a terminal c
|
||||
|
||||
Finally, you can use the environment variables in your application code:
|
||||
|
||||
```ts {% fileName="apps/my-app/src/app/api.service.ts" highlightLines=[6] %}
|
||||
```ts {% fileName="apps/my-app/src/app/api-http-client.ts" highlightLines=[6] %}
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class ApiService {
|
||||
export class ApiHttpClient {
|
||||
constructor() {
|
||||
console.log('API URL:', process.env.MY_ORG_API_URL);
|
||||
}
|
||||
@ -285,11 +285,11 @@ Alternatively, you can also [set environment variables when running a terminal c
|
||||
|
||||
Finally, we can use environment variables in our code:
|
||||
|
||||
```ts {% fileName="apps/my-app/src/app/api.service.ts" highlightLines=[6] %}
|
||||
```ts {% fileName="apps/my-app/src/app/api-http-client.ts" highlightLines=[6] %}
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class ApiService {
|
||||
export class ApiHttpClient {
|
||||
constructor() {
|
||||
console.log('API URL:', process.env.MY_ORG_API_URL);
|
||||
}
|
||||
|
||||
@ -62,14 +62,13 @@ CREATE apps/angular/shell/src/favicon.ico
|
||||
CREATE apps/angular/shell/src/index.html
|
||||
CREATE apps/angular/shell/src/styles.css
|
||||
CREATE apps/angular/shell/tsconfig.app.json
|
||||
CREATE apps/angular/shell/tsconfig.editor.json
|
||||
CREATE apps/angular/shell/tsconfig.json
|
||||
CREATE apps/angular/shell/src/app/app.component.css
|
||||
CREATE apps/angular/shell/src/app/app.component.html
|
||||
CREATE apps/angular/shell/src/app/app.component.spec.ts
|
||||
CREATE apps/angular/shell/src/app/app.component.ts
|
||||
CREATE apps/angular/shell/src/app/app.css
|
||||
CREATE apps/angular/shell/src/app/app.html
|
||||
CREATE apps/angular/shell/src/app/app.spec.ts
|
||||
CREATE apps/angular/shell/src/app/app.ts
|
||||
CREATE apps/angular/shell/src/app/app.routes.ts
|
||||
CREATE apps/angular/shell/src/app/nx-welcome.component.ts
|
||||
CREATE apps/angular/shell/src/app/nx-welcome.ts
|
||||
CREATE apps/angular/shell/src/main.ts
|
||||
CREATE apps/angular/shell/.eslintrc.json
|
||||
CREATE apps/angular/shell/jest.config.ts
|
||||
@ -180,14 +179,13 @@ CREATE apps/angular/with-remotes/shell/src/favicon.ico
|
||||
CREATE apps/angular/with-remotes/shell/src/index.html
|
||||
CREATE apps/angular/with-remotes/shell/src/styles.css
|
||||
CREATE apps/angular/with-remotes/shell/tsconfig.app.json
|
||||
CREATE apps/angular/with-remotes/shell/tsconfig.editor.json
|
||||
CREATE apps/angular/with-remotes/shell/tsconfig.json
|
||||
CREATE apps/angular/with-remotes/shell/src/app/app.component.css
|
||||
CREATE apps/angular/with-remotes/shell/src/app/app.component.html
|
||||
CREATE apps/angular/with-remotes/shell/src/app/app.component.spec.ts
|
||||
CREATE apps/angular/with-remotes/shell/src/app/app.component.ts
|
||||
CREATE apps/angular/with-remotes/shell/src/app/app.css
|
||||
CREATE apps/angular/with-remotes/shell/src/app/app.html
|
||||
CREATE apps/angular/with-remotes/shell/src/app/app.spec.ts
|
||||
CREATE apps/angular/with-remotes/shell/src/app/app.ts
|
||||
CREATE apps/angular/with-remotes/shell/src/app/app.routes.ts
|
||||
CREATE apps/angular/with-remotes/shell/src/app/nx-welcome.component.ts
|
||||
CREATE apps/angular/with-remotes/shell/src/app/nx-welcome.ts
|
||||
CREATE apps/angular/with-remotes/shell/src/main.ts
|
||||
CREATE apps/angular/with-remotes/shell/.eslintrc.json
|
||||
CREATE apps/angular/with-remotes/shell/jest.config.ts
|
||||
@ -204,18 +202,17 @@ CREATE apps/angular/with-remotes/ng-remote1/src/favicon.ico
|
||||
CREATE apps/angular/with-remotes/ng-remote1/src/index.html
|
||||
CREATE apps/angular/with-remotes/ng-remote1/src/styles.css
|
||||
CREATE apps/angular/with-remotes/ng-remote1/tsconfig.app.json
|
||||
CREATE apps/angular/with-remotes/ng-remote1/tsconfig.editor.json
|
||||
CREATE apps/angular/with-remotes/ng-remote1/tsconfig.json
|
||||
CREATE apps/angular/with-remotes/ng-remote1/src/app/app.component.ts
|
||||
CREATE apps/angular/with-remotes/ng-remote1/src/app/app.ts
|
||||
CREATE apps/angular/with-remotes/ng-remote1/src/app/app.routes.ts
|
||||
CREATE apps/angular/with-remotes/ng-remote1/src/main.ts
|
||||
CREATE apps/angular/with-remotes/ng-remote1/.eslintrc.json
|
||||
CREATE apps/angular/with-remotes/ng-remote1/jest.config.ts
|
||||
CREATE apps/angular/with-remotes/ng-remote1/src/test-setup.ts
|
||||
CREATE apps/angular/with-remotes/ng-remote1/tsconfig.spec.json
|
||||
CREATE apps/angular/with-remotes/ng-remote1/src/app/remote-entry/entry.component.ts
|
||||
CREATE apps/angular/with-remotes/ng-remote1/src/app/remote-entry/entry.ts
|
||||
CREATE apps/angular/with-remotes/ng-remote1/src/app/remote-entry/entry.routes.ts
|
||||
CREATE apps/angular/with-remotes/ng-remote1/src/app/remote-entry/nx-welcome.component.ts
|
||||
CREATE apps/angular/with-remotes/ng-remote1/src/app/remote-entry/nx-welcome.ts
|
||||
CREATE apps/angular/with-remotes/ng-remote1/module-federation.config.ts
|
||||
CREATE apps/angular/with-remotes/ng-remote1/webpack.config.ts
|
||||
CREATE apps/angular/with-remotes/ng-remote1/webpack.prod.config.ts
|
||||
@ -229,18 +226,17 @@ CREATE apps/angular/with-remotes/ng-remote2/src/favicon.ico
|
||||
CREATE apps/angular/with-remotes/ng-remote2/src/index.html
|
||||
CREATE apps/angular/with-remotes/ng-remote2/src/styles.css
|
||||
CREATE apps/angular/with-remotes/ng-remote2/tsconfig.app.json
|
||||
CREATE apps/angular/with-remotes/ng-remote2/tsconfig.editor.json
|
||||
CREATE apps/angular/with-remotes/ng-remote2/tsconfig.json
|
||||
CREATE apps/angular/with-remotes/ng-remote2/src/app/app.component.ts
|
||||
CREATE apps/angular/with-remotes/ng-remote2/src/app/app.ts
|
||||
CREATE apps/angular/with-remotes/ng-remote2/src/app/app.routes.ts
|
||||
CREATE apps/angular/with-remotes/ng-remote2/src/main.ts
|
||||
CREATE apps/angular/with-remotes/ng-remote2/.eslintrc.json
|
||||
CREATE apps/angular/with-remotes/ng-remote2/jest.config.ts
|
||||
CREATE apps/angular/with-remotes/ng-remote2/src/test-setup.ts
|
||||
CREATE apps/angular/with-remotes/ng-remote2/tsconfig.spec.json
|
||||
CREATE apps/angular/with-remotes/ng-remote2/src/app/remote-entry/entry.component.ts
|
||||
CREATE apps/angular/with-remotes/ng-remote2/src/app/remote-entry/entry.ts
|
||||
CREATE apps/angular/with-remotes/ng-remote2/src/app/remote-entry/entry.routes.ts
|
||||
CREATE apps/angular/with-remotes/ng-remote2/src/app/remote-entry/nx-welcome.component.ts
|
||||
CREATE apps/angular/with-remotes/ng-remote2/src/app/remote-entry/nx-welcome.ts
|
||||
CREATE apps/angular/with-remotes/ng-remote2/module-federation.config.ts
|
||||
CREATE apps/angular/with-remotes/ng-remote2/webpack.config.ts
|
||||
CREATE apps/angular/with-remotes/ng-remote2/webpack.prod.config.ts
|
||||
|
||||
@ -63,18 +63,17 @@ CREATE apps/angular/myremote/src/favicon.ico
|
||||
CREATE apps/angular/myremote/src/index.html
|
||||
CREATE apps/angular/myremote/src/styles.css
|
||||
CREATE apps/angular/myremote/tsconfig.app.json
|
||||
CREATE apps/angular/myremote/tsconfig.editor.json
|
||||
CREATE apps/angular/myremote/tsconfig.json
|
||||
CREATE apps/angular/myremote/src/app/app.component.ts
|
||||
CREATE apps/angular/myremote/src/app/app.ts
|
||||
CREATE apps/angular/myremote/src/app/app.routes.ts
|
||||
CREATE apps/angular/myremote/src/main.ts
|
||||
CREATE apps/angular/myremote/.eslintrc.json
|
||||
CREATE apps/angular/myremote/jest.config.ts
|
||||
CREATE apps/angular/myremote/src/test-setup.ts
|
||||
CREATE apps/angular/myremote/tsconfig.spec.json
|
||||
CREATE apps/angular/myremote/src/app/remote-entry/entry.component.ts
|
||||
CREATE apps/angular/myremote/src/app/remote-entry/entry.ts
|
||||
CREATE apps/angular/myremote/src/app/remote-entry/entry.routes.ts
|
||||
CREATE apps/angular/myremote/src/app/remote-entry/nx-welcome.component.ts
|
||||
CREATE apps/angular/myremote/src/app/remote-entry/nx-welcome.ts
|
||||
CREATE apps/angular/myremote/module-federation.config.ts
|
||||
CREATE apps/angular/myremote/webpack.config.ts
|
||||
CREATE apps/angular/myremote/webpack.prod.config.ts
|
||||
@ -172,18 +171,17 @@ CREATE apps/angular/myremote/src/favicon.ico
|
||||
CREATE apps/angular/myremote/src/index.html
|
||||
CREATE apps/angular/myremote/src/styles.css
|
||||
CREATE apps/angular/myremote/tsconfig.app.json
|
||||
CREATE apps/angular/myremote/tsconfig.editor.json
|
||||
CREATE apps/angular/myremote/tsconfig.json
|
||||
CREATE apps/angular/myremote/src/app/app.component.ts
|
||||
CREATE apps/angular/myremote/src/app/app.ts
|
||||
CREATE apps/angular/myremote/src/app/app.routes.ts
|
||||
CREATE apps/angular/myremote/src/main.ts
|
||||
CREATE apps/angular/myremote/.eslintrc.json
|
||||
CREATE apps/angular/myremote/jest.config.ts
|
||||
CREATE apps/angular/myremote/src/test-setup.ts
|
||||
CREATE apps/angular/myremote/tsconfig.spec.json
|
||||
CREATE apps/angular/myremote/src/app/remote-entry/entry.component.ts
|
||||
CREATE apps/angular/myremote/src/app/remote-entry/entry.ts
|
||||
CREATE apps/angular/myremote/src/app/remote-entry/entry.routes.ts
|
||||
CREATE apps/angular/myremote/src/app/remote-entry/nx-welcome.component.ts
|
||||
CREATE apps/angular/myremote/src/app/remote-entry/nx-welcome.ts
|
||||
CREATE apps/angular/myremote/module-federation.config.ts
|
||||
CREATE apps/angular/myremote/webpack.config.ts
|
||||
CREATE apps/angular/myremote/webpack.prod.config.ts
|
||||
|
||||
@ -219,14 +219,14 @@ We need an Angular Service that we will use to hold state:
|
||||
nx g @nx/angular:service libs/shared/data-access-user/src/lib/user
|
||||
```
|
||||
|
||||
This will create the `libs/shared/data-access-user/src/lib/user.service.ts` file. Change its contents to match:
|
||||
This will create the `libs/shared/data-access-user/src/lib/user-auth.ts` file. Change its contents to match:
|
||||
|
||||
```ts {% fileName="libs/shared/data-access-user/src/lib/user.service.ts" %}
|
||||
```ts {% fileName="libs/shared/data-access-user/src/lib/user-auth.ts" %}
|
||||
import { Injectable } from '@angular/core';
|
||||
import { BehaviorSubject } from 'rxjs';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class UserService {
|
||||
export class UserAuth {
|
||||
private isUserLoggedIn = new BehaviorSubject(false);
|
||||
isUserLoggedIn$ = this.isUserLoggedIn.asObservable();
|
||||
|
||||
@ -251,9 +251,9 @@ export * from './lib/user.service';
|
||||
|
||||
### Login Application
|
||||
|
||||
Let's set up our `entry.component.ts` file in the **Login** application so that it renders a login form. We'll import `FormsModule` and inject our `UserService` to allow us to sign the user in:
|
||||
Let's set up our `entry.ts` file in the **Login** application so that it renders a login form. We'll import `FormsModule` and inject our `UserService` to allow us to sign the user in:
|
||||
|
||||
```ts {% fileName="apps/login/src/app/remote-entry/entry.component.ts" %}
|
||||
```ts {% fileName="apps/login/src/app/remote-entry/entry.ts" %}
|
||||
import { Component } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
@ -301,7 +301,7 @@ import { inject } from '@angular/core';
|
||||
`,
|
||||
],
|
||||
})
|
||||
export class RemoteEntryComponent {
|
||||
export class RemoteEntry {
|
||||
private userService = inject(UserService);
|
||||
username = '';
|
||||
password = '';
|
||||
@ -339,11 +339,11 @@ For this to work, the state within `UserService` must be shared across both appl
|
||||
This helps to enforce a single version policy and reduces the risk of [Micro Frontend Anarchy](https://www.thoughtworks.com/radar/techniques/micro-frontend-anarchy).
|
||||
{% /callout %}
|
||||
|
||||
Start by deleting the `app.component.html`, `app.component.css`, and `nx-welcome.component.ts` files from the **Dashboard** application. They will not be needed for this tutorial.
|
||||
Start by deleting the `app.html`, `app.css`, and `nx-welcome.ts` files from the **Dashboard** application. They will not be needed for this tutorial.
|
||||
|
||||
Next, let's add our logic to the `app.component.ts` file. Change it to match the following:
|
||||
Next, let's add our logic to the `app.ts` file. Change it to match the following:
|
||||
|
||||
```ts {% fileName="apps/dashboard/src/app/app.component.ts" %}
|
||||
```ts {% fileName="apps/dashboard/src/app/app.ts" %}
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { Component, inject, OnInit } from '@angular/core';
|
||||
import { Router, RouterModule } from '@angular/router';
|
||||
@ -362,7 +362,7 @@ import { distinctUntilChanged } from 'rxjs/operators';
|
||||
<ng-template #signIn><router-outlet></router-outlet></ng-template>
|
||||
`,
|
||||
})
|
||||
export class AppComponent implements OnInit {
|
||||
export class App implements OnInit {
|
||||
private router = inject(Router);
|
||||
private userService = inject(UserService);
|
||||
isLoggedIn$ = this.userService.isUserLoggedIn$;
|
||||
@ -388,7 +388,7 @@ Finally, make sure the application routes are correctly set up:
|
||||
|
||||
```ts {% fileName="apps/dashboard/src/app/app.routes.ts" %}
|
||||
import { Route } from '@angular/router';
|
||||
import { AppComponent } from './app.component';
|
||||
import { App } from './app';
|
||||
|
||||
export const appRoutes: Route[] = [
|
||||
{
|
||||
@ -397,7 +397,7 @@ export const appRoutes: Route[] = [
|
||||
},
|
||||
{
|
||||
path: '',
|
||||
component: AppComponent,
|
||||
component: App,
|
||||
},
|
||||
];
|
||||
```
|
||||
@ -483,7 +483,7 @@ Next, we need to change how our application attempts to load the Remote when it
|
||||
```ts {% fileName="apps/dashboard/src/app/app.routes.ts" highlightLines=[2, "8-9"] %}
|
||||
import { Route } from '@angular/router';
|
||||
import { loadRemoteModule } from '@nx/angular/mf';
|
||||
import { AppComponent } from './app.component';
|
||||
import { App } from './app';
|
||||
|
||||
export const appRoutes: Route[] = [
|
||||
{
|
||||
@ -493,7 +493,7 @@ export const appRoutes: Route[] = [
|
||||
},
|
||||
{
|
||||
path: '',
|
||||
component: AppComponent,
|
||||
component: App,
|
||||
},
|
||||
];
|
||||
```
|
||||
|
||||
@ -32,8 +32,8 @@ happynrwl/
|
||||
| | | | ├── src/
|
||||
| | | | | ├──lib
|
||||
| | | | | | ├──my-header
|
||||
| | | | | | | ├── my-header.component.ts
|
||||
| | | | | | | ├── my-header.component.stories.ts
|
||||
| | | | | | | ├── my-header.ts
|
||||
| | | | | | | ├── my-header.stories.ts
|
||||
| | | | | | | └── etc...
|
||||
| | | | | | └── etc...
|
||||
| | | | | └── etc...
|
||||
|
||||
@ -25,8 +25,8 @@ The [`@nx/angular:storybook-configuration` generator](/technologies/angular/api/
|
||||
|
||||
```text
|
||||
<some-folder>/
|
||||
├── my.component.ts
|
||||
└── my.component.stories.ts
|
||||
├── my-component.ts
|
||||
└── my-component.stories.ts
|
||||
```
|
||||
|
||||
If you add more components to your project, and want to generate stories for all your (new) components at any point, you can use the [`@nx/angular:stories` generator](/technologies/angular/api/generators/stories):
|
||||
@ -56,8 +56,8 @@ and the result would be the following:
|
||||
| | | ├── src/
|
||||
| | | | ├──lib
|
||||
| | | | | ├──my-button
|
||||
| | | | | | ├── my-button.component.ts
|
||||
| | | | | | ├── my-button.component.stories.ts
|
||||
| | | | | | ├── my-button.ts
|
||||
| | | | | | ├── my-button.stories.ts
|
||||
| | | | | | └── etc...
|
||||
| | | | | └── etc...
|
||||
| | | ├── README.md
|
||||
@ -79,7 +79,7 @@ Let's take for example a library in your workspace, under `libs/feature/ui`, cal
|
||||
|
||||
Let's say that the template for that component looks like this:
|
||||
|
||||
```html {% fileName="libs/feature/ui/src/lib/my-button/my-button.component.html" %}
|
||||
```html {% fileName="libs/feature/ui/src/lib/my-button/my-button.html" %}
|
||||
<button [disabled]="disabled" [ngStyle]="{ 'padding.px': padding }">
|
||||
{{ text }}
|
||||
</button>
|
||||
@ -87,16 +87,16 @@ Let's say that the template for that component looks like this:
|
||||
|
||||
and the component looks like this:
|
||||
|
||||
```typescript {% fileName="libs/feature/ui/src/lib/my-button/my-button.component.ts" %}
|
||||
```typescript {% fileName="libs/feature/ui/src/lib/my-button/my-button.ts" %}
|
||||
import { Component, Input } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'feature-ui-my-button',
|
||||
standalone: true,
|
||||
templateUrl: './my-button.component.html',
|
||||
styleUrls: ['./my-button.component.css'],
|
||||
templateUrl: './my-button.html',
|
||||
styleUrls: ['./my-button.css'],
|
||||
})
|
||||
export class MyButtonComponent {
|
||||
export class MyButton {
|
||||
@Input() text = 'Click me!';
|
||||
@Input() padding = 10;
|
||||
@Input() disabled = true;
|
||||
@ -107,18 +107,18 @@ export class MyButtonComponent {
|
||||
|
||||
The [`@nx/angular:storybook-configuration` generator](/technologies/angular/api/generators/storybook-configuration) would generate a Story file that looks like this:
|
||||
|
||||
```typescript {% fileName="libs/feature/ui/src/lib/my-button/my-button.component.stories.ts" %}
|
||||
```typescript {% fileName="libs/feature/ui/src/lib/my-button/my-button.stories.ts" %}
|
||||
import type { Meta, StoryObj } from '@storybook/angular';
|
||||
import { MyButtonComponent } from './my-button.component';
|
||||
import { MyButton } from './my-button';
|
||||
import { within } from '@storybook/testing-library';
|
||||
import { expect } from '@storybook/jest';
|
||||
|
||||
const meta: Meta<MyButtonComponent> = {
|
||||
component: MyButtonComponent,
|
||||
title: 'MyButtonComponent',
|
||||
const meta: Meta<MyButton> = {
|
||||
component: MyButton,
|
||||
title: 'MyButton',
|
||||
};
|
||||
export default meta;
|
||||
type Story = StoryObj<MyButtonComponent>;
|
||||
type Story = StoryObj<MyButton>;
|
||||
|
||||
export const Primary: Story = {
|
||||
args: {
|
||||
|
||||
@ -69,13 +69,13 @@ Let's name the initial application `angular-store`. In this tutorial we're going
|
||||
│ ├─ angular-store
|
||||
│ │ ├─ src
|
||||
│ │ │ ├─ app
|
||||
│ │ │ │ ├─ app.component.css
|
||||
│ │ │ │ ├─ app.component.html
|
||||
│ │ │ │ ├─ app.component.spec.ts
|
||||
│ │ │ │ ├─ app.component.ts
|
||||
│ │ │ │ ├─ app.css
|
||||
│ │ │ │ ├─ app.html
|
||||
│ │ │ │ ├─ app.spec.ts
|
||||
│ │ │ │ ├─ app.ts
|
||||
│ │ │ │ ├─ app.config.ts
|
||||
│ │ │ │ ├─ app.routes.ts
|
||||
│ │ │ │ └─ nx-welcome.component.ts
|
||||
│ │ │ │ └─ nx-welcome.ts
|
||||
│ │ │ ├─ assets
|
||||
│ │ │ ├─ index.html
|
||||
│ │ │ ├─ main.ts
|
||||
@ -85,7 +85,6 @@ Let's name the initial application `angular-store`. In this tutorial we're going
|
||||
│ │ ├─ jest.config.ts
|
||||
│ │ ├─ project.json
|
||||
│ │ ├─ tsconfig.app.json
|
||||
│ │ ├─ tsconfig.editor.json
|
||||
│ │ ├─ tsconfig.json
|
||||
│ │ └─ tsconfig.spec.json
|
||||
│ └─ angular-store-e2e
|
||||
@ -153,7 +152,7 @@ Each target contains a configuration object that tells Nx how to run that target
|
||||
...
|
||||
"targets": {
|
||||
"serve": {
|
||||
"executor": "@angular-devkit/build-angular:dev-server",
|
||||
"executor": "@angular/build:dev-server",
|
||||
"defaultConfiguration": "development",
|
||||
"options": {
|
||||
"buildTarget": "angular-store:build"
|
||||
@ -240,14 +239,13 @@ CREATE apps/inventory/src/favicon.ico
|
||||
CREATE apps/inventory/src/index.html
|
||||
CREATE apps/inventory/src/styles.css
|
||||
CREATE apps/inventory/tsconfig.app.json
|
||||
CREATE apps/inventory/tsconfig.editor.json
|
||||
CREATE apps/inventory/tsconfig.json
|
||||
CREATE apps/inventory/src/app/app.component.css
|
||||
CREATE apps/inventory/src/app/app.component.html
|
||||
CREATE apps/inventory/src/app/app.component.spec.ts
|
||||
CREATE apps/inventory/src/app/app.component.ts
|
||||
CREATE apps/inventory/src/app/app.css
|
||||
CREATE apps/inventory/src/app/app.html
|
||||
CREATE apps/inventory/src/app/app.spec.ts
|
||||
CREATE apps/inventory/src/app/app.ts
|
||||
CREATE apps/inventory/src/app/app.config.ts
|
||||
CREATE apps/inventory/src/app/nx-welcome.component.ts
|
||||
CREATE apps/inventory/src/app/nx-welcome.ts
|
||||
CREATE apps/inventory/src/main.ts
|
||||
CREATE apps/inventory/.eslintrc.json
|
||||
CREATE apps/inventory/jest.config.ts
|
||||
@ -290,9 +288,9 @@ When you develop your Angular application, usually all your logic sits in the `a
|
||||
│ │ │ ├─ cart
|
||||
│ │ │ ├─ ui
|
||||
│ │ │ ├─ ...
|
||||
│ │ │ └─ app.tsx
|
||||
│ │ │ └─ app.ts
|
||||
│ │ ├─ ...
|
||||
│ │ └─ main.tsx
|
||||
│ │ └─ main.ts
|
||||
│ ├─ ...
|
||||
│ └─ project.json
|
||||
├─ nx.json
|
||||
@ -314,9 +312,9 @@ Nx allows you to separate this logic into "local libraries". The main benefits i
|
||||
Let's assume our domain areas include `products`, `orders` and some more generic design system components, called `ui`. We can generate a new library for each of these areas using the Angular library generator:
|
||||
|
||||
```
|
||||
npx nx g @nx/angular:library libs/products --standalone
|
||||
npx nx g @nx/angular:library libs/orders --standalone
|
||||
npx nx g @nx/angular:library libs/shared/ui --standalone
|
||||
npx nx g @nx/angular:library libs/products
|
||||
npx nx g @nx/angular:library libs/orders
|
||||
npx nx g @nx/angular:library libs/shared/ui
|
||||
```
|
||||
|
||||
Note how we type out the full path in the `directory` flag to place the libraries into a subfolder. You can choose whatever folder structure you like to organize your projects. If you change your mind later, you can run the [move generator](/reference/core-api/workspace/generators/move) to move a project to a different folder.
|
||||
@ -384,51 +382,56 @@ All libraries that we generate automatically have aliases created in the root-le
|
||||
}
|
||||
```
|
||||
|
||||
Hence we can easily import them into other libraries and our Angular application. As an example, let's use the pre-generated `ProductsComponent` component from our `libs/products` library.
|
||||
Hence we can easily import them into other libraries and our Angular application. As an example, let's use the pre-generated `Products` component from our `libs/products` library.
|
||||
|
||||
You can see that the `ProductsComponent` is exported via the `index.ts` file of our `products` library so that other projects in the repository can use it. This is our public API with the rest of the workspace. Only export what's really necessary to be usable outside the library itself.
|
||||
You can see that the `Products` is exported via the `index.ts` file of our `products` library so that other projects in the repository can use it. This is our public API with the rest of the workspace. Only export what's really necessary to be usable outside the library itself.
|
||||
|
||||
```ts {% fileName="libs/products/src/index.ts" %}
|
||||
export * from './lib/products/products.component';
|
||||
export * from './lib/products/products';
|
||||
```
|
||||
|
||||
We're ready to import it into our main application now. First (if you haven't already), let's set up the Angular router. Configure it in the `app.config.ts`.
|
||||
|
||||
```ts {% fileName="apps/angular-store/src/app/app.config.ts" highlightLines=[2,3,4,5,6,9] %}
|
||||
import { ApplicationConfig } from '@angular/core';
|
||||
```ts {% fileName="apps/angular-store/src/app/app.config.ts" highlightLines=[6,7,13] %}
|
||||
import {
|
||||
provideRouter,
|
||||
withEnabledBlockingInitialNavigation,
|
||||
} from '@angular/router';
|
||||
ApplicationConfig,
|
||||
provideBrowserGlobalErrorListeners,
|
||||
provideZoneChangeDetection,
|
||||
} from '@angular/core';
|
||||
import { provideRouter } from '@angular/router';
|
||||
import { appRoutes } from './app.routes';
|
||||
|
||||
export const appConfig: ApplicationConfig = {
|
||||
providers: [provideRouter(appRoutes, withEnabledBlockingInitialNavigation())],
|
||||
providers: [
|
||||
provideBrowserGlobalErrorListeners(),
|
||||
provideZoneChangeDetection({ eventCoalescing: true }),
|
||||
provideRouter(appRoutes),
|
||||
],
|
||||
};
|
||||
```
|
||||
|
||||
And in `app.component.html`:
|
||||
And in `app.html`:
|
||||
|
||||
```ts {% fileName="apps/angular-store/src/app/app.component.html" %}
|
||||
```ts {% fileName="apps/angular-store/src/app/app.html" %}
|
||||
<router-outlet></router-outlet>
|
||||
```
|
||||
|
||||
Then we can add the `ProductsComponent` component to our `app.routes.ts` and render it via the routing mechanism whenever a user hits the `/products` route.
|
||||
Then we can add the `Products` component to our `app.routes.ts` and render it via the routing mechanism whenever a user hits the `/products` route.
|
||||
|
||||
```ts {% fileName="apps/angular-store/src/app/app.routes.ts" highlightLines=[10,11,12,13,14] %}
|
||||
import { Route } from '@angular/router';
|
||||
import { NxWelcomeComponent } from './nx-welcome.component';
|
||||
import { NxWelcome } from './nx-welcome';
|
||||
|
||||
export const appRoutes: Route[] = [
|
||||
{
|
||||
path: '',
|
||||
component: NxWelcomeComponent,
|
||||
component: NxWelcome,
|
||||
pathMatch: 'full',
|
||||
},
|
||||
{
|
||||
path: 'products',
|
||||
loadComponent: () =>
|
||||
import('@angular-monorepo/products').then((m) => m.ProductsComponent),
|
||||
import('@angular-monorepo/products').then((m) => m.Products),
|
||||
},
|
||||
];
|
||||
```
|
||||
@ -439,51 +442,51 @@ Serving your app (`npx nx serve angular-store`) and then navigating to `/product
|
||||
|
||||
Let's apply the same for our `orders` library.
|
||||
|
||||
- import the `OrdersComponent` from `libs/orders` into the `app.routes.ts` and render it via the routing mechanism whenever a user hits the `/orders` route
|
||||
- import the `Orders` from `libs/orders` into the `app.routes.ts` and render it via the routing mechanism whenever a user hits the `/orders` route
|
||||
|
||||
In the end, your `app.routes.ts` should look similar to this:
|
||||
|
||||
```ts {% fileName="apps/angular-store/src/app/app.routes.ts" highlightLines=[15,16,17,18,19] %}
|
||||
import { Route } from '@angular/router';
|
||||
import { NxWelcomeComponent } from './nx-welcome.component';
|
||||
import { NxWelcome } from './nx-welcome';
|
||||
|
||||
export const appRoutes: Route[] = [
|
||||
{
|
||||
path: '',
|
||||
component: NxWelcomeComponent,
|
||||
component: NxWelcome,
|
||||
pathMatch: 'full',
|
||||
},
|
||||
{
|
||||
path: 'products',
|
||||
loadComponent: () =>
|
||||
import('@angular-monorepo/products').then((m) => m.ProductsComponent),
|
||||
import('@angular-monorepo/products').then((m) => m.Products),
|
||||
},
|
||||
{
|
||||
path: 'orders',
|
||||
loadComponent: () =>
|
||||
import('@angular-monorepo/orders').then((m) => m.OrdersComponent),
|
||||
import('@angular-monorepo/orders').then((m) => m.Orders),
|
||||
},
|
||||
];
|
||||
```
|
||||
|
||||
Let's also show products in the `inventory` app.
|
||||
|
||||
```ts {% fileName="apps/inventory/src/app/app.component.ts" highlightLines=[2,5] %}
|
||||
```ts {% fileName="apps/inventory/src/app/app.ts" highlightLines=[2,5] %}
|
||||
import { Component } from '@angular/core';
|
||||
import { ProductsComponent } from '@angular-monorepo/products';
|
||||
import { Products } from '@angular-monorepo/products';
|
||||
|
||||
@Component({
|
||||
imports: [ProductsComponent],
|
||||
imports: [Products],
|
||||
selector: 'app-root',
|
||||
templateUrl: './app.component.html',
|
||||
styleUrl: './app.component.css',
|
||||
templateUrl: './app.html',
|
||||
styleUrl: './app.css',
|
||||
})
|
||||
export class AppComponent {
|
||||
export class App {
|
||||
title = 'inventory';
|
||||
}
|
||||
```
|
||||
|
||||
```ts {% fileName="apps/inventory/src/app/app.component.html" %}
|
||||
```ts {% fileName="apps/inventory/src/app/app.html" %}
|
||||
<lib-products></lib-products>
|
||||
```
|
||||
|
||||
@ -909,7 +912,7 @@ git commit -a -m "some commit message"
|
||||
|
||||
And then make a small change to the `products` library.
|
||||
|
||||
```html {% fileName="libs/products/src/lib/product-list/product-list.component.html" %}
|
||||
```html {% fileName="libs/products/src/lib/product-list/product-list.html" %}
|
||||
<p>product-list works!</p>
|
||||
<p>This is a change. 👋</p>
|
||||
```
|
||||
@ -1030,10 +1033,10 @@ If you're ready and want to ship your applications, you can build them using
|
||||
```{% command="npx nx run-many -t build" path="angular-monorepo" %}
|
||||
NX Generating @nx/angular:component
|
||||
|
||||
CREATE libs/orders/src/lib/order-list/order-list.component.css
|
||||
CREATE libs/orders/src/lib/order-list/order-list.component.html
|
||||
CREATE libs/orders/src/lib/order-list/order-list.component.spec.ts
|
||||
CREATE libs/orders/src/lib/order-list/order-list.component.ts
|
||||
CREATE libs/orders/src/lib/order-list/order-list.css
|
||||
CREATE libs/orders/src/lib/order-list/order-list.html
|
||||
CREATE libs/orders/src/lib/order-list/order-list.spec.ts
|
||||
CREATE libs/orders/src/lib/order-list/order-list.ts
|
||||
UPDATE libs/orders/src/index.ts
|
||||
❯ nx run-many -t build
|
||||
|
||||
@ -1174,23 +1177,23 @@ To enforce the rules, Nx ships with a custom ESLint rule. Open the `.eslintrc.ba
|
||||
}
|
||||
```
|
||||
|
||||
To test it, go to your `libs/products/src/lib/product-list/product-list.component.ts` file and import the `OrdersComponent` from the `orders` project:
|
||||
To test it, go to your `libs/products/src/lib/product-list/product-list.ts` file and import the `Orders` component from the `orders` project:
|
||||
|
||||
```ts {% fileName="libs/products/src/lib/product-list/product-list.component.ts" highlightLines=[4,5] %}
|
||||
```ts {% fileName="libs/products/src/lib/product-list/product-list.ts" highlightLines=[4,5] %}
|
||||
import { Component } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
|
||||
// This import is not allowed 👇
|
||||
import { OrdersComponent } from '@angular-monorepo/orders';
|
||||
import { Orders } from '@angular-monorepo/orders';
|
||||
|
||||
@Component({
|
||||
selector: 'angular-monorepo-product-list',
|
||||
standalone: true,
|
||||
imports: [CommonModule],
|
||||
templateUrl: './product-list.component.html',
|
||||
styleUrls: ['./product-list.component.css'],
|
||||
templateUrl: './product-list.html',
|
||||
styleUrls: ['./product-list.css'],
|
||||
})
|
||||
export class ProductsComponent {}
|
||||
export class Products {}
|
||||
```
|
||||
|
||||
If you lint your workspace you'll get an error now:
|
||||
@ -1200,9 +1203,9 @@ NX Running target lint for 7 projects
|
||||
✖ nx run products:lint
|
||||
Linting "products"...
|
||||
|
||||
/Users/isaac/Documents/code/nx-recipes/angular-monorepo/libs/products/src/lib/product-list/product-list.component.ts
|
||||
/Users/isaac/Documents/code/nx-recipes/angular-monorepo/libs/products/src/lib/product-list/product-list.ts
|
||||
5:1 error A project tagged with "scope:products" can only depend on libs tagged with "scope:products", "scope:shared" @nx/enforce-module-boundaries
|
||||
5:10 warning 'OrdersComponent' is defined but never used @typescript-eslint/no-unused-vars
|
||||
5:10 warning 'Orders' is defined but never used @typescript-eslint/no-unused-vars
|
||||
|
||||
✖ 2 problems (1 error, 1 warning)
|
||||
|
||||
|
||||
@ -19,7 +19,7 @@ One of the key features of Nx in a monorepo setting is that you're able to run t
|
||||
|
||||
If we were developing locally, you could commit your changes so far and then make a small change to the `products` library.
|
||||
|
||||
```html {% fileName="libs/products/src/lib/product-list/product-list.component.html" %}
|
||||
```html {% fileName="libs/products/src/lib/product-list/product-list.html" %}
|
||||
<p>product-list works!</p>
|
||||
<p>This is a change. 👋</p>
|
||||
```
|
||||
|
||||
@ -2,9 +2,9 @@
|
||||
"name": "orders",
|
||||
"$schema": "../../node_modules/nx/schemas/project-schema.json",
|
||||
"sourceRoot": "libs/orders/src",
|
||||
"prefix": "lib",
|
||||
"projectType": "library",
|
||||
"tags": ["type:feature", "scope:orders"],
|
||||
"// targets": "to see all targets run: nx show project orders --web",
|
||||
"targets": {
|
||||
"test": {
|
||||
"executor": "@nx/jest:jest",
|
||||
|
||||
@ -2,9 +2,9 @@
|
||||
"name": "products",
|
||||
"$schema": "../../node_modules/nx/schemas/project-schema.json",
|
||||
"sourceRoot": "libs/products/src",
|
||||
"prefix": "lib",
|
||||
"projectType": "library",
|
||||
"tags": ["type:feature", "scope:products"],
|
||||
"// targets": "to see all targets run: nx show project products --web",
|
||||
"targets": {
|
||||
"test": {
|
||||
"executor": "@nx/jest:jest",
|
||||
|
||||
@ -1,15 +0,0 @@
|
||||
import styles from './products.module.css';
|
||||
|
||||
// This import is not allowed 👇
|
||||
import { Orders } from '@angular-monorepo/orders';
|
||||
|
||||
export function Products() {
|
||||
return (
|
||||
<div className={styles['container']}>
|
||||
<h1>Welcome to Products!</h1>
|
||||
<p>This is a change. 👋</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Products;
|
||||
@ -0,0 +1,13 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
|
||||
// This import is not allowed 👇
|
||||
import { Orders } from '@angular-monorepo/orders';
|
||||
|
||||
@Component({
|
||||
selector: 'lib-products',
|
||||
imports: [CommonModule],
|
||||
templateUrl: './products.html',
|
||||
styleUrl: './products.css',
|
||||
})
|
||||
export class Products {}
|
||||
@ -2,9 +2,9 @@
|
||||
"name": "ui",
|
||||
"$schema": "../../../node_modules/nx/schemas/project-schema.json",
|
||||
"sourceRoot": "libs/shared/ui/src",
|
||||
"prefix": "lib",
|
||||
"projectType": "library",
|
||||
"tags": ["type:ui", "scope:shared"],
|
||||
"// targets": "to see all targets run: nx show project ui --web",
|
||||
"targets": {
|
||||
"test": {
|
||||
"executor": "@nx/jest:jest",
|
||||
|
||||
@ -53,9 +53,9 @@ To enforce the rules, Nx ships with a custom ESLint rule. Open the `eslint.confi
|
||||
|
||||
```
|
||||
|
||||
To test it, go to your `libs/products/src/lib/products.tsx` file and import the `Orders` component from the `orders` project:
|
||||
To test it, go to your `libs/products/src/lib/products/products.ts` file and import the `Orders` component from the `orders` project:
|
||||
|
||||
```solution:/libs/products/src/lib/products.tsx title="/libs/products/src/lib/products.tsx" {3-4}
|
||||
```solution:/libs/products/src/lib/products/products.ts title="/libs/products/src/lib/products/products.ts" {4-5}
|
||||
|
||||
```
|
||||
|
||||
@ -70,9 +70,9 @@ npx nx run-many -t lint
|
||||
✖ nx run products:lint
|
||||
Linting "products"...
|
||||
|
||||
/Users/isaac/Documents/code/nx-recipes/angular-monorepo/libs/products/src/lib/products.tsx
|
||||
4:1 error A project tagged with "scope:products" can only depend on libs tagged with "scope:products", "scope:shared" @nx/enforce-module-boundaries
|
||||
4:10 warning 'Orders' is defined but never used @typescript-eslint/no-unused-vars
|
||||
/Users/isaac/Documents/code/nx-recipes/angular-monorepo/libs/products/src/lib/products/products.ts
|
||||
5:1 error A project tagged with "scope:products" can only depend on libs tagged with "scope:products", "scope:shared" @nx/enforce-module-boundaries
|
||||
5:10 warning 'Orders' is defined but never used @typescript-eslint/no-unused-vars
|
||||
|
||||
✖ 2 problems (1 error, 1 warning)
|
||||
|
||||
|
||||
@ -7,11 +7,10 @@
|
||||
"tags": [],
|
||||
"targets": {
|
||||
"build": {
|
||||
"executor": "@angular-devkit/build-angular:application",
|
||||
"executor": "@angular/build:application",
|
||||
"outputs": ["{options.outputPath}"],
|
||||
"options": {
|
||||
"outputPath": "dist/apps/angular-store",
|
||||
"index": "apps/angular-store/src/index.html",
|
||||
"browser": "apps/angular-store/src/main.ts",
|
||||
"polyfills": ["zone.js"],
|
||||
"tsConfig": "apps/angular-store/tsconfig.app.json",
|
||||
@ -21,8 +20,7 @@
|
||||
"input": "apps/angular-store/public"
|
||||
}
|
||||
],
|
||||
"styles": ["apps/angular-store/src/styles.css"],
|
||||
"scripts": []
|
||||
"styles": ["apps/angular-store/src/styles.css"]
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
@ -49,7 +47,7 @@
|
||||
"defaultConfiguration": "production"
|
||||
},
|
||||
"serve": {
|
||||
"executor": "@angular-devkit/build-angular:dev-server",
|
||||
"executor": "@angular/build:dev-server",
|
||||
"configurations": {
|
||||
"production": {
|
||||
"buildTarget": "angular-store:build:production"
|
||||
@ -61,7 +59,7 @@
|
||||
"defaultConfiguration": "development"
|
||||
},
|
||||
"extract-i18n": {
|
||||
"executor": "@angular-devkit/build-angular:extract-i18n",
|
||||
"executor": "@angular/build:extract-i18n",
|
||||
"options": {
|
||||
"buildTarget": "angular-store:build"
|
||||
}
|
||||
|
||||
@ -1,27 +0,0 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
import { AppComponent } from './app.component';
|
||||
import { NxWelcomeComponent } from './nx-welcome.component';
|
||||
import { RouterModule } from '@angular/router';
|
||||
|
||||
describe('AppComponent', () => {
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [AppComponent, NxWelcomeComponent, RouterModule.forRoot([])],
|
||||
}).compileComponents();
|
||||
});
|
||||
|
||||
it('should render title', () => {
|
||||
const fixture = TestBed.createComponent(AppComponent);
|
||||
fixture.detectChanges();
|
||||
const compiled = fixture.nativeElement as HTMLElement;
|
||||
expect(compiled.querySelector('h1')?.textContent).toContain(
|
||||
'Welcome angular-store'
|
||||
);
|
||||
});
|
||||
|
||||
it(`should have as title 'angular-store'`, () => {
|
||||
const fixture = TestBed.createComponent(AppComponent);
|
||||
const app = fixture.componentInstance;
|
||||
expect(app.title).toEqual('angular-store');
|
||||
});
|
||||
});
|
||||
@ -1,13 +0,0 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { NxWelcomeComponent } from './nx-welcome.component';
|
||||
|
||||
@Component({
|
||||
imports: [NxWelcomeComponent, RouterModule],
|
||||
selector: 'app-root',
|
||||
templateUrl: './app.component.html',
|
||||
styleUrl: './app.component.css',
|
||||
})
|
||||
export class AppComponent {
|
||||
title = 'angular-store';
|
||||
}
|
||||
@ -1,9 +1,14 @@
|
||||
import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';
|
||||
import {
|
||||
ApplicationConfig,
|
||||
provideBrowserGlobalErrorListeners,
|
||||
provideZoneChangeDetection,
|
||||
} from '@angular/core';
|
||||
import { provideRouter } from '@angular/router';
|
||||
import { appRoutes } from './app.routes';
|
||||
|
||||
export const appConfig: ApplicationConfig = {
|
||||
providers: [
|
||||
provideBrowserGlobalErrorListeners(),
|
||||
provideZoneChangeDetection({ eventCoalescing: true }),
|
||||
provideRouter(appRoutes),
|
||||
],
|
||||
|
||||
@ -0,0 +1,20 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
import { App } from './app';
|
||||
import { NxWelcome } from './nx-welcome';
|
||||
|
||||
describe('App', () => {
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [App, NxWelcome],
|
||||
}).compileComponents();
|
||||
});
|
||||
|
||||
it('should render title', () => {
|
||||
const fixture = TestBed.createComponent(App);
|
||||
fixture.detectChanges();
|
||||
const compiled = fixture.nativeElement as HTMLElement;
|
||||
expect(compiled.querySelector('h1')?.textContent).toContain(
|
||||
'Welcome angular-store'
|
||||
);
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,13 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { NxWelcome } from './nx-welcome';
|
||||
|
||||
@Component({
|
||||
imports: [NxWelcome, RouterModule],
|
||||
selector: 'app-root',
|
||||
templateUrl: './app.html',
|
||||
styleUrl: './app.css',
|
||||
})
|
||||
export class App {
|
||||
protected title = 'angular-store';
|
||||
}
|
||||
@ -773,11 +773,11 @@ import { CommonModule } from '@angular/common';
|
||||
Build, test and lint your app
|
||||
</summary>
|
||||
<pre><span># Build</span>
|
||||
nx build
|
||||
nx build
|
||||
<span># Test</span>
|
||||
nx test
|
||||
nx test
|
||||
<span># Lint</span>
|
||||
nx lint
|
||||
nx lint
|
||||
<span># Run them together!</span>
|
||||
nx run-many -t build test lint</pre>
|
||||
</details>
|
||||
@ -866,4 +866,4 @@ nx g @nx/angular:component ui/src/lib/button</pre>
|
||||
styles: [],
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
})
|
||||
export class NxWelcomeComponent {}
|
||||
export class NxWelcome {}
|
||||
@ -1,7 +1,5 @@
|
||||
import { bootstrapApplication } from '@angular/platform-browser';
|
||||
import { appConfig } from './app/app.config';
|
||||
import { AppComponent } from './app/app.component';
|
||||
import { App } from './app/app';
|
||||
|
||||
bootstrapApplication(AppComponent, appConfig).catch((err) =>
|
||||
console.error(err)
|
||||
);
|
||||
bootstrapApplication(App, appConfig).catch((err) => console.error(err));
|
||||
|
||||
@ -4,7 +4,11 @@
|
||||
"outDir": "../../dist/out-tsc",
|
||||
"types": []
|
||||
},
|
||||
"files": ["src/main.ts"],
|
||||
"include": ["src/**/*.d.ts"],
|
||||
"exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"]
|
||||
"include": ["src/**/*.ts"],
|
||||
"exclude": [
|
||||
"jest.config.ts",
|
||||
"src/test-setup.ts",
|
||||
"src/**/*.test.ts",
|
||||
"src/**/*.spec.ts"
|
||||
]
|
||||
}
|
||||
|
||||
@ -1,6 +0,0 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"include": ["src/**/*.ts"],
|
||||
"compilerOptions": {},
|
||||
"exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"]
|
||||
}
|
||||
@ -1,32 +1,32 @@
|
||||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"target": "es2022",
|
||||
"esModuleInterop": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": true,
|
||||
"noImplicitOverride": true,
|
||||
"noPropertyAccessFromIndexSignature": true,
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": true
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"target": "es2022",
|
||||
"moduleResolution": "bundler",
|
||||
"isolatedModules": true,
|
||||
"emitDecoratorMetadata": false,
|
||||
"module": "preserve"
|
||||
},
|
||||
"angularCompilerOptions": {
|
||||
"enableI18nLegacyMessageIdFormat": false,
|
||||
"strictInjectionParameters": true,
|
||||
"strictInputAccessModifiers": true,
|
||||
"typeCheckHostBindings": true,
|
||||
"strictTemplates": true
|
||||
},
|
||||
"files": [],
|
||||
"include": [],
|
||||
"references": [
|
||||
{
|
||||
"path": "./tsconfig.editor.json"
|
||||
},
|
||||
{
|
||||
"path": "./tsconfig.app.json"
|
||||
},
|
||||
{
|
||||
"path": "./tsconfig.spec.json"
|
||||
}
|
||||
],
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"angularCompilerOptions": {
|
||||
"enableI18nLegacyMessageIdFormat": false,
|
||||
"strictInjectionParameters": true,
|
||||
"strictInputAccessModifiers": true,
|
||||
"strictTemplates": true
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
"compilerOptions": {
|
||||
"outDir": "../../dist/out-tsc",
|
||||
"module": "commonjs",
|
||||
"moduleResolution": "node10",
|
||||
"target": "es2016",
|
||||
"types": ["jest", "node"]
|
||||
},
|
||||
|
||||
@ -19,7 +19,7 @@
|
||||
},
|
||||
"nxCloudId": "6810b7447beee15fcea96208",
|
||||
"targetDefaults": {
|
||||
"@angular-devkit/build-angular:application": {
|
||||
"@angular/build:application": {
|
||||
"cache": true,
|
||||
"dependsOn": ["^build"],
|
||||
"inputs": ["production", "^production"]
|
||||
@ -51,6 +51,15 @@
|
||||
}
|
||||
},
|
||||
"plugins": [
|
||||
{
|
||||
"plugin": "@nx/cypress/plugin",
|
||||
"options": {
|
||||
"targetName": "e2e",
|
||||
"openTargetName": "open-cypress",
|
||||
"componentTestingTargetName": "component-test",
|
||||
"ciTargetName": "e2e-ci"
|
||||
}
|
||||
},
|
||||
{
|
||||
"plugin": "@nx/eslint/plugin",
|
||||
"options": {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -5,54 +5,53 @@
|
||||
"scripts": {},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@angular/common": "~19.2.0",
|
||||
"@angular/compiler": "~19.2.0",
|
||||
"@angular/core": "~19.2.0",
|
||||
"@angular/forms": "~19.2.0",
|
||||
"@angular/platform-browser": "~19.2.0",
|
||||
"@angular/platform-browser-dynamic": "~19.2.0",
|
||||
"@angular/router": "~19.2.0",
|
||||
"@angular/common": "~20.0.0",
|
||||
"@angular/compiler": "~20.0.0",
|
||||
"@angular/core": "~20.0.0",
|
||||
"@angular/forms": "~20.0.0",
|
||||
"@angular/platform-browser": "~20.0.0",
|
||||
"@angular/platform-browser-dynamic": "~20.0.0",
|
||||
"@angular/router": "~20.0.0",
|
||||
"rxjs": "~7.8.0",
|
||||
"zone.js": "~0.15.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular-devkit/build-angular": "~19.2.0",
|
||||
"@angular-devkit/core": "~19.2.0",
|
||||
"@angular-devkit/schematics": "~19.2.0",
|
||||
"@angular/cli": "~19.2.0",
|
||||
"@angular/compiler-cli": "~19.2.0",
|
||||
"@angular/language-service": "~19.2.0",
|
||||
"@angular-devkit/core": "~20.0.0",
|
||||
"@angular-devkit/schematics": "~20.0.0",
|
||||
"@angular/build": "~20.0.0",
|
||||
"@angular/cli": "~20.0.0",
|
||||
"@angular/compiler-cli": "~20.0.0",
|
||||
"@angular/language-service": "~20.0.0",
|
||||
"@eslint/js": "^9.8.0",
|
||||
"@nx/angular": "20.8.1",
|
||||
"@nx/devkit": "20.8.1",
|
||||
"@nx/eslint": "20.8.1",
|
||||
"@nx/eslint-plugin": "20.8.1",
|
||||
"@nx/jest": "20.8.1",
|
||||
"@nx/js": "20.8.1",
|
||||
"@nx/playwright": "20.8.1",
|
||||
"@nx/web": "20.8.1",
|
||||
"@nx/workspace": "20.8.1",
|
||||
"@playwright/test": "^1.36.0",
|
||||
"@schematics/angular": "~19.2.0",
|
||||
"@nx/angular": "21.2.0-beta.1",
|
||||
"@nx/cypress": "21.2.0-beta.1",
|
||||
"@nx/eslint": "21.2.0-beta.1",
|
||||
"@nx/eslint-plugin": "21.2.0-beta.1",
|
||||
"@nx/jest": "21.2.0-beta.1",
|
||||
"@nx/js": "21.2.0-beta.1",
|
||||
"@nx/web": "21.2.0-beta.1",
|
||||
"@nx/workspace": "21.2.0-beta.1",
|
||||
"@schematics/angular": "~20.0.0",
|
||||
"@swc-node/register": "~1.9.1",
|
||||
"@swc/core": "~1.5.7",
|
||||
"@swc/helpers": "~0.5.11",
|
||||
"@types/jest": "^29.5.12",
|
||||
"@types/node": "18.16.9",
|
||||
"@typescript-eslint/utils": "^8.19.0",
|
||||
"angular-eslint": "^19.2.0",
|
||||
"@typescript-eslint/utils": "^8.29.0",
|
||||
"angular-eslint": "^20.0.0-beta.1",
|
||||
"cypress": "^14.2.1",
|
||||
"eslint": "^9.8.0",
|
||||
"eslint-config-prettier": "^10.0.0",
|
||||
"eslint-plugin-playwright": "^1.6.2",
|
||||
"eslint-plugin-cypress": "^3.5.0",
|
||||
"jest": "^29.7.0",
|
||||
"jest-environment-jsdom": "^29.7.0",
|
||||
"jest-preset-angular": "~14.4.0",
|
||||
"nx": "20.8.1",
|
||||
"jest-preset-angular": "~14.6.0",
|
||||
"nx": "21.2.0-beta.1",
|
||||
"prettier": "^2.6.2",
|
||||
"ts-jest": "^29.1.0",
|
||||
"ts-node": "10.9.1",
|
||||
"tslib": "^2.3.0",
|
||||
"typescript": "~5.7.2",
|
||||
"typescript-eslint": "^8.19.0"
|
||||
"typescript": "~5.8.2",
|
||||
"typescript-eslint": "^8.29.0"
|
||||
}
|
||||
}
|
||||
|
||||
@ -50,32 +50,32 @@ Let's name the initial application `angular-store`. In this tutorial we're going
|
||||
├─ ...
|
||||
├─ apps
|
||||
│ ├─ angular-store
|
||||
│ │ ├─ public
|
||||
│ │ │ │ └─ favicon.ico
|
||||
│ │ ├─ src
|
||||
│ │ │ ├─ app
|
||||
│ │ │ │ ├─ app.component.css
|
||||
│ │ │ │ ├─ app.component.html
|
||||
│ │ │ │ ├─ app.component.spec.ts
|
||||
│ │ │ │ ├─ app.component.ts
|
||||
│ │ │ │ ├─ app.config.ts
|
||||
│ │ │ │ ├─ app.css
|
||||
│ │ │ │ ├─ app.html
|
||||
│ │ │ │ ├─ app.routes.ts
|
||||
│ │ │ │ └─ nx-welcome.component.ts
|
||||
│ │ │ ├─ assets
|
||||
│ │ │ │ ├─ app.spec.ts
|
||||
│ │ │ │ ├─ app.ts
|
||||
│ │ │ │ └─ nx-welcome.ts
|
||||
│ │ │ ├─ index.html
|
||||
│ │ │ ├─ main.ts
|
||||
│ │ │ ├─ styles.css
|
||||
│ │ │ └─ test-setup.ts
|
||||
│ │ ├─ eslintrc.json
|
||||
│ │ ├─ eslint.config.mjs
|
||||
│ │ ├─ jest.config.ts
|
||||
│ │ ├─ project.json
|
||||
│ │ ├─ tsconfig.app.json
|
||||
│ │ ├─ tsconfig.editor.json
|
||||
│ │ ├─ tsconfig.json
|
||||
│ │ └─ tsconfig.spec.json
|
||||
│ └─ angular-store-e2e
|
||||
│ └─ ...
|
||||
├─ nx.json
|
||||
├─ tsconfig.base.json
|
||||
└─ package.json
|
||||
├─ package.json
|
||||
└─ tsconfig.base.json
|
||||
```
|
||||
|
||||
The setup includes:
|
||||
|
||||
@ -36,7 +36,7 @@ Each target contains a configuration object that tells Nx how to run that target
|
||||
...
|
||||
"targets": {
|
||||
"serve": {
|
||||
"executor": "@angular-devkit/build-angular:dev-server",
|
||||
"executor": "@angular/build:dev-server",
|
||||
"defaultConfiguration": "development",
|
||||
"options": {
|
||||
"buildTarget": "angular-store:build"
|
||||
|
||||
@ -7,11 +7,10 @@
|
||||
"tags": [],
|
||||
"targets": {
|
||||
"build": {
|
||||
"executor": "@angular-devkit/build-angular:application",
|
||||
"executor": "@angular/build:application",
|
||||
"outputs": ["{options.outputPath}"],
|
||||
"options": {
|
||||
"outputPath": "dist/apps/inventory",
|
||||
"index": "apps/inventory/src/index.html",
|
||||
"browser": "apps/inventory/src/main.ts",
|
||||
"polyfills": ["zone.js"],
|
||||
"tsConfig": "apps/inventory/tsconfig.app.json",
|
||||
@ -21,8 +20,7 @@
|
||||
"input": "apps/inventory/public"
|
||||
}
|
||||
],
|
||||
"styles": ["apps/inventory/src/styles.css"],
|
||||
"scripts": []
|
||||
"styles": ["apps/inventory/src/styles.css"]
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
@ -49,7 +47,7 @@
|
||||
"defaultConfiguration": "production"
|
||||
},
|
||||
"serve": {
|
||||
"executor": "@angular-devkit/build-angular:dev-server",
|
||||
"executor": "@angular/build:dev-server",
|
||||
"configurations": {
|
||||
"production": {
|
||||
"buildTarget": "inventory:build:production"
|
||||
@ -61,7 +59,7 @@
|
||||
"defaultConfiguration": "development"
|
||||
},
|
||||
"extract-i18n": {
|
||||
"executor": "@angular-devkit/build-angular:extract-i18n",
|
||||
"executor": "@angular/build:extract-i18n",
|
||||
"options": {
|
||||
"buildTarget": "inventory:build"
|
||||
}
|
||||
|
||||
@ -1,27 +0,0 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
import { AppComponent } from './app.component';
|
||||
import { NxWelcomeComponent } from './nx-welcome.component';
|
||||
import { RouterModule } from '@angular/router';
|
||||
|
||||
describe('AppComponent', () => {
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [AppComponent, NxWelcomeComponent, RouterModule.forRoot([])],
|
||||
}).compileComponents();
|
||||
});
|
||||
|
||||
it('should render title', () => {
|
||||
const fixture = TestBed.createComponent(AppComponent);
|
||||
fixture.detectChanges();
|
||||
const compiled = fixture.nativeElement as HTMLElement;
|
||||
expect(compiled.querySelector('h1')?.textContent).toContain(
|
||||
'Welcome inventory'
|
||||
);
|
||||
});
|
||||
|
||||
it(`should have as title 'inventory'`, () => {
|
||||
const fixture = TestBed.createComponent(AppComponent);
|
||||
const app = fixture.componentInstance;
|
||||
expect(app.title).toEqual('inventory');
|
||||
});
|
||||
});
|
||||
@ -1,13 +0,0 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { NxWelcomeComponent } from './nx-welcome.component';
|
||||
|
||||
@Component({
|
||||
imports: [NxWelcomeComponent, RouterModule],
|
||||
selector: 'app-root',
|
||||
templateUrl: './app.component.html',
|
||||
styleUrl: './app.component.css',
|
||||
})
|
||||
export class AppComponent {
|
||||
title = 'inventory';
|
||||
}
|
||||
@ -1,9 +1,14 @@
|
||||
import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';
|
||||
import {
|
||||
ApplicationConfig,
|
||||
provideBrowserGlobalErrorListeners,
|
||||
provideZoneChangeDetection,
|
||||
} from '@angular/core';
|
||||
import { provideRouter } from '@angular/router';
|
||||
import { appRoutes } from './app.routes';
|
||||
|
||||
export const appConfig: ApplicationConfig = {
|
||||
providers: [
|
||||
provideBrowserGlobalErrorListeners(),
|
||||
provideZoneChangeDetection({ eventCoalescing: true }),
|
||||
provideRouter(appRoutes),
|
||||
],
|
||||
|
||||
@ -0,0 +1,20 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
import { App } from './app';
|
||||
import { NxWelcome } from './nx-welcome';
|
||||
|
||||
describe('App', () => {
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [App, NxWelcome],
|
||||
}).compileComponents();
|
||||
});
|
||||
|
||||
it('should render title', () => {
|
||||
const fixture = TestBed.createComponent(App);
|
||||
fixture.detectChanges();
|
||||
const compiled = fixture.nativeElement as HTMLElement;
|
||||
expect(compiled.querySelector('h1')?.textContent).toContain(
|
||||
'Welcome inventory'
|
||||
);
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,13 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { NxWelcome } from './nx-welcome';
|
||||
|
||||
@Component({
|
||||
imports: [NxWelcome, RouterModule],
|
||||
selector: 'app-root',
|
||||
templateUrl: './app.html',
|
||||
styleUrl: './app.css',
|
||||
})
|
||||
export class App {
|
||||
protected title = 'inventory';
|
||||
}
|
||||
@ -862,4 +862,4 @@ nx g @nx/angular:component ui/src/lib/button</pre>
|
||||
styles: [],
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
})
|
||||
export class NxWelcomeComponent {}
|
||||
export class NxWelcome {}
|
||||
@ -1,7 +1,5 @@
|
||||
import { bootstrapApplication } from '@angular/platform-browser';
|
||||
import { appConfig } from './app/app.config';
|
||||
import { AppComponent } from './app/app.component';
|
||||
import { App } from './app/app';
|
||||
|
||||
bootstrapApplication(AppComponent, appConfig).catch((err) =>
|
||||
console.error(err)
|
||||
);
|
||||
bootstrapApplication(App, appConfig).catch((err) => console.error(err));
|
||||
|
||||
@ -4,7 +4,11 @@
|
||||
"outDir": "../../dist/out-tsc",
|
||||
"types": []
|
||||
},
|
||||
"files": ["src/main.ts"],
|
||||
"include": ["src/**/*.d.ts"],
|
||||
"exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"]
|
||||
"include": ["src/**/*.ts"],
|
||||
"exclude": [
|
||||
"jest.config.ts",
|
||||
"src/test-setup.ts",
|
||||
"src/**/*.test.ts",
|
||||
"src/**/*.spec.ts"
|
||||
]
|
||||
}
|
||||
|
||||
@ -1,6 +0,0 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"include": ["src/**/*.ts"],
|
||||
"compilerOptions": {},
|
||||
"exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"]
|
||||
}
|
||||
@ -1,32 +1,32 @@
|
||||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"target": "es2022",
|
||||
"esModuleInterop": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": true,
|
||||
"noImplicitOverride": true,
|
||||
"noPropertyAccessFromIndexSignature": true,
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": true
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"target": "es2022",
|
||||
"moduleResolution": "bundler",
|
||||
"isolatedModules": true,
|
||||
"emitDecoratorMetadata": false,
|
||||
"module": "preserve"
|
||||
},
|
||||
"angularCompilerOptions": {
|
||||
"enableI18nLegacyMessageIdFormat": false,
|
||||
"strictInjectionParameters": true,
|
||||
"strictInputAccessModifiers": true,
|
||||
"typeCheckHostBindings": true,
|
||||
"strictTemplates": true
|
||||
},
|
||||
"files": [],
|
||||
"include": [],
|
||||
"references": [
|
||||
{
|
||||
"path": "./tsconfig.editor.json"
|
||||
},
|
||||
{
|
||||
"path": "./tsconfig.app.json"
|
||||
},
|
||||
{
|
||||
"path": "./tsconfig.spec.json"
|
||||
}
|
||||
],
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"angularCompilerOptions": {
|
||||
"enableI18nLegacyMessageIdFormat": false,
|
||||
"strictInjectionParameters": true,
|
||||
"strictInputAccessModifiers": true,
|
||||
"strictTemplates": true
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
"compilerOptions": {
|
||||
"outDir": "../../dist/out-tsc",
|
||||
"module": "commonjs",
|
||||
"moduleResolution": "node10",
|
||||
"target": "es2016",
|
||||
"types": ["jest", "node"]
|
||||
},
|
||||
|
||||
@ -1 +1 @@
|
||||
export * from './lib/orders/orders.component';
|
||||
export * from './lib/orders/orders';
|
||||
|
||||
@ -1,16 +1,16 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { UiComponent } from './ui.component';
|
||||
import { Orders } from './orders';
|
||||
|
||||
describe('UiComponent', () => {
|
||||
let component: UiComponent;
|
||||
let fixture: ComponentFixture<UiComponent>;
|
||||
describe('Orders', () => {
|
||||
let component: Orders;
|
||||
let fixture: ComponentFixture<Orders>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [UiComponent],
|
||||
imports: [Orders],
|
||||
}).compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(UiComponent);
|
||||
fixture = TestBed.createComponent(Orders);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
@ -4,7 +4,7 @@ import { CommonModule } from '@angular/common';
|
||||
@Component({
|
||||
selector: 'lib-orders',
|
||||
imports: [CommonModule],
|
||||
templateUrl: './orders.component.html',
|
||||
styleUrl: './orders.component.css',
|
||||
templateUrl: './orders.html',
|
||||
styleUrl: './orders.css',
|
||||
})
|
||||
export class OrdersComponent {}
|
||||
export class Orders {}
|
||||
@ -1,12 +1,21 @@
|
||||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"target": "es2022",
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": true,
|
||||
"noImplicitOverride": true,
|
||||
"noPropertyAccessFromIndexSignature": true,
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": true
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"module": "preserve",
|
||||
"moduleResolution": "bundler"
|
||||
},
|
||||
"angularCompilerOptions": {
|
||||
"enableI18nLegacyMessageIdFormat": false,
|
||||
"strictInjectionParameters": true,
|
||||
"strictInputAccessModifiers": true,
|
||||
"typeCheckHostBindings": true,
|
||||
"strictTemplates": true
|
||||
},
|
||||
"files": [],
|
||||
"include": [],
|
||||
@ -17,12 +26,5 @@
|
||||
{
|
||||
"path": "./tsconfig.spec.json"
|
||||
}
|
||||
],
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"angularCompilerOptions": {
|
||||
"enableI18nLegacyMessageIdFormat": false,
|
||||
"strictInjectionParameters": true,
|
||||
"strictInputAccessModifiers": true,
|
||||
"strictTemplates": true
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
"compilerOptions": {
|
||||
"outDir": "../../dist/out-tsc",
|
||||
"module": "commonjs",
|
||||
"moduleResolution": "node10",
|
||||
"target": "es2016",
|
||||
"types": ["jest", "node"]
|
||||
},
|
||||
|
||||
@ -1 +1 @@
|
||||
export * from './lib/products/products.component';
|
||||
export * from './lib/products/products';
|
||||
|
||||
@ -1,21 +0,0 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { ProductsComponent } from './products.component';
|
||||
|
||||
describe('ProductsComponent', () => {
|
||||
let component: ProductsComponent;
|
||||
let fixture: ComponentFixture<ProductsComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [ProductsComponent],
|
||||
}).compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(ProductsComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@ -1,16 +1,16 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { UiComponent } from './ui.component';
|
||||
import { Products } from './products';
|
||||
|
||||
describe('UiComponent', () => {
|
||||
let component: UiComponent;
|
||||
let fixture: ComponentFixture<UiComponent>;
|
||||
describe('Products', () => {
|
||||
let component: Products;
|
||||
let fixture: ComponentFixture<Products>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [UiComponent],
|
||||
imports: [Products],
|
||||
}).compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(UiComponent);
|
||||
fixture = TestBed.createComponent(Products);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
@ -4,7 +4,7 @@ import { CommonModule } from '@angular/common';
|
||||
@Component({
|
||||
selector: 'lib-products',
|
||||
imports: [CommonModule],
|
||||
templateUrl: './products.component.html',
|
||||
styleUrl: './products.component.css',
|
||||
templateUrl: './products.html',
|
||||
styleUrl: './products.css',
|
||||
})
|
||||
export class ProductsComponent {}
|
||||
export class Products {}
|
||||
@ -1,12 +1,21 @@
|
||||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"target": "es2022",
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": true,
|
||||
"noImplicitOverride": true,
|
||||
"noPropertyAccessFromIndexSignature": true,
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": true
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"module": "preserve",
|
||||
"moduleResolution": "bundler"
|
||||
},
|
||||
"angularCompilerOptions": {
|
||||
"enableI18nLegacyMessageIdFormat": false,
|
||||
"strictInjectionParameters": true,
|
||||
"strictInputAccessModifiers": true,
|
||||
"typeCheckHostBindings": true,
|
||||
"strictTemplates": true
|
||||
},
|
||||
"files": [],
|
||||
"include": [],
|
||||
@ -17,12 +26,5 @@
|
||||
{
|
||||
"path": "./tsconfig.spec.json"
|
||||
}
|
||||
],
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"angularCompilerOptions": {
|
||||
"enableI18nLegacyMessageIdFormat": false,
|
||||
"strictInjectionParameters": true,
|
||||
"strictInputAccessModifiers": true,
|
||||
"strictTemplates": true
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
"compilerOptions": {
|
||||
"outDir": "../../dist/out-tsc",
|
||||
"module": "commonjs",
|
||||
"moduleResolution": "node10",
|
||||
"target": "es2016",
|
||||
"types": ["jest", "node"]
|
||||
},
|
||||
|
||||
@ -1 +1 @@
|
||||
export * from './lib/ui/ui.component';
|
||||
export * from './lib/ui/ui';
|
||||
|
||||
@ -1,16 +1,16 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { OrdersComponent } from './orders.component';
|
||||
import { Ui } from './ui';
|
||||
|
||||
describe('OrdersComponent', () => {
|
||||
let component: OrdersComponent;
|
||||
let fixture: ComponentFixture<OrdersComponent>;
|
||||
describe('Ui', () => {
|
||||
let component: Ui;
|
||||
let fixture: ComponentFixture<Ui>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [OrdersComponent],
|
||||
imports: [Ui],
|
||||
}).compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(OrdersComponent);
|
||||
fixture = TestBed.createComponent(Ui);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
@ -4,7 +4,7 @@ import { CommonModule } from '@angular/common';
|
||||
@Component({
|
||||
selector: 'lib-ui',
|
||||
imports: [CommonModule],
|
||||
templateUrl: './ui.component.html',
|
||||
styleUrl: './ui.component.css',
|
||||
templateUrl: './ui.html',
|
||||
styleUrl: './ui.css',
|
||||
})
|
||||
export class UiComponent {}
|
||||
export class Ui {}
|
||||
@ -1,12 +1,21 @@
|
||||
{
|
||||
"extends": "../../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"target": "es2022",
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": true,
|
||||
"noImplicitOverride": true,
|
||||
"noPropertyAccessFromIndexSignature": true,
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": true
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"module": "preserve",
|
||||
"moduleResolution": "bundler"
|
||||
},
|
||||
"angularCompilerOptions": {
|
||||
"enableI18nLegacyMessageIdFormat": false,
|
||||
"strictInjectionParameters": true,
|
||||
"strictInputAccessModifiers": true,
|
||||
"typeCheckHostBindings": true,
|
||||
"strictTemplates": true
|
||||
},
|
||||
"files": [],
|
||||
"include": [],
|
||||
@ -17,12 +26,5 @@
|
||||
{
|
||||
"path": "./tsconfig.spec.json"
|
||||
}
|
||||
],
|
||||
"extends": "../../../tsconfig.base.json",
|
||||
"angularCompilerOptions": {
|
||||
"enableI18nLegacyMessageIdFormat": false,
|
||||
"strictInjectionParameters": true,
|
||||
"strictInputAccessModifiers": true,
|
||||
"strictTemplates": true
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
"compilerOptions": {
|
||||
"outDir": "../../../dist/out-tsc",
|
||||
"module": "commonjs",
|
||||
"moduleResolution": "node10",
|
||||
"target": "es2016",
|
||||
"types": ["jest", "node"]
|
||||
},
|
||||
|
||||
@ -19,7 +19,7 @@
|
||||
},
|
||||
"nxCloudId": "67b34f1b5f0dc34dcae257e2",
|
||||
"targetDefaults": {
|
||||
"@angular-devkit/build-angular:application": {
|
||||
"@angular/build:application": {
|
||||
"cache": true,
|
||||
"dependsOn": ["^build"],
|
||||
"inputs": ["production", "^production"]
|
||||
|
||||
@ -1,20 +1,20 @@
|
||||
import { Route } from '@angular/router';
|
||||
import { NxWelcomeComponent } from './nx-welcome.component';
|
||||
import { NxWelcome } from './nx-welcome';
|
||||
|
||||
export const appRoutes: Route[] = [
|
||||
{
|
||||
path: '',
|
||||
component: NxWelcomeComponent,
|
||||
component: NxWelcome,
|
||||
pathMatch: 'full',
|
||||
},
|
||||
{
|
||||
path: 'products',
|
||||
loadComponent: () =>
|
||||
import('@angular-monorepo/products').then((m) => m.ProductsComponent),
|
||||
import('@angular-monorepo/products').then((m) => m.Products),
|
||||
},
|
||||
{
|
||||
path: 'orders',
|
||||
loadComponent: () =>
|
||||
import('@angular-monorepo/orders').then((m) => m.OrdersComponent),
|
||||
import('@angular-monorepo/orders').then((m) => m.Orders),
|
||||
},
|
||||
];
|
||||
|
||||
@ -4,9 +4,9 @@ import { RouterModule } from '@angular/router';
|
||||
@Component({
|
||||
imports: [RouterModule],
|
||||
selector: 'app-root',
|
||||
templateUrl: './app.component.html',
|
||||
styleUrl: './app.component.css',
|
||||
templateUrl: './app.html',
|
||||
styleUrl: './app.css',
|
||||
})
|
||||
export class AppComponent {
|
||||
title = 'angular-store';
|
||||
export class App {
|
||||
protected title = 'angular-store';
|
||||
}
|
||||
@ -1,12 +0,0 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { ProductsComponent } from '@angular-monorepo/products';
|
||||
|
||||
@Component({
|
||||
imports: [ProductsComponent],
|
||||
selector: 'app-root',
|
||||
templateUrl: './app.component.html',
|
||||
styleUrl: './app.component.css',
|
||||
})
|
||||
export class AppComponent {
|
||||
title = 'inventory';
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { Products } from '@angular-monorepo/products';
|
||||
|
||||
@Component({
|
||||
imports: [Products],
|
||||
selector: 'app-root',
|
||||
templateUrl: './app.html',
|
||||
styleUrl: './app.css',
|
||||
})
|
||||
export class App {
|
||||
protected title = 'inventory';
|
||||
}
|
||||
@ -21,21 +21,21 @@ All libraries that we generate automatically have aliases created in the root-le
|
||||
}
|
||||
```
|
||||
|
||||
Hence we can easily import them into other libraries and our Angular application. As an example, let's use the pre-generated `ProductsComponent` component from our `libs/products` library.
|
||||
Hence we can easily import them into other libraries and our Angular application. As an example, let's use the pre-generated `Products` component from our `libs/products` library.
|
||||
|
||||
You can see that the `ProductsComponent` is exported via the `index.ts` file of our `products` library so that other projects in the repository can use it. This is our public API with the rest of the workspace. Only export what's really necessary to be usable outside the library itself.
|
||||
You can see that the `Products` is exported via the `index.ts` file of our `products` library so that other projects in the repository can use it. This is our public API with the rest of the workspace. Only export what's really necessary to be usable outside the library itself.
|
||||
|
||||
```ts title="/libs/products/src/index.ts"
|
||||
export * from './lib/products/products.component';
|
||||
export * from './lib/products/products';
|
||||
```
|
||||
|
||||
We're ready to import it into our main application now. First (if you haven't already), let's set up the Angular router. Remove the `app-nx-welcome` component from `app.component.html`:
|
||||
We're ready to import it into our main application now. First (if you haven't already), let's set up the Angular router. Remove the `app-nx-welcome` component from `app.html`:
|
||||
|
||||
```solution:/apps/angular-store/src/app/app.component.html title="/apps/angular-store/src/app/app.component.html"
|
||||
```solution:/apps/angular-store/src/app/app.html title="/apps/angular-store/src/app/app.html"
|
||||
|
||||
```
|
||||
|
||||
Then we can add the `ProductsComponent` component to our `app.routes.ts` and render it via the routing mechanism whenever a user hits the `/products` route.
|
||||
Then we can add the `Products` component to our `app.routes.ts` and render it via the routing mechanism whenever a user hits the `/products` route.
|
||||
|
||||
```solution:/apps/angular-store/src/app/app.routes.ts title="/apps/angular-store/src/app/app.routes.ts" {10-14} collapse={15-19}
|
||||
|
||||
@ -45,7 +45,7 @@ Serving your app (`npx nx serve angular-store`) and then navigating to `/product
|
||||
|
||||

|
||||
|
||||
Let's apply the same for our `orders` library. Import the `OrdersComponent` from `libs/orders` into the `app.routes.ts` and render it via the routing mechanism whenever a user hits the `/orders` route
|
||||
Let's apply the same for our `orders` library. Import the `Orders` from `libs/orders` into the `app.routes.ts` and render it via the routing mechanism whenever a user hits the `/orders` route
|
||||
|
||||
In the end, your `app.routes.ts` should look similar to this:
|
||||
|
||||
@ -55,11 +55,11 @@ In the end, your `app.routes.ts` should look similar to this:
|
||||
|
||||
Let's also show products in the `inventory` app.
|
||||
|
||||
```solution:/apps/inventory/src/app/app.component.ts title="/apps/inventory/src/app/app.component.ts" {2,5}
|
||||
```solution:/apps/inventory/src/app/app.ts title="/apps/inventory/src/app/app.ts" {2,5}
|
||||
|
||||
```
|
||||
|
||||
```solution:/apps/inventory/src/app/app.component.html title="/apps/inventory/src/app/app.component.html"
|
||||
```solution:/apps/inventory/src/app/app.html title="/apps/inventory/src/app/app.html"
|
||||
|
||||
```
|
||||
|
||||
|
||||
@ -2,8 +2,19 @@
|
||||
"name": "orders",
|
||||
"$schema": "../../node_modules/nx/schemas/project-schema.json",
|
||||
"sourceRoot": "libs/orders/src",
|
||||
"prefix": "lib",
|
||||
"projectType": "library",
|
||||
"tags": ["type:feature", "scope:orders"],
|
||||
"// targets": "to see all targets run: nx show project orders --web",
|
||||
"targets": {}
|
||||
"targets": {
|
||||
"test": {
|
||||
"executor": "@nx/jest:jest",
|
||||
"outputs": ["{workspaceRoot}/coverage/{projectRoot}"],
|
||||
"options": {
|
||||
"jestConfig": "libs/orders/jest.config.ts"
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"executor": "@nx/eslint:lint"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,8 +2,19 @@
|
||||
"name": "products",
|
||||
"$schema": "../../node_modules/nx/schemas/project-schema.json",
|
||||
"sourceRoot": "libs/products/src",
|
||||
"prefix": "lib",
|
||||
"projectType": "library",
|
||||
"tags": ["type:feature", "scope:products"],
|
||||
"// targets": "to see all targets run: nx show project products --web",
|
||||
"targets": {}
|
||||
"targets": {
|
||||
"test": {
|
||||
"executor": "@nx/jest:jest",
|
||||
"outputs": ["{workspaceRoot}/coverage/{projectRoot}"],
|
||||
"options": {
|
||||
"jestConfig": "libs/products/jest.config.ts"
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"executor": "@nx/eslint:lint"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,8 +2,19 @@
|
||||
"name": "ui",
|
||||
"$schema": "../../../node_modules/nx/schemas/project-schema.json",
|
||||
"sourceRoot": "libs/shared/ui/src",
|
||||
"prefix": "lib",
|
||||
"projectType": "library",
|
||||
"tags": ["type:ui", "scope:shared"],
|
||||
"// targets": "to see all targets run: nx show project ui --web",
|
||||
"targets": {}
|
||||
"targets": {
|
||||
"test": {
|
||||
"executor": "@nx/jest:jest",
|
||||
"outputs": ["{workspaceRoot}/coverage/{projectRoot}"],
|
||||
"options": {
|
||||
"jestConfig": "libs/shared/ui/jest.config.ts"
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"executor": "@nx/eslint:lint"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,11 +7,10 @@
|
||||
"tags": [],
|
||||
"targets": {
|
||||
"build": {
|
||||
"executor": "@angular-devkit/build-angular:application",
|
||||
"executor": "@angular/build:application",
|
||||
"outputs": ["{options.outputPath}"],
|
||||
"options": {
|
||||
"outputPath": "dist/apps/angular-store",
|
||||
"index": "apps/angular-store/src/index.html",
|
||||
"browser": "apps/angular-store/src/main.ts",
|
||||
"polyfills": ["zone.js"],
|
||||
"tsConfig": "apps/angular-store/tsconfig.app.json",
|
||||
@ -21,8 +20,7 @@
|
||||
"input": "apps/angular-store/public"
|
||||
}
|
||||
],
|
||||
"styles": ["apps/angular-store/src/styles.css"],
|
||||
"scripts": []
|
||||
"styles": ["apps/angular-store/src/styles.css"]
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
@ -49,7 +47,7 @@
|
||||
"defaultConfiguration": "production"
|
||||
},
|
||||
"serve": {
|
||||
"executor": "@angular-devkit/build-angular:dev-server",
|
||||
"executor": "@angular/build:dev-server",
|
||||
"configurations": {
|
||||
"production": {
|
||||
"buildTarget": "angular-store:build:production"
|
||||
@ -61,7 +59,7 @@
|
||||
"defaultConfiguration": "development"
|
||||
},
|
||||
"extract-i18n": {
|
||||
"executor": "@angular-devkit/build-angular:extract-i18n",
|
||||
"executor": "@angular/build:extract-i18n",
|
||||
"options": {
|
||||
"buildTarget": "angular-store:build"
|
||||
}
|
||||
|
||||
@ -1,27 +0,0 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
import { AppComponent } from './app.component';
|
||||
import { NxWelcomeComponent } from './nx-welcome.component';
|
||||
import { RouterModule } from '@angular/router';
|
||||
|
||||
describe('AppComponent', () => {
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [AppComponent, NxWelcomeComponent, RouterModule.forRoot([])],
|
||||
}).compileComponents();
|
||||
});
|
||||
|
||||
it('should render title', () => {
|
||||
const fixture = TestBed.createComponent(AppComponent);
|
||||
fixture.detectChanges();
|
||||
const compiled = fixture.nativeElement as HTMLElement;
|
||||
expect(compiled.querySelector('h1')?.textContent).toContain(
|
||||
'Welcome angular-store'
|
||||
);
|
||||
});
|
||||
|
||||
it(`should have as title 'angular-store'`, () => {
|
||||
const fixture = TestBed.createComponent(AppComponent);
|
||||
const app = fixture.componentInstance;
|
||||
expect(app.title).toEqual('angular-store');
|
||||
});
|
||||
});
|
||||
@ -1,13 +0,0 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { NxWelcomeComponent } from './nx-welcome.component';
|
||||
|
||||
@Component({
|
||||
imports: [NxWelcomeComponent, RouterModule],
|
||||
selector: 'app-root',
|
||||
templateUrl: './app.component.html',
|
||||
styleUrl: './app.component.css',
|
||||
})
|
||||
export class AppComponent {
|
||||
title = 'angular-store';
|
||||
}
|
||||
@ -1,9 +1,14 @@
|
||||
import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';
|
||||
import {
|
||||
ApplicationConfig,
|
||||
provideBrowserGlobalErrorListeners,
|
||||
provideZoneChangeDetection,
|
||||
} from '@angular/core';
|
||||
import { provideRouter } from '@angular/router';
|
||||
import { appRoutes } from './app.routes';
|
||||
|
||||
export const appConfig: ApplicationConfig = {
|
||||
providers: [
|
||||
provideBrowserGlobalErrorListeners(),
|
||||
provideZoneChangeDetection({ eventCoalescing: true }),
|
||||
provideRouter(appRoutes),
|
||||
],
|
||||
|
||||
@ -0,0 +1,20 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
import { App } from './app';
|
||||
import { NxWelcome } from './nx-welcome';
|
||||
|
||||
describe('App', () => {
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [App, NxWelcome],
|
||||
}).compileComponents();
|
||||
});
|
||||
|
||||
it('should render title', () => {
|
||||
const fixture = TestBed.createComponent(App);
|
||||
fixture.detectChanges();
|
||||
const compiled = fixture.nativeElement as HTMLElement;
|
||||
expect(compiled.querySelector('h1')?.textContent).toContain(
|
||||
'Welcome angular-store'
|
||||
);
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,13 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { NxWelcome } from './nx-welcome';
|
||||
|
||||
@Component({
|
||||
imports: [NxWelcome, RouterModule],
|
||||
selector: 'app-root',
|
||||
templateUrl: './app.html',
|
||||
styleUrl: './app.css',
|
||||
})
|
||||
export class App {
|
||||
protected title = 'angular-store';
|
||||
}
|
||||
@ -773,11 +773,11 @@ import { CommonModule } from '@angular/common';
|
||||
Build, test and lint your app
|
||||
</summary>
|
||||
<pre><span># Build</span>
|
||||
nx build
|
||||
nx build
|
||||
<span># Test</span>
|
||||
nx test
|
||||
nx test
|
||||
<span># Lint</span>
|
||||
nx lint
|
||||
nx lint
|
||||
<span># Run them together!</span>
|
||||
nx run-many -t build test lint</pre>
|
||||
</details>
|
||||
@ -866,4 +866,4 @@ nx g @nx/angular:component ui/src/lib/button</pre>
|
||||
styles: [],
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
})
|
||||
export class NxWelcomeComponent {}
|
||||
export class NxWelcome {}
|
||||
@ -1,7 +1,5 @@
|
||||
import { bootstrapApplication } from '@angular/platform-browser';
|
||||
import { appConfig } from './app/app.config';
|
||||
import { AppComponent } from './app/app.component';
|
||||
import { App } from './app/app';
|
||||
|
||||
bootstrapApplication(AppComponent, appConfig).catch((err) =>
|
||||
console.error(err)
|
||||
);
|
||||
bootstrapApplication(App, appConfig).catch((err) => console.error(err));
|
||||
|
||||
@ -4,7 +4,11 @@
|
||||
"outDir": "../../dist/out-tsc",
|
||||
"types": []
|
||||
},
|
||||
"files": ["src/main.ts"],
|
||||
"include": ["src/**/*.d.ts"],
|
||||
"exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"]
|
||||
"include": ["src/**/*.ts"],
|
||||
"exclude": [
|
||||
"jest.config.ts",
|
||||
"src/test-setup.ts",
|
||||
"src/**/*.test.ts",
|
||||
"src/**/*.spec.ts"
|
||||
]
|
||||
}
|
||||
|
||||
@ -1,6 +0,0 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"include": ["src/**/*.ts"],
|
||||
"compilerOptions": {},
|
||||
"exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"]
|
||||
}
|
||||
@ -1,32 +1,32 @@
|
||||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"target": "es2022",
|
||||
"esModuleInterop": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": true,
|
||||
"noImplicitOverride": true,
|
||||
"noPropertyAccessFromIndexSignature": true,
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": true
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"target": "es2022",
|
||||
"moduleResolution": "bundler",
|
||||
"isolatedModules": true,
|
||||
"emitDecoratorMetadata": false,
|
||||
"module": "preserve"
|
||||
},
|
||||
"angularCompilerOptions": {
|
||||
"enableI18nLegacyMessageIdFormat": false,
|
||||
"strictInjectionParameters": true,
|
||||
"strictInputAccessModifiers": true,
|
||||
"typeCheckHostBindings": true,
|
||||
"strictTemplates": true
|
||||
},
|
||||
"files": [],
|
||||
"include": [],
|
||||
"references": [
|
||||
{
|
||||
"path": "./tsconfig.editor.json"
|
||||
},
|
||||
{
|
||||
"path": "./tsconfig.app.json"
|
||||
},
|
||||
{
|
||||
"path": "./tsconfig.spec.json"
|
||||
}
|
||||
],
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"angularCompilerOptions": {
|
||||
"enableI18nLegacyMessageIdFormat": false,
|
||||
"strictInjectionParameters": true,
|
||||
"strictInputAccessModifiers": true,
|
||||
"strictTemplates": true
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
"compilerOptions": {
|
||||
"outDir": "../../dist/out-tsc",
|
||||
"module": "commonjs",
|
||||
"moduleResolution": "node10",
|
||||
"target": "es2016",
|
||||
"types": ["jest", "node"]
|
||||
},
|
||||
|
||||
@ -19,7 +19,7 @@
|
||||
},
|
||||
"nxCloudId": "6810b7447beee15fcea96208",
|
||||
"targetDefaults": {
|
||||
"@angular-devkit/build-angular:application": {
|
||||
"@angular/build:application": {
|
||||
"cache": true,
|
||||
"dependsOn": ["^build"],
|
||||
"inputs": ["production", "^production"]
|
||||
@ -51,6 +51,15 @@
|
||||
}
|
||||
},
|
||||
"plugins": [
|
||||
{
|
||||
"plugin": "@nx/cypress/plugin",
|
||||
"options": {
|
||||
"targetName": "e2e",
|
||||
"openTargetName": "open-cypress",
|
||||
"componentTestingTargetName": "component-test",
|
||||
"ciTargetName": "e2e-ci"
|
||||
}
|
||||
},
|
||||
{
|
||||
"plugin": "@nx/eslint/plugin",
|
||||
"options": {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user