LoginSignup
15
8

More than 3 years have passed since last update.

Schematics で Layered Architectureを実現させるライブラリを作って公開してみた話

Last updated at Posted at 2019-12-08

この記事 Angular Advent Calendar 2019 9日目の記事です。

Schematicsでライブラリを作成してみました。
今回は作ったライブラリの説明と、作成を通して学んだことを共有させていただきたいと思います。

作ったもの

https://www.npmjs.com/package/ng-layer-generator です。
ng-layer-gen.gif

$ yarn add ng-layer-generator -D

して、

$ yarn ng-lg --name=task --type=usecase

とコマンドを叩くと、
task.usecase.spec.tstask.usecase.tsが作成されます。
作成されたファイルの中身はng g service taskで生成されたものとほぼ同じで、class名がTaskServiceではなくTaskUsecaseとなっているということだけが異なります。

要は、serviceと同じ中身だけど、sercviceって名前がつかないファイルを作るためのライブラリです。

--nameオプションと、--typeオプションの他に、ファイルを作成するパスを指定できる--pathオプションと、multiple projects用にどのプロジェクトに作成するかを指定する--projectオプションがあります。

きっかけ

現在私が所属しているチームでは、Layered ArchitectureでAngularアプリケーションを開発しています。
スクリーンショット 2019-12-09 0.01.48.png
引用元: 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

でとても分かりやすくまとめられているので、そちらをご覧ください。
今回のライブラリ作成に参考にさせていただきました。ありがとうございます:bow:

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していました。

↓ 無駄にバージョンが上がって行く様子
スクリーンショット 2019-12-09 4.20.20.png

そんな時に便利なのがnpm linkです。
開発しているライブラリのディレクトリで、

$ npm link

ライブラリを使用したいアプリケーションのディレクトリで、

$ npm link <ライブラリ名>

とすれば、アプリケーションからライブラリを使うことができます。

yarnを使ってる場合は、yarn linkyarn 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

15
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
8