Image for post
Image for post
Photo by Arie Wubben on Unsplash

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?

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"
}

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.

Image for post
Image for post

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store