question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. ItΒ collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Exporting modules from outside the library folder fails with an error

See original GitHub issue

Type of Issue

[x ] Bug Report
[ ] Feature Request

Description

I’m trying to export parts of an existing angular app as a library, but it seems there is path issues. Here is my folder structure: image

And my public_api.ts:

export * from '../src/app/shared/shared.module';

But when trying to build the library, I get this error:

Building Angular library from lib/ng-package.json

BUILD ERROR
Error at /Users/noda/github/addon-library/test/lib/.ng_build/ts/public_api.ts:2:15: Cannot find module '../src/app/shared/shared.module'.
Error: Error at /Users/noda/github/addon-library/test/lib/.ng_build/ts/public_api.ts:2:15: Cannot find module '../src/app/shared/shared.module'.
    at new UserError (/Users/noda/github/addon-library/test/node_modules/@angular/tsc-wrapped/src/tsc.js:27:28)
    at check (/Users/noda/github/addon-library/test/node_modules/@angular/tsc-wrapped/src/tsc.js:93:15)
    at Tsc.typeCheck (/Users/noda/github/addon-library/test/node_modules/@angular/tsc-wrapped/src/tsc.js:173:9)
    at /Users/noda/github/addon-library/test/node_modules/@angular/tsc-wrapped/src/main.js:122:23
    at <anonymous>

How To Reproduce

  1. Create a typical angular-cli app with a feature module.
  2. Create a dedicated lib folder containing ng-packagr configuration
  3. Try to export your app feature module in lib/public_api.ts with something like export * from '../src/app/my-feature/my-feature.module';
  4. Build the library

Expected Behaviour

The library builds without error πŸ˜„

Version Information

ng-packagr: v1.6.0
node: v8.8.1
@angular: v5.0.5
rxjs: 5.5.2
zone.js: 0.8.14

please include any version information that might be relevant, e.g. other third-party libraries

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Reactions:24
  • Comments:39 (4 by maintainers)

github_iconTop GitHub Comments

28reactions
annalencommented, Mar 27, 2018

I get the same error when using sencondary entry points.

I try to build the library according to the following scheme:

  • All services which have to have one and only one instance per application should be implemented in the BarModule here.
  • And ViewModules should import services from FooModule.

Here is a link to the git project of the sample library: https://github.com/annalen/example-library.

This example project is structured as follows:

example-library
β”œβ”€β”€ foo
|   β”œβ”€β”€ bar
|   |	β”œβ”€β”€ src
|   |	|   β”œβ”€β”€ bar.module.ts
|   |	|   └── settings.service.ts
|   |	β”œβ”€β”€ index.ts
|   |	β”œβ”€β”€ package.json
|   |	└── public_api.ts
|   β”œβ”€β”€ view
|   |	β”œβ”€β”€ src
|   |	|   β”œβ”€β”€ view.component.ts
|   |	|   β”œβ”€β”€ view.component.html
|   |	|   └── view.module.ts
|   |	β”œβ”€β”€ index.ts
|   |	β”œβ”€β”€ package.json
|   |	└── public_api.ts
|   └── package.json
β”œβ”€β”€ public_api.ts
└── package.json

In this example case, the ViewModule imports the BarModule and the ViewComponent uses the SettingsService.

And I think that’s why I get the following error.:

File '.../example-library/lib/foo/bar/src/bar.module.ts' is not under 'rootDir' 
'...\example-library\lib\foo\view'. 'rootDir' is expected to contain all source files.
error TS6059: 
File '.../example-library/lib/foo/bar/src/settings.service.ts' is not under 'rootDir' 
'..\example-library\lib\foo\view'. 'rootDir' is expected to contain all source files.

Thank you for your help.

12reactions
Proantagonistcommented, Aug 24, 2019

I have found a solution that suits my needs.

Context: The utils package used as an example below is meant to be a framework-agnostic tool set that is used across internal applications (vanilla, angular, etc). If the project was written in JS, then any tool in the package could be utilized.

While better solution exists in the form of custom NPM scripts, I am also developing some Angular packages alongside, which is why I’m using Angular CLI to handle the scaffolding and build process. That’s why you won’t see any true Angular modules being used in the example.

Anyways, it made sense to split tools by feature or function into separate packages that would then be able to be imported separately into consuming applications. The utils package evolved into having secondary endpoints with a source structure that resembled:

.
β”œβ”€β”€ dist
β”œβ”€β”€ node_modules
β”œβ”€β”€ packages (1)
β”‚  β”œβ”€β”€ utils (2)
β”‚  β”‚   └── geometry (3)
β”‚  β”‚   β”‚   β”œβ”€β”€ src
β”‚  β”‚   β”‚   β”‚   β”œβ”€β”€ lib
β”‚  β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ esri
β”‚  β”‚   β”‚   β”‚   β”‚   β”‚   └── centroidFromGeometry.ts
β”‚  β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ generic
β”‚  β”‚   β”‚   β”‚   β”‚   β”‚   └── nearestIndex.ts (6)
β”‚  β”‚   β”‚   β”‚   └── public-api.ts
β”‚  β”‚   β”‚   β”œβ”€β”€ public-api.ts
β”‚  β”‚   β”‚   β”œβ”€β”€ ng-package.json (7)
β”‚  β”‚   β”‚   └── package.json
β”‚  β”‚   β”œβ”€β”€ number (4)
β”‚  β”‚   β”‚   β”œβ”€β”€ src
β”‚  β”‚   β”‚   β”‚   β”œβ”€β”€ lib
β”‚  β”‚   β”‚   β”‚   β”‚   └── smallestIndex.ts (5)
β”‚  β”‚   β”‚   β”‚   └── public-api.ts
β”‚  β”‚   β”‚   β”œβ”€β”€ public-api.ts
β”‚  β”‚   β”‚   β”œβ”€β”€ ng-package.json
β”‚  β”‚   β”‚   └── package.json
β”‚  β”‚   β”œβ”€β”€ public-api.ts
β”‚  β”‚   β”œβ”€β”€ ng-package.json
β”‚  β”‚   └── package.json
β”œβ”€β”€ angular.json
β”œβ”€β”€ package.json
β”œβ”€β”€ tsconfig.json
└── tslint.json

(1) Renamed default β€œprojects” folder generated by Angular CLI. The scope of the project is @tamu-gisc.

(2) Scoped package entry point. The entry point is @tamu-gisc/utils

(3) Secondary entry point for the utils package. The entry point is @tamu-gisc/utils/geometry

(4) Secondary entry point for the utils package. - The entry point is @tamu-gisc/utils/number

(5) Dependency FOR (6)

(7) Specifies the entry file for the secondary entry point:

{
  "$schema": "../../../node_modules/ng-packagr/ng-package.schema.json",
  "lib": {
    "entryFile": "public-api.ts",
    "umdModuleIds": {}
  }
}

When ng build --project=utils was executed, NgPackagr attempted to build both (3) geometry and (4) number packages as secondary entry points for (2) utils. However, when NgPackagr builds the (3) geometry secondary entry point, it realizes that (5) is not at or in the same package directory relative to (3) geometry’s public-api.ts entry file specified in (7).

The solution I found was reformatting the project structure to the following:

.
β”œβ”€β”€ dist
β”œβ”€β”€ node_modules
β”œβ”€β”€ packages (1)
β”‚  β”œβ”€β”€ utils (2)
β”‚  β”‚   β”œβ”€β”€ internal (8)
β”‚  β”‚   β”‚   β”œβ”€β”€ geometry
β”‚  β”‚   β”‚   β”‚   β”œβ”€β”€ esri
β”‚  β”‚   β”‚   β”‚   β”‚   └── centroidFromGeometry.ts
β”‚  β”‚   β”‚   β”‚   β”œβ”€β”€ generic
β”‚  β”‚   β”‚   β”‚   β”‚   └── nearestIndex.ts (6)
β”‚  β”‚   β”‚   β”œβ”€β”€ number
β”‚  β”‚   β”‚   β”‚   └── smallestIndex.ts (5)
β”‚  β”‚   β”œβ”€β”€ geometry (3)
β”‚  β”‚   β”‚   β”œβ”€β”€ ng-package.json (7)
β”‚  β”‚   β”‚   └── package.json
β”‚  β”‚   β”œβ”€β”€ number (4)
β”‚  β”‚   β”‚   β”œβ”€β”€ ng-package.json
β”‚  β”‚   β”‚   └── package.json
β”‚  β”‚   β”œβ”€β”€ public-api.ts
β”‚  β”‚   β”œβ”€β”€ public-api.geometry.ts (9)
β”‚  β”‚   β”œβ”€β”€ public-api.number.ts
β”‚  β”‚   β”œβ”€β”€ ng-package.json
β”‚  β”‚   └── package.json
β”œβ”€β”€ angular.json
β”œβ”€β”€ package.json
β”œβ”€β”€ tsconfig.json
└── tslint.json

With this layout, all the business logic of the library modules goes into (8) internal, and (6) has no problem importing (5). The secondary entry point file for the (3) geometry package has moved to the root of the (9) utils package.

The geometry package (7) ng-package.json now looks like:

{
 "$schema": "../../../node_modules/ng-packagr/ng-package.schema.json",
 "lib": {
   "entryFile": "../public-api.geometry.ts",
   "umdModuleIds": {}
 }
}

Why this works?

This explanation is potentially wrong, so take it with a grain of salt. However, it’s the best I can do in my own words.

NgPackagr recognizes secondary entry points by the presence of either package.json with the β€œngPackage” property OR ng-package.json (Source). Because of this, it is possible to designate secondary entry points with either or both package.json or ng-package.json (see (3) and (4) in the file tree above) and omitting any source files there. The source files are moved to a β€œshared” space where all packages can access and reference (See (8)). The entry file for each of the packages are alongside the primary entry point’s entry file (See (9)) and in this way the all source files are at or in the same package directory relative to their respective entry file, meeting the 'rootDir' is expected to contain all source files. requirement.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Python error "ImportError: No module named" - Stack Overflow
The problem in my case was that there was the permission to newly installed modules were not 755 . That was because umask...
Read more >
Angular Library Module Import Error
try un-excluding the dist directory (from the folder right-click menu, choose Mark directory as/Not Excluded) - does the issue persist? 1.
Read more >
import - JavaScript - MDN Web Docs - Mozilla
Given a value named myExport which has been exported from the module my-module either implicitly as export * from 'another.js' ) or explicitlyΒ ......
Read more >
Documentation - Module Resolution - TypeScript
If you are having resolution problems with import s and export s in TypeScript, try setting moduleResolution: "node" to see if it fixes...
Read more >
Export and Import - The Modern JavaScript Tutorial
Imagine, we're writing a β€œpackage”: a folder with a lot of modules, with some of the functionality exported outside (tools like NPM allow...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found