2021-12-07sanojimaruです。2021の8日目の記事です。新しいサービスをサクッと立ち上げる際に、シンプルなコマンド数回でデプロイできるamplifyは非常に強力な選択肢です。amplifyだけでは認証やユーザー情報のまわりで痒いところに手が届かないケースがあり、自前でサクッとサービスを立ち上げられるboilerplate的なものを作りました。frameworkとserverless-s3-syncなどのプラグインを組み合わせることで単一のパッケージで実現可能です。targetを変えてウィジェットのみIE11にも対応させる、など柔軟な対応を可能にしました。中身の概要は下記の通りです。下記のように落ち着きました。/services配下にディレクトリを設置します。サービス間で共有するものはroot直下に配置します。実際のテンプレートがこちらです。sts:AssumeRoleこのテンプレートは4つの引数を取ります。serverless-framework-deploy-pipelineこのテンプレートで構築する各サービスのprefixになるキーワード。基本的にはサービス名。prdgithubのリポジトリID。githubユーザー名/リポジトリ名。Stringデプロイするgithubリポジトリのブランチ名。production環境はmainなど。mainこのstackをdeployする簡単なスクリプトもあります。引数にstackの環境名(=DEPLOY_ENV)をセットします。引数を省略するとDEPLOY_ENVにdevがセットされます。Env=${ENV_VALUE}/env/.env.localを環境変数として読み込み、必要な値を設置しています。dev環境とprd環境のときでデプロイするブランチを分ける仕込みを忘れましたが投稿予定日が迫っているので何となく無視して進めます。FormationにCodePipelineのstackがデプロイされ、githubの該当リポジトリ/ブランチにpushするとデプロイされる一式が出来ました。CircleCIの方が楽じゃない?と思いましたが迷わず続けます。workspaceを使っています。workspace毎にserverless.ymlがあって、それぞれ独立したスタックをデプロイするようになっているので、buildspecはシンプルにworkspace分のdeployを実行するだけです。lintを入れるとよいです。Typescriptなので、共有できるパッケージはworkspaceで管理するようにします。workspaceはこのように書くとservices配下のディレクトリを走査し、発見したpackage.jsonをworkspaceとして認識します。[パッケージ名]などとしますが、このときワークスペース名はディレクトリ名ではなくpackage.jsonのnameを指定します。],}ワークスペースに共通するdevDependenciesはROOT/package.jsonに追加してワークスペース間で共有しています。[パッケージ名]とします。}}.eslintrc.jsなども共有したかったので、lintコマンドもROOT/package.jsonに書きました。両方のワークスペースを一気にlint&prettierしてくれるので便利です。},}frontendのデプロイ。SDK的にちょっとしたタグ配信ができるように静的ファイルを配信することを想定しています。frameworkはdeployの仕組みだけを使っているイメージです。静的ファイルのデプロイにはserverless-s3-syncプラグインを使い、distディレクトリ配下のファイルを任意のs3バケットにアップロードしています。s3バケットのpublic_readは推奨されていないので適宜CloudFrontなど追加してください。Retainbackendの方はnodeで動くのでtsconfig.jsonのcompilerOptions.targetはESNextにしていますが、frontendはブラウザが対象になるのでそれだと色々不都合があります。そのため、frontendの方はwebkpack+babelでIE11をターゲットにしたトランスパイルをします。]}typescriptをwebpackする場合、babel-loader単体だと型チェックまでしてくれないようです。typescriptをbabelでビルドしつつlintや型チェックもやりたいを参考にts-loaderを追加します。rules.N.useのbabel-loaderの下にts-loaderを追記しています。},};フロントエンド側のpackage.jsonはこんな感じです。deployでデプロイします。build:devとやると、dist/ディレクトリ以下にjsファイルが生成されていると思います。このファイルがそのままS3に配置され、インターネットに公開されるイメージです。今回のfrontendはjavascriptタグを想定していて、外部から呼び出すためにブラウザのwindowオブジェクトにプロパティを生やしたい感じでした。tsconfigには継承機能があるので、DOMライブラリを読み込んでおきます。}}eslintとtsconfigROOT直下に置いてあるものを両方のワークスペースで利用します。tsconfigは継承した上で一部の値をオーバーライドしています。変わったことはしていません。"**/*.test.ts"]}ROOT直下のpackage.jsonファイルにこのようなscriptを書くことで、ワークスペースを横断してlintや型チェックができます。huskyでgit-hookに引っ掛けています。-cになっているのは、git-hookの実行時にパスが通っておらずtsconfigなども無視されるので都合が悪いからです。pushすれば、backendとfrontendが自動的にデプロイされるサーバーレスな一式ができましました。codepipelineも含めて全てが従量課金のインフラなので非常にヘルシーにサービスが作れてよいですね。Typescriptの開発環境をちゃんと作るのも初体験ですが、型安全の恩恵に加えて、10数年前にeclipse+javaでエンジニアキャリアをスタートした私としてはvscodeによる補完バリバリな開発体験はクセになりそうです。Supershipではプロダクト開発やサービス開発に関わる人を絶賛募集しております。Typescript+Next.js+Nest.jsのようなモダンなnode開発プロジェクトもありますので、ご興味がある方は以下リンクよりご確認ください。採用サイト是非ともよろしくお願いします。