Convert your .NET Core with Angular SPA app to an NX environment - Quick Guide

dkreider

Daniel Kreider

Posted on October 31, 2020

Convert your .NET Core with Angular SPA app to an NX environment - Quick Guide

Interested in joining the big guys by adding NX to your .NET Core Angular App?

Here's a complete step-by-step guide that will show you exactly how to integrate .NET Core, Angular and NX (Nrwl Extensions)

Say.

With the growing power and fame of the .NET Core framework and Angular some awesome possibilities are blooming.

One of these is .NET Core's support for Angular.

Just take the .NET Core CLI and the only thing you gotta bang into that keyboard is...

dotnet new angular -o MyNextAwesomeApp

...and BOOM! It generates a simple .NET Core API server as well as an Angular SPA with amazing server-side rendering, auth options, and more.

Hot stuff if you want to know my opinion.

But what if we want to do better? And use NX to manage our Angular app(s)?

I mean, why not? All the other big guys like...

  • American Airlines
  • Microsoft
  • RedHat
  • FedEx
  • Cisco
  • Audi

...and all kinds of other cool kids are using it.

So how do we install and use NX with a .NET Core Angular SPA app?

Pre-requisites

An ASP.Net Core project with Angular SPA.

Install NX

Assuming that the ASP.NET Core Angular app has already been created the next step is to verify our Angular version.

  • Open your project in a terminal and cd into the ClientApp directory.
  • Type ng --version to check your global Angular version.

With NX you must install the NX version that matches the major version of your global Angular CLI. So head over to package repository and find the version you want. Then type the following command.

  • ng add @nrwl/package@cli.version.number

Fix the imports

The installer tries it's best to update your angular.json file but I found that it really messed my config up so I had to do some manual editing.

Basically all you should need to do is update the broken imports.

Here's a fixed angular.json example.

{
  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
  "version": 1,
  "newProjectRoot": "projects",
  "projects": {
    "MyAwesomeProject": {
      "root": "apps/MyAwesomeProject",
      "sourceRoot": "apps/MyAwesomeProject/src",
      "projectType": "application",
      "prefix": "app",
      "schematics": {},
      "architect": {
        "build": {
          "builder": "@angular-devkit/build-angular:browser",
          "options": {
            "progress": false,
            "extractCss": true,
            "outputPath": "dist",
            "index": "apps/MyAwesomeProject/src/index.html",
            "main": "apps/MyAwesomeProject/src/main.ts",
            "polyfills": "apps/MyAwesomeProject/src/polyfills.ts",
            "tsConfig": "apps/MyAwesomeProject/tsconfig.app.json",
            "assets": ["apps/MyAwesomeProject/src/assets"],
            "styles": [],
            "scripts": []
          },
          "configurations": {
            "production": {
              "fileReplacements": [
                {
                  "replace": "apps/MyAwesomeProject/src/environments/environment.ts",
                  "with": "apps/MyAwesomeProject/src/environments/environment.prod.ts"
                }
              ],
              "optimization": true,
              "outputHashing": "all",
              "sourceMap": false,
              "extractCss": true,
              "namedChunks": false,
              "aot": true,
              "extractLicenses": true,
              "vendorChunk": false,
              "buildOptimizer": true
            }
          }
        },
        "serve": {
          "builder": "@angular-devkit/build-angular:dev-server",
          "options": {
            "browserTarget": "MyAwesomeProject:build"
          },
          "configurations": {
            "production": {
              "browserTarget": "MyAwesomeProject:build:production"
            }
          }
        },
        "extract-i18n": {
          "builder": "@angular-devkit/build-angular:extract-i18n",
          "options": {
            "browserTarget": "MyAwesomeProject:build"
          }
        },
        "test": {
          "builder": "@angular-devkit/build-angular:karma",
          "options": {
            "main": "apps/MyAwesomeProject/src/test.ts",
            "polyfills": "apps/MyAwesomeProject/src/polyfills.ts",
            "tsConfig": "apps/MyAwesomeProject/src/tsconfig.spec.json",
            "karmaConfig": "apps/MyAwesomeProject/src/karma.conf.js",
            "styles": ["apps/MyAwesomeProject/src/styles.css"],
            "scripts": [],
            "assets": ["apps/MyAwesomeProject/src/assets"]
          }
        },
        "lint": {
          "builder": "@angular-devkit/build-angular:tslint",
          "options": {
            "tsConfig": ["apps/MyAwesomeProject/tsconfig.app.json", "apps/MyAwesomeProject/tsconfig.spec.json"],
            "exclude": ["**/node_modules/**"]
          }
        },
        "server": {
          "builder": "@angular-devkit/build-angular:server",
          "options": {
            "outputPath": "dist-server",
            "main": "apps/MyAwesomeProject/src/main.ts",
            "tsConfig": "apps/MyAwesomeProject/tsconfig.server.json"
          },
          "configurations": {
            "dev": {
              "optimization": true,
              "outputHashing": "all",
              "sourceMap": false,
              "namedChunks": false,
              "extractLicenses": true,
              "vendorChunk": true
            },
            "production": {
              "optimization": true,
              "outputHashing": "all",
              "sourceMap": false,
              "namedChunks": false,
              "extractLicenses": true,
              "vendorChunk": false
            }
          }
        }
      }
    },
    "MyAwesomeProject-e2e": {
      "root": "apps/MyAwesomeProject-e2e/",
      "projectType": "application",
      "architect": {
        "e2e": {
          "builder": "@angular-devkit/build-angular:protractor",
          "options": {
            "protractorConfig": "apps/MyAwesomeProject-e2e/protractor.conf.js",
            "devServerTarget": "MyAwesomeProject:serve"
          }
        },
        "lint": {
          "builder": "@angular-devkit/build-angular:tslint",
          "options": {
            "tsConfig": "apps/MyAwesomeProject-e2e/tsconfig.e2e.json",
            "exclude": ["**/node_modules/**"]
          }
        }
      }
    }
  },
  "defaultProject": "MyAwesomeProject"
}
Enter fullscreen mode Exit fullscreen mode

Conclusion

Not bad! Not bad my friend! You've made a great choice by installing NX.

Interested in going further? There's a great demo app here.

Questions or comments? Don't hesitate to contact me.

Alt Text

💖 💪 🙅 🚩
dkreider
Daniel Kreider

Posted on October 31, 2020

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related