Angularライブラリーに別のEntryPointを追加する
Angular CLI で作成したライブラリープロジェクトに別の EntryPoint を追加する方法です。
前回は Component Harness を使用したテストを書いてみましたが、 Component Harness はライブラリーとして配布することでより効果を得ることができます。しかし同じ EntryPoint からテスト用のクラスをインポート出来てしまうのは違和感があるため、 @hoge/lib
に対して @hoge/lib/testing
を追加してみます。
環境
Angular CLI: 9.0.2 Node: 12.16.0 OS: win32 x64 Angular: 9.0.1 ... animations, common, compiler, compiler-cli, core, forms ... language-service, platform-browser, platform-browser-dynamic ... router Ivy Workspace: Yes Package Version ------------------------------------------------------------ @angular-devkit/architect 0.900.2 @angular-devkit/build-angular 0.900.2 @angular-devkit/build-ng-packagr 0.900.2 @angular-devkit/build-optimizer 0.900.2 @angular-devkit/build-webpack 0.900.2 @angular-devkit/core 9.0.2 @angular-devkit/schematics 9.0.2 @angular/cdk 9.0.0 @angular/cli 9.0.2 @angular/material 9.0.0 @ngtools/webpack 9.0.2 @schematics/angular 9.0.2 @schematics/update 0.900.2 ng-packagr 9.0.0 rxjs 6.5.4 typescript 3.7.5 webpack 4.41.2
ライブラリープロジェクトに別のEntryPointを追加する
Angular CLI で作成したライブラリーに別の EntryPoint を追加する方法は ng-packagr が正式にサポートしています。
新しい EntryPoint となるディレクトリーを作成し、その中に package.json
または ng-package.json
と export する機能を含めた public_api.ts
を追加します。
my_package ├── src | ├── public_api.ts | └── *.ts ├── ng-package.json ├── package.json └── testing ├── src | ├── public_api.ts | └── *.ts └── package.json
my_package/testing/package.json
の中身は空の ngPackage
を含めるだけで良いようです。筆者は ng-package.json
を配置しています。こちらはライブラリープロジェクトのルートディレクトリーにも存在する設定ファイルと同じです。
{ "ngPackage": {} }
ただしこの方法で新しい EntryPoint を追加し、 my_package/src
の下にあるファイルを public_api.ts
に追加すると '...' is not under 'rootDir'
と怒られてビルドに失敗します。
違うディレクトリーに含まれるクラスを新しいEntryPointに含める
ソースコードを眺めてみたところ、どうやら rootDir
は entryFile (public_api.ts) のディレクトリーを指している様です。
// https://github.com/ng-packagr/ng-packagr/blob/v9.0.0/src/lib/ts/tsconfig.ts#L80 const basePath = path.dirname(entryPoint.entryFilePath); ... const overrideOptions: ng.CompilerOptions = { flatModuleId: entryPoint.moduleId, flatModuleOutFile: `${entryPoint.flatModuleFile}.js`, basePath, rootDir: basePath, lib: entryPoint.languageLevel ? entryPoint.languageLevel.map(lib => `lib.${lib}.d.ts`) : tsConfig.options.lib, declarationDir: basePath, sourceRoot: `ng://${entryPoint.moduleId}`, jsx, };
ならばいたしかたがないと、全て my_package/src/*
にファイルを含めてしまえば解決します。いたしかたがない。
my_package/src/testing_api.ts
を作成し、ここに @mypackage/testing
からエクスポートされるものを追加します。
my_package ├── src | ├── public_api.ts | ├── testing_api.ts | └── *.ts ├── ng-package.json ├── package.json └── testing └── ng-package.json
my_package/testing/ng-package.json
は my_package/src/testing_api.ts
を EntryFile に指定するだけで OK です。
{ "lib": { "entryFile": "../src/testing_api.ts" } }