Techtouch Developers Blog

テックタッチ株式会社の開発チームによるテックブログです

Amplify + Nx (React + Typescript) で爆速で monorepo 環境を構築する

adventCalendar-day9

この記事はテックタッチアドベントカレンダー9 日目の記事です。 8 日目は ポエマー masaru 氏による 少女に何が起ったか ~少女が他人のウェブサーバー構成を知るまでにやったいくつかのこと、そしてその結末~ でした。 ただのポエムかと思いきやかなりコアなセキュリティの話だったのでとても勉強になりました。

テックタッチのフロントエンドエンジニアの taka です。

最近テックタッチでは、品質を更に向上させるため、また今後開発を加速できるようにするためにコードを一新しました。 そこで Amplify と Nx を使って monorepo の開発環境を構築したので、その手順を記しておこうと思います。 ざっくり言うとこれらを使うことで、

  • monorepo の環境を簡単にセットアップしたい
  • React + Typescript で開発したい
  • ESLint や Jest などの開発ツールを使いたい
  • Storybook を使いたい
  • PR 毎にアプリと Storybook をホスティングしたい
  • ビルドを最適化したい

といった願いを叶えることができます。 (その他もいろんな恩恵を受けています)

Amplify とは

詳しい説明は割愛しますが、公式曰く

  1. AWS のバックエンドを迅速に設定
  2. アプリケーションへ簡単に接続
  3. ウェブアプリケーションを 3 ステップでデプロイ

の利点があるとあります。

今回は 3 番の ウェブアプリケーションを 3 ステップでデプロイ の利点を活用していきます。

NetlifyVercel でも同じようなことができますが、テックタッチでは AWS を使っているので、その流れで Amplify を使うことにしました。 オープンソースであれば、Netlify や Vercel を使うのがいいかなと思います。後述しますが、Amplify の Preview 機能は private repository のみでしか利用できないというのもありますので。 ちなみに今回 monorepo 環境を構築しますが、 Amplify での monorepo 環境は今年の 6 月に対応されたそうです。

Nxとは

React + Typescript の monorepo 開発環境をコマンド一つで構築することができます。 ESLint や Jest 等の設定もされており、Next や Gatsby、Storybook 等の追加もコマンド一つで行うことができます。 本家曰く、

  • Google や Facebook、Microsoft のように開発できる
  • キャッシュを用いたインテリジェントなビルドシステムを使える
  • モダンなツールが使える

だそうです。 正直めちゃくちゃ便利です。 以前は yarn workspace を使って monorepo 環境を構築していたのですが、新規で package を作るのが大変だったり、手動で package 間の依存関係を定義してあげたりといろいろ手間だったのですが、これを使うことでそこらへんを勝手にやってくれるので、非常に開発効率が上がっています。 また大規模開発を前提としているので、キャッシュや依存関係を解析することによるビルドの最適化もすることができるので、そういった点でも多大な恩恵を受けています。

実際に動かしてみる

今回は todos app と components library (storybook) を作って、それらをビルド・ホスティングしてみます。 今回作った環境はGitHub - takakobem/amplify-nx-exampleにあげてあります。

環境の構築と todos app の作成

npx create-nx-workspace@latest

? Workspace name (e.g., org name)     myorg
? What to create in the new workspace react
? Application name                    todos
? Default stylesheet format           CSS

# nx serve で app を起動できます

今回は yarn を使いたいので

yarn install

components lib の作成と storybook のセットアップ

nx g @nrwl/react:lib components

yarn add @nrwl/storybook
yarn nx g storybook-configuration components

? Configure a cypress e2e app to run against the storybook instance? Yes
? Automatically generate story files for components declared in this library? Yes
? Automatically generate *.spec.ts files in the cypress e2e app generated by the cypress-configure schematic? Yes

# nx storybook components で storybook を起動できます

GitHub 等に push (1回目)

一旦 commit / push し、先に amplify の設定に入ります。 ここで先に amplify.yml を作成して commit してしまうと、なぜか amplify の subfolder の認識がうまくいかないので注意! おそらくバグだと思うので、今後は解消されるかもしれません。

Amplify の設定

AWS から Amplify Console に移動し、以下のように設定していきましょう。

  • 「Host your web app」を Get started f:id:techtouch:20201209002245p:plain f:id:techtouch:20201209002428p:plain

  • 利用するレポジトリを選択し f:id:techtouch:20201209002929p:plain

  • リポジトリ、ブランチの指定をし、「Connecting a monorepo? Pick a folder.」にチェックを入れ、app までのパスを指定して「次へ」 f:id:techtouch:20201209003300p:plain

  • そのまま「次へ」 f:id:techtouch:20201209103100p:plain

  • そのまま「保存してデプロイ」 f:id:techtouch:20201209103131p:plain

  • 設定が完了すると、こんな画面になります f:id:techtouch:20201209103256p:plain

同様に libs/components に対しても同じように設定しましょう。

amplify.yml の作成

以下に注意して作成しましょう

  • nx を使うと、ビルド成果物は /dist以下にできるので、 artifacts にはそこまでの相対パスを指定しましょう
  • base directory は appRoot になってしまっているため、yarn 経由で nx を実行することで、実質ワークスペース直下で実行できます。 yarn を経由せずに npx nx build todosのようにすると workspace.json が無いと言われてしまうので注意しましょう。
version: 1
applications:
    - appRoot: apps/todos
    frontend:
        phases:
        build:
            commands:
            - yarn install
            - yarn nx build todos
        artifacts:
        baseDirectory: ../../dist/apps/todos
        files:
            - '**/*'
        cache:
        paths:
            - node_modules/**/*
    - appRoot: libs/components
    frontend:
        phases:
        build:
            commands:
            - yarn install
            - yarn nx build-storybook components
        artifacts:
        baseDirectory: ../../dist/storybook/components
        files:
            - '**/*'
        cache:
        paths:
            - node_modules/**/*

GitHub 等に push (2回目)

push すると Amplify でビルドが回るはずです。 以下のようになっていれば成功です! 2 つともホスティングされているのが確認できますね。 f:id:techtouch:20201209104457p:plain

Previewの設定

PR 毎にビルドを回したいので、以下の設定をしましょう。 今回サンプルアプリを作っていて自分もハマったのですが、private repository でないと Preview 機能が動作しないので注意してください!

For apps with backend environments provisioned using the Amplify CLI, every pull request (private Git repositories only) spins up an ephemeral backend that is deleted when the PR is closed.


  • Amplify コンソールからアプリを選択し、Previews を開き「Enable previews」 f:id:techtouch:20201209103700p:plain

GitHub であれば「Install GitHub app to enable previews」と聞かれるので、説明に従って設定していきましょう。

  • ブランチを選択し、「Manage」から「Enabled」に変更する f:id:techtouch:20201209103957p:plain f:id:techtouch:20201209104010p:plain

これで Pull Request 毎に Status が表示されるようになり、そこからアプリを確認できるようになります。 f:id:techtouch:20201209104221p:plain

ただイケてないのが、現状 Status には一つしか表示されないということです。 つまり、今回 todos app と components の storybook を2つ設定しましたが、これらの両方を Status に表示することができません。。 ここは今後の Amplify に期待しましょう。(もしやり方知ってる方いたら教えていただけると幸いです)

余談

ちなみにテックタッチでは、Amplify コンソールから、ドメインアクセスコントロールも設定しています。 Basic 認証をかけられるので、テックタッチの人間のみが簡単に最新の状態を確認できるようになっています。 セキュリティ面で気になる人はこれらも設定しておくと良いでしょう。

実際に運用してみて

正直めちゃくちゃ便利です。 Status が一つしか表示できない問題があるのと、テックタッチのメインアプリは Chrome 拡張等なので、テックタッチでは現状は Storybook のみホスティングしています。 エンジニアはレビュー時に PR 毎の Storybook を確認したり、時にはデザイナーさんに PR の段階で Storybook を見てもらったりと、今までは手元でビルドをしなければいけなかったものが Amplify 上で確認できるので、とても効率よくなりました。

終わりに

今回は Amplify と Nx を組み合わせて monorepo の開発環境を構築してみました。 Amplify はホスティングだけに利用しましたが、他の AWS のサービスと簡単に接続できたり、Amplify DataStore を使って GraphQL でオフライン対応ができたりもするので、もっと使いこなしていきたいと思っています。 また個人的には Nx はとても好きなプロダクトで、他にも依存関係のグラフを表示できたりビルドキャッシュをクラウド経由で共有してローカルでのビルド時間を減らすことができたり、開発をサポートする機能が盛りだくさんです。テックタッチもこれからもっともっと成長していくので、大規模開発に耐えうる環境は意識して作っていこうと思っています!

明日は misty による「kong で grpc」です。乞うご期待。