web-dev-qa-db-ja.com

ライブラリプロジェクトに絶対インポートパスを設定するにはどうすればよいですか?

私は、ライブラリ自体とテストアプリケーション用の2つのプロジェクトを含むワークスペースを持つライブラリを持っています。

├── projects
    ├── midi-app
    └── midi-lib

ワークスペースtsconfig.jsonファイルで、いくつかの@appおよび@libパスを構成しました。

"paths": {
  "@app/*": ["projects/midi-app/src/app/*"],
  "@lib/*": ["projects/midi-lib/src/lib/*"],
  "midi-lib": [
    "dist/midi-lib"
  ],
  "midi-lib/*": [
    "dist/midi-lib/*"
  ]
}

上記のprojects/midi-lib/tsconfig.lib.jsonファイルを拡張したtsconfig.jsonファイルがあります。

"extends": "../../tsconfig.json",

以下を含むpublic-api.tsファイルがあります。

export * from './lib/midi-lib.module';

このライブラリをテストアプリケーションで問題なく使用できます。

しかし、Nodeモジュールとしてインポートされた別のワークスペースの別のクライアントアプリケーションで使用しようとすると、不明なパスCan't resolve '@lib/...'で多くのエラーが発生します。

ライブラリパスをクライアントアプリケーションで公開されるように表現するにはどうすればよいですか?または、ライブラリをパッケージ化するときにライブラリパスを変換する方法は?

余談ですが、拡張が逆に行われないのはなぜでしょうか。 tsconfig.jsonファイルを拡張するのがprojects/midi-lib/tsconfig.lib.jsonファイルではないのはなぜですか?

これが私がパッケージ化してライブラリを使用する方法です:

ライブラリをパッケージ化するには、親package.jsonファイルのスクリプト配列に次のスクリプトを追加します

"copy-license": "cp ./LICENSE.md ./dist/midi-lib",
"copy-readme": "cp ./README.md ./dist/midi-lib",
"copy-files": "npm run copy-license && npm run copy-readme",
"build-lib": "ng build midi-lib",
"npm-pack": "cd dist/midi-lib && npm pack",
"package": "npm run build-lib && npm run copy-files && npm run npm-pack",

次のコマンドを実行します:npm run package

次に、依存関係をインストールします

npm install ../midi-lib/dist/midi-lib/midi-lib-0.0.1.tgz

アプリケーションモジュールにモジュールをインポートします。app.module.tsファイルには次のものが含まれます。

import { MidiLibModule } from 'midi-lib';
@NgModule({
  imports: [
    MidiLibModule

最後にコンポーネントをテンプレートに挿入します

<midi-midi-lib></midi-midi-lib>

ライブラリがクライアントアプリケーションにインストールされると、.d.tsディレクトリに多数のnode_modules/midi-libファイルが含まれます。

├── bundles
├── esm2015
│   └── lib
│       ├── device
│       ├── keyboard
│       ├── model
│       │   ├── measure
│       │   └── note
│       │       ├── duration
│       │       └── pitch
│       ├── service
│       ├── sheet
│       ├── soundtrack
│       ├── store
│       ├── synth
│       └── upload
├── esm5
│   └── lib
│       ├── device
│       ├── keyboard
│       ├── model
│       │   ├── measure
│       │   └── note
│       │       ├── duration
│       │       └── pitch
│       ├── service
│       ├── sheet
│       ├── soundtrack
│       ├── store
│       ├── synth
│       └── upload
├── fesm2015
├── fesm5
└── lib
    ├── device
    ├── keyboard
    ├── model
    │   ├── measure
    │   └── note
    │       ├── duration
    │       └── pitch
    ├── service
    ├── sheet
    ├── soundtrack
    ├── store
    ├── synth
    └── upload

このようにlib/service/melody.service.d.tsファイル

import { SoundtrackStore } from '@lib/store/soundtrack-store';
import { ParseService } from '@lib/service/parse.service';
import { CommonService } from './common.service';
export declare class MelodyService {
    private soundtrackStore;
    private parseService;
    private commonService;
    constructor(soundtrackStore: SoundtrackStore, parseService: ParseService, commonService: CommonService);
    addSomeMelodies(): void;
    private addSoundtrack;
    private generateNotes;
}

ご覧のとおり、これには@libパスマッピングへの参照が含まれていますが、これはクライアントアプリケーションでは認識されていません。

回避策としてbaseUrlプロパティを使用することも試みましたが、ライブラリをインストールするときにこのbaseUrl値が指定されなかったため、それも役に立ちませんでした。

コマンドnpm run packageでライブラリをパッケージ化すると、pathsマッピングが解決されないのはなぜですか?

12
Stephane

他の人が言ったように、TypeScriptは@appおよび@libインポートを変更しません。ライブラリパッケージで絶対パスを使用しようとすると、同じ問題が発生しました。必要なのは、rollupまたは同様の何かを使用して公開用にライブラリを準備することです。

ロールアップにはさまざまなプラグインがあり、完全なセットアップについては説明しませんが、必要なのはインポートを書き換えるプラグインです。このプラグインはそれを行うように見えます: https://github.com/bitshiftza/rollup-plugin-ts-paths

残りのロールアップ構成では、おそらく rollup-plugin-node-resolve および rollup-plugin-commonjs と、TypeScriptを処理するプラグイン( rollup-plugin-TypeScript )、またはbabelを使用する新しいルートに進むことができます。ロールアップを使用してコードをパッケージ用に準備する(Reactなど)TypeScriptで記述された一般的なライブラリがあるため、いくつかのガイドを検索してください。

ハッピーコーディング。

0
Matthias