angularangular8angular-cli-v8

Angular CLI 8."ng serve" fails when using "paths" in tsconfig.json


I'm working on a project that includes several different frontends based on Angular 8. Each frontend is a separate Angular 8 project with its own folder substructure. Their root folders are all located in the same main folder.

theproject
    |___ frontend1
    |___ frontend2
    ...

To avoid duplicate code and to optimize code refactoring we've come to the decision to put repetitive code into a "base" folder and import it via the paths option set in tsconfig.json.

theproject
    |___ frontend1/
    |___ frontend2/
    ...
    |___ base-ui/

We started with a simple class representing collections of constants that are used throughout the entire frontend landscape. This class is located inside the file constants.ts which is to be found in the folder base-ui/constants

theproject
    |___ frontend1/
    |___ frontend2/
    ...
    |___ base-ui/constants/constants.ts

This is our tsconfig.json

{
  "compileOnSave": false,
  "compilerOptions": {
    "baseUrl": "./",
    "outDir": "./dist/out-tsc",
    "sourceMap": true,
    "declaration": false,
    "module": "es2015",
    "moduleResolution": "node",
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "importHelpers": true,
    "target": "es5",
    "typeRoots": [
      "node_modules/@types"
    ],
    "lib": [
      "es2018",
      "dom"
    ],
    "types": [
      "hammerjs",
      "jasmine"
    ],
    "paths": {
      "@shared/*": [
        "../base-ui/*"
      ]
    }
  }
}

And this is the very simple content of constants.ts

export class BaseServerConstants {
    public static readonly LOGOUT_URL = 'server/logout';
    public static readonly LOGIN_URL = 'server/login';
}

Here is how we import/use it

import { BaseServerConstants } from '@shared/constants/constants';

...

performLogout(): void {
    window.location.href = BaseServerConstants.LOGOUT_URL;
}

This works like a charm as long as we just code or build the projects with ng build or ng build --prod.

But using ng serve inside the console of IntelliJ or VS Code always leads to the same error message which says:

ERROR in /Users/developer/theproject/base-ui/constants/constants.ts
Module not found: Error: Can't resolve 'tslib' in '/Users/developer/theproject/base-ui/constants'

Why does this happen? Why am I able to use this paths option in order to import very basic classes out of simple TS files that are located beyond the baseUrl and apply them while coding. And they also cause no compiler errors when building the final application! The apps work as expected afterwards.

But when this code is supposed to run locally inside NodeJS it won't compile?!

Is there an additional option I have to set?

Any help or hint is very much appreciated!


Solution

  • Well, I found a solution myself.

    One has to simply put a barrel (index.ts) inside the external folder and export the file of interest. So in my case doing this solved the problem above:

    theproject
        |___ frontend1/
        |___ frontend2/
        ...
        |___ base-ui/constants/constants.ts
        |___ base-ui/index.ts
    

    Content of index.ts

    export * from './constants/constants';
    

    Unfortunately, this works up to Angular 8.1.3. The newer projects using Angular 8.2.7 run into the same error as before...