この記事 Angular Advent Calendar 2019 9日目の記事です。
Schematicsでライブラリを作成してみました。
今回は作ったライブラリの説明と、作成を通して学んだことを共有させていただきたいと思います。
作ったもの
https://www.npmjs.com/package/ng-layer-generator です。
$ yarn add ng-layer-generator -D
して、
$ yarn ng-lg --name=task --type=usecase
とコマンドを叩くと、
task.usecase.spec.ts
とtask.usecase.ts
が作成されます。
作成されたファイルの中身はng g service task
で生成されたものとほぼ同じで、class名がTaskService
ではなくTaskUsecase
となっているということだけが異なります。
要は、serviceと同じ中身だけど、sercviceって名前がつかないファイルを作るためのライブラリです。
--name
オプションと、--type
オプションの他に、ファイルを作成するパスを指定できる--path
オプションと、multiple projects用にどのプロジェクトに作成するかを指定する--project
オプションがあります。
きっかけ
現在私が所属しているチームでは、Layered ArchitectureでAngularアプリケーションを開発しています。
引用元: https://speakerdeck.com/kasaharu/classi-angular-night-number-4?slide=26
このアーキテクチャではビジネスロジックを~Serviceに詰め込むのでもなく、NgRxを使ってeffectsに集中させるのでもなく、
usecase
- コンポーネントのイベントから呼ばれて、そのイベントに応じた処理をする
query
- storeから必要な情報を取得しコンポーネントに渡す
repository
- バックエンドのAPIやブラウザストレージなどアプリケーション外との橋渡しになる
といった具合に、各レイヤーがそれぞれ責務を持つ形になっています。
詳しくは @kasaharu さんのスライド https://speakerdeck.com/kasaharu/classi-angular-night-number-4 をご覧ください。
ng g service
or ng g class
このアーキテクチャで開発している時に、私的に面倒くさいなと感じたのは、ファイルの生成方法です。
UsecaseやQueryなどの各classは、コンポーネントや他のclassからDIされるので、@Injectableデコレーターをつける必要があります。
@Injectabeデコレーターが付いているclassは、お馴染みのng generate service
コマンドで作成できますが、~UsecaseService
という名前になるのも変だし、class名とファイル名を変更するのも面倒です。
ng generate class
コマンドも使えますが、DIのためにclassに@Injectableデコレーターを書き足したり、テストコードを変更するのもまた面倒です。
それなら、**~Service
という名前ではないけど、ファイルの中身はserviceと一緒のものを作ってくれるツールを作っちゃえばいいじゃん!!**と思ったのが、今回のきっかけです
schematics とは
schematicsとは、angular-devkitとして提供されているコード生成ライブラリです。
使い方はすでに、
https://qiita.com/hand-dot/items/db780a51915e2dc85221
https://qiita.com/puku0x/items/462a038133e7233dfaed
でとても分かりやすくまとめられているので、そちらをご覧ください。
今回のライブラリ作成に参考にさせていただきました。ありがとうございます
schematicsを使ってみた所感ですが、テストが簡単で最高でした。
it('specify name, type, path, and project', () => {
const runner = new SchematicTestRunner('schematics', collectionPath);
const options = {
name: 'sample',
type: 'usecase',
path: 'usecases',
project: 'app1'
};
const tree = runner.runSchematic('ng-layer-generator', options, Tree.empty());
const expectedOutput = [
'/projects/app1/src/app/usecases/sample.usecase.spec.ts',
'/projects/app1/src/app/usecases/sample.usecase.ts'
];
expect(tree.files).toEqual(expectedOutput);
});
こんな感じで、このoptionを渡してコマンドを実行すると、どんな名前のファイルが生成されたかテストすることができます。
ライブラリ作って学んだこと
ライブラリ開発中に、実際にローカルで開発しているAngularのアプリケーションで使ってみて挙動を確かめることが多々ありました。
しかし、ローカルで開発中のライブラリを別リポジトリで使ういい方法が思いつかなかった私は、ログを仕込んで確認するためだけにその都度バージョンを上げてnpmにpublishしていました。
そんな時に便利なのがnpm link
です。
開発しているライブラリのディレクトリで、
$ npm link
ライブラリを使用したいアプリケーションのディレクトリで、
$ npm link <ライブラリ名>
とすれば、アプリケーションからライブラリを使うことができます。
yarnを使ってる場合は、yarn link
とyarn link <ライブラリ名>
で大丈夫です。
今まで、OSSのライブラリを手元でどう動かして確認するか全く想像がつきませんでしたが、npm linkで手元で確認できそうです。
まとめ
まだこのライブラリは完成??したばかりでチームではまだ使ってないので、メンバーに使ってもらってブラッシュアップしていきたいです。
また、個人的にnpm linkを知ったのが大きくて、これからいろんなOSSをcloneして手元で動かしていきたいなと思ってます。
明日は@MasanobuAkibaさんです。
参考資料
https://speakerdeck.com/kasaharu/classi-angular-night-number-4
https://qiita.com/hand-dot/items/db780a51915e2dc85221
https://qiita.com/puku0x/items/462a038133e7233dfaed