I am trying to create what I believe is called a secondary entry point into my angular npm package. I want the following two entry points
@scope/data-service
@scope/data-service/models
Using the angular-cli to generate the base package generates the following structure
scope
└───data-service
│ karma.conf.js
│ ng-package.json
│ ng-package.prod.json
│ package.json
│ tsconfig.lib.json
│ tsconfig.spec.json
│ tslint.json
│
└───src
│ public_api.ts
│ test.ts
│
└───lib
data-service.component.spec.ts
data-service.component.ts
data-service.module.ts
data-service.service.spec.ts
data-service.service.ts
Based on ng-packagr documentation you would add a folder under data-service called models then add a second package.json
to that folder but ng-packagr seems to use a slightly different structure than the angular-cli. Ideally I am trying to model the structure similar to https://github.com/angular/angular/tree/master/packages/common but as long as the public exposed is @scope/data-service
and @scope/data-service/models
I would be happy.
When I try to create the structure similar to ng-packager recommendation I get
error TS6059: File 'C:/projects/data-service-app/projects/scope/data-service/models/src/index.ts' is not under 'rootDir' 'C:\projects\data-service-app\projects\scope\data-service\src'. 'rootDir' is expected to contain all source files.
When I move the models directory into the data-service\src
directory my entrypoints are
@scope/data-service
@scope/data-service/src/models
How do I get rid of the src on my secondary entry point?
What is the correct approach for creating a library with a secondary entry point when using the angular-cli?
By adding secondary entrypoints, we basically split our Angular libraries into multiple chunks, just like Angular Material does. The idea behind it is not new at all, this option already exists since the beginning phase of ng-packagr.
In a newly created Angular library that's the only entry point that you have and it exports all of your modules, components, services, etc. An npm package can have additional entry points, called secondary entry points (or subentry points).
The Angular CLI has a generate library command to generate a new Angular library. This works fine for smaller libs but as your library grows it becomes more difficult to maintain and may have negative performance impacts.
According to ng-packagr documentation, one of the folder layout examples for secondary entry points is to have it like the following: As can be seen, the folder for secondary entry points is placed directly under /my_package, which differs from the primary entry point folders that are put under /my_package/src.
Example Folder Layout for Secondary Entrypoints
All you have to do is create a
package.json
file and put it where you want a secondary entry point to be created. One way this can be done is by mimicking the folder structure of the following example which has a testing entry point in addition to its main entry point.my_package ├── src | ├── public_api.ts | └── *.ts ├── ng-package.json ├── package.json └── testing ├── src | ├── public_api.ts | └── *.ts └── package.json
The contents of
my_package/testing/package.json
can be as simple as:{ "ngPackage": {} }
No, that is not a typo. No name is required. No version is required. It's all handled for you by ng-packagr! When built, the primary entry point is imported by
import {..} from '@my/library'
and the secondary entry point withimport {..} from '@my/library/testing'
Source - https://github.com/ng-packagr/ng-packagr/blob/master/docs/secondary-entrypoints.md
I'm afraid that this is not an easy task with ng-packagr.
For every "project" that you try to package, ng-packagr automatically detects all secondary packages.
ng-packagr ignores tsconfig.lib.json
files of secondary packages, it will use the tsconfig file provided with the primary package.
It then loads a TS program for the primary and all secondaries, before compiling, with the tsconfig of the primary.
This is done this way so the packager can then parse the code and create a dependency tree, which will tell it which package to render first, 2nd etc... YES, it also means that ng-packagr DOES NOT assume that a secondary package always depends on the primary, it might be the other way and it's valid...
Now, up to this point everything should be ok, no errors etc... A TS program is created for all packages but without emitting anything so all is good.
The error you see comes in the compilation phase, where the compiler try to emit files and throws. This is when ng-packagr logs "Compiling TypeScript sources through ngc"
At this point, typescript is not happy with the reference to a file outside of the root, which is the case.
One solution is to update the paths
property in tsconfig
to point to the output directory for every package that was built. So if package A was just compiled, we change/create paths
record that points to the output library which will not be considered as a TS source... thus no error.
This will work, I have tested it, but sadly it requires some work either in ng-packagr
source code or, as I did it, using a custom angular devkit builder...
With it you can replace the paths
right after each compilation has finished, so next compilation will reference the built output and not the source code.
Because ng-packagr build packages based on dependency graph we are safe to assume that this will work.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With