Slide 1

Slide 1 text

© 2023 LayerX Inc. 今日からできる!雑なコード生成のすすめ 2023-12-14 Nihonbashi.js #8 @izumin5210

Slide 2

Slide 2 text

© 2023 LayerX Inc. 2 ▸ Wantedly, Inc. (2018-04 - 2022-08) ▸ LayerX (2022-09-) ‐ バクラク事業部 Enabling Team ‐ Backend と Web Frontend 中心にやってます ▸ 最近のお気に入りパッケージは @bufbuild/protoplugin, @floating-ui/react 画像を入れてね whoami @izumin5210

Slide 3

Slide 3 text

© 2023 LayerX Inc. 3 コード生成とは はじめに - 雑なコード生成のすすめ

Slide 4

Slide 4 text

© 2023 LayerX Inc. 4 はじめに - 雑なコード生成のすすめ .proto .graphql pages/**/*.tsx *_pb.ts, *_connect.ts @bufbuild/protoc-gen-es @connectrpc/protoc-gen-connet-es *.ts $path.ts graphql-codegen など pathpida など APIスキーマをもとに クライアントが自動で作られる! 型もあって安心! ファイルパスをもとに URLビルダーが自動で作られる! 型もあって安心!

Slide 5

Slide 5 text

© 2023 LayerX Inc. 5 はじめに - 雑なコード生成のすすめ .proto .graphql pages/**/*.tsx *_pb.ts, *_connect.ts @bufbuild/protoc-gen-es @connectrpc/protoc-gen-connet-es *.ts $path.ts graphql-codegen など pathpida など APIスキーマをもとに クライアントが自動で作られる! 型もあって安心! ファイルパスをもとに URLビルダーが自動で作られる! 型もあって安心! 他で宣言されているルール(APIスキーマ, ファイル・ディレクトリ構成, etc.)に従って コードを書いている場合、それは自動で生成できる可能性がある TypeScript は型の表現力が高いので、 うまくコードを生成できれば高い生産性を得られる

Slide 6

Slide 6 text

© 2023 LayerX Inc. 6 コード生成は便利! …が、世の中にちょうどいいパッケージが存在しないことがある はじめに - 雑なコード生成のすすめ

Slide 7

Slide 7 text

© 2023 LayerX Inc. 7 コード生成は便利! …が、世の中にちょうどいいパッケージが存在しないことがある ↓ 雑でもいいので、痒いところを掻くためのコード生成を自作しよう! はじめに - 雑なコード生成のすすめ

Slide 8

Slide 8 text

目次 Agenda ▸ はじめに ▸ How to 雑コード生成 ▸ How to 何かをもとにコード生成 ‐ Protobuf ‐ GraphQL ‐ TypeScript

Slide 9

Slide 9 text

© 2023 LayerX Inc. 9 雑なコード生成の例 例: public/ 以下のファイル一覧を型に ▸ モチベーション ‐ Next.js 標準の typedRoutes だと未対応 ▸ じつは40行くらいで作れる。めっちゃ簡単。 ‐ 再帰的にディレクトリを見て、ファイル一覧を作る ‐ ファイル一覧の配列を | で join して union にする

Slide 10

Slide 10 text

© 2023 LayerX Inc. 10 雑なコード生成の例 雑ポイント①: コードは雑に文字列で組み立ててOK 専用のライブラリの使い方を覚える必要はない (ただし,変数名の衝突が気になるサイズのコードをつくるときは ts-poet 等に頼ると楽)

Slide 11

Slide 11 text

© 2023 LayerX Inc. 11 雑なコード生成の例 雑ポイント②: コードは雑に stdout or fs.writeFile でOK fs.writeFile してもいいけど shellscript でリダイレクトするほうが楽(かも)

Slide 12

Slide 12 text

© 2023 LayerX Inc. 12 雑なコード生成の例 雑ポイント③: ts-node 等で雑に直接実行してOK ビルドなどややこしいことは考えたくないが、TypeScriptで書きたい (上の例は package.json に記述している。shebang を書くパターンもナシではない。)

Slide 13

Slide 13 text

© 2023 LayerX Inc. 13 雑なコード生成の例 雑ポイント④: いきなり完璧を目指さない 1つのリポジトリや社内での利用に限れば、困ってからでもなんとかなる! 完璧にエッジケース対応したり汎用化したりはもっと後でいい

Slide 14

Slide 14 text

© 2023 LayerX Inc. 14 他のなんらかの宣言・定義(APIスキーマ, コード, etc.)をもとに コード生成したいケースは? 雑なコード生成のすすめ

Slide 15

Slide 15 text

© 2023 LayerX Inc. 15 何らかの宣言から TypeScript を生成する GraphQL をもとに TypeScript を吐く graphql パッケージで構造化されたスキーマを取得できるので、そこから必要な情報を集める (上のコードは InputObject から zod の Object schema を作ろうとしている)

Slide 16

Slide 16 text

© 2023 LayerX Inc. 16 何らかの宣言から TypeScript を生成する Protobuf をもとに TypeScript を吐く @bufbuild/protoplugin を使えば 構造化されたスキーマを元にコード生成ができる (左のコードは Protobuf の message から zod の Object schema を生成しようとしている)

Slide 17

Slide 17 text

© 2023 LayerX Inc. 17 何らかの宣言から TypeScript を生成する TypeScript をもとに TypeScript を吐く typescript や ts-morph でコードを AST に変換できる あとは目的のコードを見つけて処理するだけ (目的のコードの AST 上での表現は AST Explorer で調べる)

Slide 18

Slide 18 text

© 2023 LayerX Inc. 18 他のなんらかの宣言・定義(APIスキーマ, コード, etc.)をもとに コード生成したいケースは? ↓ 何らかの方法で Tree or リストが得られるので、 それを辿るだけ! はじめに - 雑なコード生成のすすめ

Slide 19

Slide 19 text

© 2023 LayerX Inc. 19 ▸ コード生成は、こだわりすぎなければ難しくないし手間もかからない ‐ 「雑に文字列 join して stdout に出すスクリプト」を「雑に ts-node で動かす」でもそんなに困らない ‐ スキーマやASTを読むのも、限られたユースケースなら複雑なフレームワークに乗る必要もない。 for … of でなんとかなる。 まとめ ▸ ほどよいライブラリが世の中にないときは、 さっと手を動かして雑な(ちょうどいい)コード生成をしてみませんか? ‐ その雑なツールがいつか public になればみんなハッピーかも ‐ 面白いネタがあったら教えてください or 公開まってます!