Angular-cli: One library can't import another library

Created on 5 May 2018  路  26Comments  路  Source: angular/angular-cli

Versions

Angular CLI: 6.0.0
Node: 10.0.0
OS: darwin x64
Angular: 6.0.0
... animations, cli, common, compiler, compiler-cli, core, forms
... http, language-service, platform-browser
... platform-browser-dynamic, router

Package                            Version
------------------------------------------------------------
@angular-devkit/architect          0.6.0
@angular-devkit/build-angular      0.6.0
@angular-devkit/build-ng-packagr   0.6.0
@angular-devkit/build-optimizer    0.6.0
@angular-devkit/core               0.6.0
@angular-devkit/schematics         0.6.0
@ngtools/json-schema               1.1.0
@ngtools/webpack                   6.0.0
@schematics/angular                0.6.0
@schematics/update                 0.6.0
ng-packagr                         3.0.0-rc.2
rxjs                               6.1.0
typescript                         2.7.2
webpack                            4.6.0

Repro steps

  • Step 1
    ng generate library model-lib
    ng generate library ui-lib
    ng generate application portal
  • Step 2
    ng build model-lib
  • Step 3
    import { ModelLibModule } from 'model-lib' in portal module
    ng build portal
  • Step 4
    import { ModelLibModule } from 'model-lib' in ui-lib module
    ng build ui-lib

Observed behavior

BUILD ERROR
projects/ui-lib/src/lib/ui-lib.module.ts(3,29): error TS2307: Cannot find module 'model-lib'.

Desired behavior

Library should import other library same as application.

high broken

Most helpful comment

Ok, after trying plenty of different things I finally managed to get it to work.

--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,16 +1,16 @@
 {
   "compileOnSave": false,
   "compilerOptions": {
-    "baseUrl": ".",
+    "baseUrl": "./",
     "outDir": "./dist/out-tsc",
     "sourceMap": true,
     "declaration": false,
-    "module": "es2015",
+    "module": "esnext",
     "moduleResolution": "node",
     "emitDecoratorMetadata": true,
     "experimentalDecorators": true,
     "importHelpers": true,
-    "target": "es5",
+    "target": "es2015",
     "typeRoots": ["node_modules/@types"],
     "lib": ["es2018", "dom"],
     "paths": {
--- a/tsconfig.app.json
+++ b/tsconfig.app.json
@@ -2,11 +2,7 @@
   "extends": "./tsconfig.json",
   "compilerOptions": {
     "outDir": "./out-tsc/app",
-    "types": [],
-    "paths": {
-      "ngx-hover-opacity": ["projects/ngx-hover-opacity/src/public_api"],
-      "ngx-hover-opacity/*": ["projects/ngx-hover-opacity/src/public_api"]
-    }
+    "types": []
   },
   "include": ["src/**/*.ts"],

Might eventually help someone out here :man_shrugging:

All 26 comments

Have same issue, even added two libs to tsconfig.json file

Same, it's a pretty critical issue imho. I tried playing with the compiler options "baseUrl" and "path", but the error is always the same during the compilation step with ngc.
Note that the IDE's (VS Code) intellisense works in resolving an import from library 1 written inside a file of library 2, but then the compilation of library 2 fails.

solved that issue by defining libs in paths see https://github.com/formly-js/ngx-formly/blob/master/tsconfig.json#L20-L22 and for building libs I used a patch in ng-packgr to make it work

@aitboudad can you point me to a link explaining how ngpackagr patches work? I can't find it in their documentation. I mean, does the .patch file just need to be in the project folder somewhere and have to be named ng-packagr.patch?
It could solve my issue because I've already mapped the dependency library correctly in paths but to no avail.

Thanks @aitboudad.
While trying to figure out what the hell that patch is (looks like a piece of git diff, something I'm not confortable with), I manually added a log inside the ng-packagr script for ngc compilation, and I've realized two things:
1) library 2, which doesn't compile because tsc (or ngc? Didn't dig too much) cannot resolve absolute paths from library1 pointing to dist/library1, inherits the main tsconfig.json, where the following options are specified:
{ "baseUrl": "./", [...], "paths": { "library1": ["dist/library1"], "library2": ["dist/library2"] } }.
My library2's tsconfig.lib.json was trying to override these options like this:
{ "baseUrl": "../../" }
When I added the following log lines:
image
I noticed that baseUrl would still point to "./" (which, for the compilation of library 2, would be {root}/projects/library2/src and therefore this baseUrl was not overridden!
Moreover, I would expect the path to be {root}/projects/library2, where tsconfig.lib.json is, not the {root}/projects/library2/src folder, which is 1 level deeper!
So my solution is to override the paths option inside library2's tsconfig, using 3 times the "../" command:
{ [...], "paths": { "library1": ["../../../dist/library1"] } }
and now it works.

@Etchelon another easy way is to add paths in tsconfig.lib.json but it'll not wok when using a secondary entry points

same here

With a library generated with 6.0.2+ this should no longer be an issue. Support for secondary entry points will be corrected via https://github.com/angular/devkit/pull/933

For an existing library exhibiting the issue, ensure the library that contains the import has its own tsconfig and that it has a paths section as described in the previous responses.

With a library generated with 6.0.2+ this should no longer be an issue.

Can you elaborate on this?

If lib-b depends on lib-a (both created w/6.0.0):

Which library do I need to regenerate for this issue to go away?

What manual change can I make so that both libs function as if they were created w/6.0.2+?

I regenerated lib-b w/6.0.7 and still had an issue.

btw, adding paths to lib-b as describe above works---but if this is not the 'official cli' way, I'd rather not use it.

Any news on this? I have the same issue with Angular CLI 6.0.8..

It works for me after I have corrected the "paths" of library in "tsconfig.lib.json". I have Angular CLI 6.0.9.

Same here with "@angular/cli": "6.2.5", I think this issue should be reopened =/

If anyone has a fix BTW can you please share your solution? Tried with the path too but didn't work either

Ok so I've been digging into that issue and found out what was wrong.

For some reason, /src/tsconfig.app.json had into compilerOptions the following prop:

"baseUrl": "./",

Removed that and now everything seems to be working.

@maxime1992 Thanks a lot!! I was debugging this for a couple of hours and it was driving me crazy. Thanks a lot.

It happens when you migrate an application from 5.x to latest angular version, in my case it was 7.x. So old tsconfig.app contained that property and was messing the imports from the libraries.

Trying to migrate to v8... this trick doesn't work anymore and baseUrl is now required...

I've been stuck on that for 2 hours now :(

Ok, after trying plenty of different things I finally managed to get it to work.

--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,16 +1,16 @@
 {
   "compileOnSave": false,
   "compilerOptions": {
-    "baseUrl": ".",
+    "baseUrl": "./",
     "outDir": "./dist/out-tsc",
     "sourceMap": true,
     "declaration": false,
-    "module": "es2015",
+    "module": "esnext",
     "moduleResolution": "node",
     "emitDecoratorMetadata": true,
     "experimentalDecorators": true,
     "importHelpers": true,
-    "target": "es5",
+    "target": "es2015",
     "typeRoots": ["node_modules/@types"],
     "lib": ["es2018", "dom"],
     "paths": {
--- a/tsconfig.app.json
+++ b/tsconfig.app.json
@@ -2,11 +2,7 @@
   "extends": "./tsconfig.json",
   "compilerOptions": {
     "outDir": "./out-tsc/app",
-    "types": [],
-    "paths": {
-      "ngx-hover-opacity": ["projects/ngx-hover-opacity/src/public_api"],
-      "ngx-hover-opacity/*": ["projects/ngx-hover-opacity/src/public_api"]
-    }
+    "types": []
   },
   "include": ["src/**/*.ts"],

Might eventually help someone out here :man_shrugging:

Specifically, just adding those two lines to your lib's tsconfig:
"baseUrl": "./",
"module": "esnext",

Specifically, just adding those two lines to your lib's tsconfig:
"baseUrl": "./",
"module": "esnext",

Hello @kcrossman. I just added this in my tsconfig.lib.json, but now my first library can not see components from another library (shared-lib). Do u have any solution for that?

Specifically, just adding those two lines to your lib's tsconfig:
"baseUrl": "./",
"module": "esnext",

Hello @kcrossman. I just added this in my tsconfig.lib.json, but now my first library can not see components from another library (shared-lib). Do u have any solution for that?

This is a project I made to test making a library and whatnot, for your reference:
https://github.com/kcrossman/OpenNg

Check out my config files to see if they can help you out.

In your tsconfig.json, you need to specify the path to each library you have as such:

...
    "paths": {
      "shared-lib": [
        "dist/shared-lib"
      ],
      "shared-lib/*": [
        "dist/shared-lib/*"
      ]
    }
...

Import your library with just:
import { ... } from 'shared-lib';

After which, you have to run ng build or ng build shared-lib to publish your library to that dist folder. Your code may show red lines but it will work at that point if you just run ng serve if you have an Angular application to demo your libraries.

I haven't tried creating multiple libraries with my sample, so further from that I won't be of much help.

@kcrossman I have the same issue with angular 8, I made a repo to reproduce my error here: https://github.com/fjoalland/multiple-angular-lib/

You just need to follow the steps and you will have the same error as me
[error] Error: : Unexpected value 'Lib1Module in D:/Documents/multiple-angular-lib/lib1/dist/libs/lib1/libs-lib1.d.ts' imported by the module 'Lib2Module in D:/Documents/multiple-angular-lib/lib2/projects/libs/lib2/src/lib/lib2.module.ts'. Please add a @NgModule annotation. at Object.<anonymous> (D:\Documents\multiple-angular-lib\lib2\node_modules\ng-packagr\lib\ngc\compile-source-files.js:73:19)

DId you manage to find a solution?

@fjoalland Your repository isn't configured correctly to use the normal import rule. You will have to host each library and npm install them to use them. I will copy some commands so that you can re-create your libraries to work how I suggested it would work...

  1. ng new ng-libs-ws --style=scss --createApplication=false --skip-git --skip-install
    (ws means workspace, not a standard name for Angular and you can name it whatever you want, but createApplication=false basically creates an empty Angular shell to group your Angular libraries and apps)
  2. cd ng-libs-ws
  3. ng g library ng-lib1 --skip-install
  4. ng g library ng-lib2 --skip-install
  5. ng g library ng-lib3 --skip-install
  6. (optional) ng g application ng-libs-demo --style=scss --routing --minimal --skip-install
  7. npm i

At this point, you should be able to import your ng-lib1 where you want to use it. Though, I haven't done this myself. I've only verified the commands work and the initial config looks right...

@kcrossman Thank you for your answer.

However, I have tested well and it does not work. Maybe I did not explain what I was trying to do.

I would like to import a library into another library (and not an angular application). I know how to import a library into an angular application, it works without problems. However, I get an error when I import a library into another library with the npm linkcommand. By cons (and this is the most surprising!), If I deploy my library on a private repository (example: nexus), and I import it into another library with the command npm install, it will work. So the problem is because of symlink, it doesn't work when I try to import a library into another library.

I recreated a github with my error and with I follow the steps you made: https://github.com/fjoalland/import-lib-angular-in-other-angular-lib

There are two librairies:

  • ng-lib2 in ng-libs-ws-bis directory
  • ng-lib1 in ng-libs-ws directory

To have my error, follow these steps:

  • cd ng-libs-ws
  • npm i
  • ng build
  • cd dist/ng-lib1
  • npm link
  • cd ../../..
  • cd ng-libs-ws-bis
  • npm i
  • npm link ng-lib1
  • ng build

The ng-lib2 library imports the ng-lib1 library module

import { NgModule } from '@angular/core';
import { NgLib2Component } from './ng-lib2.component';
import {NgLib1Module} from 'ng-lib1';

@NgModule({
  declarations: [NgLib2Component],
  imports: [
    NgLib1Module
  ],
  exports: [NgLib2Component]
})
export class NgLib2Module { }

Bellow, the error I got

ERROR: : Unexpected value 'NgLib1Module in /home/user/Documents/Test/libs/ng-libs-ws/dist/ng-lib1/ng-lib1.d.ts' imported by the module 'NgLib2Module in /home/user/Documents/Test/libs/ng-libs-ws-bis/projects/ng-lib2/src/lib/ng-lib2.module.ts'. Please add a @NgModule annotation.

An unhandled exception occurred: : Unexpected value 'NgLib1Module in /home/user/Documents/Test/libs/ng-libs-ws/dist/ng-lib1/ng-lib1.d.ts' imported by the module 'NgLib2Module in /home/user/Documents/Test/libs/ng-libs-ws-bis/projects/ng-lib2/src/lib/ng-lib2.module.ts'. Please add a @NgModule annotation.

See "/tmp/ng-cOPw65/angular-errors.log" for further details.

On the other hand, if I publish the library ng-libs-ws on my private repository nexus, and install it with the command 'npm install ng-lib2' on ng-libs-ws-bis, it will work.

@fjoalland If they are separate Angular projects/roots/workspaces, you cannot share them without hosting them in some way and npm installing them. You don't necessarily have to use Nexus, something like Verdaccio may work better for you locally (more help).

@krossman thanks a lot I didn't know Verdaccio! It's a great solution to resolve my problem.
I will try that and tell you if it's working. But I hope that one day, npm link will work with angular library. It's much comfortable to use ng build --watch in a symlink to debug your library in real time.

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

_This action has been performed automatically by a bot._

Was this page helpful?
0 / 5 - 0 ratings

Related issues

naveedahmed1 picture naveedahmed1  路  3Comments

MateenKadwaikar picture MateenKadwaikar  路  3Comments

purushottamjha picture purushottamjha  路  3Comments

IngvarKofoed picture IngvarKofoed  路  3Comments

JanStureNielsen picture JanStureNielsen  路  3Comments