@froko/ng-essentials: Version 3.1.1 released

Last weekend I’ve released a new minor version of @froko/ng-essentials. Together with the rebirth of my blog, I think it’s time to write something about it. So let’s get started:

ng-essentials is an Angular schematic aimed to add better defaults to a newly created application. I’ve been working with Angular2+ since the early days, and I’ve always found myself tweaking and configuring the same settings over and over again with every new project I’ve started. Then I’ve heard about the custom schematics that have been introduced in Angular 7 and started playing around with them. The result was the born of ng-essentials back in fall 2018.

As the npm site states, ng-essentials includes many of the ideas of a blog post, written by Martin Hochel: Use React tools for better Angular apps. The schematic improves a new Angular project in the following ways:

  • Update of the npm packages to their latest stable version, while keeping specific version dependencies (e.g. Angular vs. Typescript)
  • Removal of all automatic update signifiers (e.g. ^ or ~) in package.json, inclusive the save-exact=true setting in .npmrc. I’ve seen too many projects failed to build after some time since not all dependent projects seem to follow the semantic versioning.
  • Introduction of npm-force-resolutions as a pre-install script. This will ensure that sub-dependencies are installed with security-patched versions defined in the resolutions array of package.json.
  • Improvement of TsLint settings. One special case is the import statement ordering with different blocks. TsLint is now able to find and fix such issues so that you don’t have to worry about them anymore.
  • Installation and configuration of prettier for advanced code formatting: Just run npm run format to bring your codebase in a consistent shape.
  • Installation and configuration of husky. It will set up a git hook that automatically runs prettier to format your staged code and does linting of your existing codebase when you commit to git. This works great if your git repo only includes your Angular project. If, on the other hand, your Angular project is just a part of a higher-order git repo, you will have to deal with the fact, that the commit hook runs with every commit, even if it has nothing to do with your Angular codebase.
    I haven’t found a really good workaround yet. The only thing I can propose is to uninstall husky and a related package called pretty-quick. To do so, just run npm uninstall husky pretty-quick and remove the husky section in package.json.
  • Creation of a settings file in the .vscode folder. It will configure Visual Studio Code to format and fix-lint your file every time you save it.
  • Creation of a launch file in the .vscode folder to support debug capabilities while serving or testing your code.
  • Introduction of an ENV_PROVIDERS injection token in environment.ts and environment.prod.ts. This makes your code less dependent on the actual environment file. ENV_PROVIDERS gets registered in the providers array of the AppModule. So it’s possible to define your services like this:
import { HttpClient } from '@angular/common/http';
import { Inject, Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class MyDataService {
  constructor(
    private http: HttpClient,
    @Inject('baseUrl') private baseUrl: string) {}

  getAll(): Observable<MyData[]> {
    const url = `${this.baseUrl}/courses`;
    return this.http.get<MyData[]>(url);
  }
}
  • Removal of the e2e testing functionality with protractor. There are some reasons why I made this a non-optional operation:
    • Protractor is outdated. It once had its benefits compared to cypress (see below), especially when it comes to multi-browser support. But with the most recent major release of cypress, this is no longer the case. See this blog post for 5 reasons you should not use Protractor in 2020. Spoiler: They don’t recommend cypress as a first-class replacement…
    • Protractor has a dependency to jasmine – at least with the default Angular CLI stack. My goal was to remove karma/jasmine entirely when you opt-in for jest (see below). This is only possible if I remove Protractor as well.
    • Maybe your project doesn’t need e2e tests at all…

Configuration Options

ng-essentials comes with 2 additional configuration options:

  • --jest
    Removes karma/jasmine entirely and replaces it with jest using @angular-builders/jest. ng test will automatically use jest as test runner.
    ng-test --coverage will display an additional test coverage report, while ng-test --watch starts jest in a continuous mode waiting for file changes. If you have a wallaby license, you can use it as well – just use the automatic configuration.
    ng-essentials will store the chosen configuration options in angular.json and add itself as default collection. This will allow the creation of libraries and applications later on with jest enabled if ng-essentials has been added before with the --jest option.
  • --cypress
    Adds e2e testing with Cypress.io including the ability to write tests in TypeScript. Since there is no Angular builder yet, the ng e2e command has been removed and replaced by npm run cypress. In its default configuration, it will fire up ng serve and open a visual cypress instance where you can run your e2e tests.

After Installation Tasks

There are some limitations to the Angular Schematics, or I haven’t found out all possibilities. Either way, after adding the ng-essentials schematics we have to tasks by ourselves before commiting to git:

  1. rm -rf e2e
    Remove protractor’s source folder since it is not used anymore.
  2. npm run format
    Reformat your codebase based on the prettier settings.
  3. ng lint --fix
    lint and fix your codebase.

Now we have a commitable state and really good starting point for our next Angular project!