angular-cli library create secondary entry point

戏子无情 提交于 2019-12-18 16:48:11

问题


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?


回答1:


Thanks for the reply. Here is the solution I ended up with, it all revolved around setting up the index.ts and public_api.ts files correctly

\---projects
    \---scope
        \---ngx-package
            |   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
                |       package-client-config.ts
                |       package-client.spec.ts
                |       package-client.ts
                |       package.module.ts
                |
                \---models
                    |   index.ts  (1)
                    |   package.json (2)
                    |   public_api.ts  (3)
                    |
                    \---src
                        |   public_api.ts  (4)
                        |
                        \---lib
                            |   model-a.ts
                            |   model-b.ts
                            |
                            \---hateoas
                                    hateoas.ts

Ok so in the tree above notes the parens with numbers inside they correspond to the files below.

1) /projects/scope/ngx-package/src/models/index.ts

// export what ./public_api exports so we can reference models like
// import { modelA } from './models'
export * from './public_api';

2) /projects/scope/ngx-package/src/models/package.json

{
  "ngPackage": {}
}

3) /projects/scope/ngx-package/src/models/public_api.ts

export * from './src/public_api';

4) /projects/scope/ngx-package/src/models/src/public_api.ts

export * from './lib/model-a';
export * from './lib/model-b';
export * from './lib/hateoas/hateoas';

With this setup you only need to maintain your list of exports in one place. I tried a lot of other variations that didn't work this seemed to work without problem.




回答2:


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.




回答3:


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



来源:https://stackoverflow.com/questions/50802447/angular-cli-library-create-secondary-entry-point

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!