Angular Library paths alias declared in tsconfig.json not working: Module not found: Error: Can't resolve

Viewed 969

I'am developing an Angular (v12) library and a small app to test it that have the following structure:

├── projects
│   ├── my-app
│   │   ├── karma.conf.js
│   │   ├── src
│   │   ├── tsconfig.app.json
│   │   └── tsconfig.spec.json
│   └── my-lib
│       ├── README.md
│       ├── karma.conf.js
│       ├── ng-package.json
│       ├── node_modules
│       ├── package-lock.json
│       ├── package.json
│       ├── src
│       ├── tsconfig.lib.json
│       ├── tsconfig.lib.prod.json
│       └── tsconfig.spec.json
└── tsconfig.json

In the root ./tsconfig.json I declare paths aliases (as I understand to be recognized by VS Code):

 {
  "compileOnSave": false,
  "compilerOptions": {
    "baseUrl": "./",
    "outDir": "./dist/out-tsc",
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "noImplicitOverride": true,
    "noPropertyAccessFromIndexSignature": true,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true,
    "sourceMap": true,
    "paths": {
      "my-lib": [
        "dist/my-lib/my-lib",
        "dist/my-lib"
      ],
      "@services/*": [
        "projects/my-lib/src/lib/services/*"
      ]
    },
    "declaration": false,
    "downlevelIteration": true,
    "experimentalDecorators": true,
    "moduleResolution": "node",
    "importHelpers": true,
    "target": "es2017",
    "module": "es2020",
    "lib": [
      "es2020",
      "dom"
    ]
  },
  "angularCompilerOptions": {
    "enableI18nLegacyMessageIdFormat": false,
    "strictInjectionParameters": true,
    "strictInputAccessModifiers": true,
    "strictTemplates": true
  }
}

In the ./projects/my-lib/tsconfig.lib.json I declare again the paths aliases (as I understand to be interpreted by the ng-packagr compiler):

{
    "compileOnSave": false,
    "compilerOptions": {
      "baseUrl": "./",
      "outDir": "./dist/out-tsc",
      "paths": {
        "@services/*": [ "src/lib/services/*" ],
      },
      "sourceMap": true,
      "declaration": false,
      "module": "es2015",
      "moduleResolution": "node",
      "emitDecoratorMetadata": true,
      "experimentalDecorators": true,
      "target": "es5",
      "typeRoots": [
        "node_modules/@types"
      ],
      "lib": [
        "es2017",
        "dom"
      ]
    }
  }

The ./angular.json is referencing the tsconfig.lib.json:

{
  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
  "version": 1,
  "newProjectRoot": "projects",
  "projects": {
    "my-lib": {
      "projectType": "library",
      "root": "projects/my-lib",
      "sourceRoot": "projects/my-lib/src",
      "prefix": "lib",
      "architect": {
        "build": {
          "builder": "@angular-devkit/build-angular:ng-packagr",
          "options": {
            "project": "projects/my-lib/ng-package.json"
          },
          "configurations": {
            "production": {
              "tsConfig": "projects/my-lib/tsconfig.lib.prod.json"
            },
            "development": {
              "tsConfig": "projects/my-lib/tsconfig.lib.json"
            }
          },
          "defaultConfiguration": "production"

The Library is compiling without any errors.

When I import the library in my-app and I want to import a service for example, It does not resolve the paths aliases :

./node_modules/my-lib/fesm2015/my-lib.mjs:11:0-56 - Error: Module not found: Error: Can't resolve '@services/my-lib/my-lib.service' in '/Users/***/projects/ANGULAR/angular-tour-of-heroes/node_modules/my-lib/fesm2015'
    
    Error: node_modules/my-lib/lib/custom-page/custom-page.component.d.ts:2:30 - error TS2307: Cannot find module '@services/my-lib/my-lib.service' or its corresponding type declarations.
    
    2 import { MyLibService } from '@services/my-lib/my-lib.service';

Error: node_modules/my-lib/lib/custom-page/custom-page.component.d.ts:2:30 - error TS2307: Cannot find module '@services/my-lib/my-lib.service' or its corresponding type declarations.

2 import { MyLibService } from '@services/my-lib/my-lib.service';

I tried any combinations of configuration in the world, paths seems to be impossible to be used in an Angular Library

1 Answers

The tsconfig file for production is projects/my-lib/tsconfig.lib.prod.json (as declared in angular.json), so you probably have forgotten to set the alias path for production. To my understanding, this should point to the right path in the dist folder.

That said, I have the same issue (but already when running dev locally), so this is just a guess.

Edit:

I got it working locally, and am now facing a similar issue when trying to build. In my case it's an error not an absolute path (no ref to where that error comes from), and when I use the alias everywhere in my components, a lot of No suitable injection token for parameter 'tooltip' of class 'MyComponent'. errors.

I still hope you can make it work, but perhaps my answer won't lead to the solution.

Related