Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

angular-cli library create secondary entry point

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?

like image 339
JoAMoS Avatar asked Jun 11 '18 16:06

JoAMoS


People also ask

Why do we need secondary entrypoints in angular?

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.

What is the difference between NPM and angular entry points?

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).

How do I create a new library in angular?

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.

How do I create a secondary entry point folder in ng-packagr?

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.


Video Answer


2 Answers

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 with import {..} from '@my/library/testing'

Source - https://github.com/ng-packagr/ng-packagr/blob/master/docs/secondary-entrypoints.md

like image 63
progm Avatar answered Oct 14 '22 17:10

progm


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.

like image 35
Shlomi Assaf Avatar answered Oct 14 '22 19:10

Shlomi Assaf