TypeScript環境 for Backend 2023ざっくりメモ
Linter
ESLintに変わるものを探す(コードベースが肥大化した時にJSベースのlinterだとパフォーマンスが気になる)
Biome(Romeの後継 いつの間にかRomeの開発終わってた)
- 最近流行り?のRust製
- eslintにあるルールは大体ありそう
- formatterも兼ねてる
- bunでも使える
- editorのplugin(vscode, intelliJ)もある
- CLIベースのCIもサポート/GitHub Actionsとの連携も容易そう(Actionsがある)
- JSXまで行けるのでmonorepo環境でFE/BEの共通フォーマッターとして良さそう
- オールインワンツールとしてかなり優秀そうな印象を受けた
Formatter
dprint
- 最近流行り?のRust製
- Markdown/TOMLとかのフォーマットもできる
- Prettier等のWasmプラグインが用意されていて,既存のフォーマット方法の踏襲もできる
- CLIベースのCIもサポート/GitHub Actionsとの連携も容易そう(Actionsがある)
- Monorepoに特化している?
JSランタイム
Deno
- Rustベース
- JS実行エンジンV8
- Node.jsのセキュリティ周りの強化(ファイル、ネットワーク、および環境へのアクセスを明示的に有効にする必要がある)
- ングルバイナリとして出力されデプロイしやすい
- Fresh(Web Framework)やLume(Static Site Genarator)などの周辺エコシステムも充実
- いつの間にかnpmモジュールの互換性ができてた
Bun
- Zigベース
- JS実行エンジンJSC
- スピード、バンドル、テスト、Node.jsパッケージとの互換性に重点を置いたオールインワンのランタイムとツールキット(バンドル、トランスパイラ、パッケージマネージャが全部含まれる)
- Denoと同様、シングルバイナリで出てくる
- JSXとTypeScriptをネイティブサポート(そのままトランスパイルする)
Package Manager
pnpm
- node_modules内でsymboliclinkを使用されており、ローカルPCの.pnpm_store内にハードリンクされる
- ワークスペースモードが使用可能(ユーティリティ系のパッケージの管理に良さそう)
bun
- Bunでもワークスペースモードが使えるらしい
- node_modules内は実体らしい。キャッシュが挟まれていて早いのだとか(?)
Test
jest以外の選択肢を探す
というかそもそもJestって何で遅いんだ。。。
- ts-jest で型も含めたトランスパイルを行っている
というかトランスパイルが基本的に重いぽい(babel-jest使ってても)
Vitestは bun testどっちもjest互換
対応状況
Vitest
bun test
複雑じゃないテストなら大体できそうな印象を受けた
TypeScript and JSX
Lifecycle hooks
Snapshot testing
UI & DOM testing
Watch mode with --watch
Script pre-loading with --preload
mockも問題なさそう
spyとかもいける
Cloudflare
Cloudflare Workers
I/O Wait大きめでもコストを抑えつつStreamingできるサーバーレス環境が欲しいので検討する
- price(2023/10/31より)
- 基本的にCPU使用中にのみ課金されるようになった。
- タイムアウトは30秒
Large language models and generative AI models are incredibly powerful. But they aren’t always fast — asking a model to create an image, transcribe a segment of audio, or write a story often takes multiple seconds — far longer than a typical API response or database query that we expect to return in tens of milliseconds.
AI関連のサービスでのアウトバウンドでの待ち時間中にも課金される従来のServerless functionだとコストがかかるためこの辺りを見直したらしい。
And with Workers, you never have to pay extra for provisioned concurrency, pay a penalty for streaming responses, or incur egregious egress fees.
らしいのでStreamでもこれは適用されるらしい。
Streamで課金されない理由:
since the system now considers a Worker to be idle during response streaming, the response streaming time will no longer be billed.
レスポンスヘッダが返された時点で、idle状態と見なされるそう。
Workersのセキュリティについて
- 認証用のエンドポイントや、DBへの書き込み部分は別Workerに切り出したいなどの要件は達成できるのか
- Service Bindingで可能
- Workers間で普通に通信しようとするとPublicなネットワークを経由しないといけないが、Service BindingによってCloudflare Internalで完結する。
- IP制限はできない??
- Cloudflare WAFでできそう
- Zone Lockdown で特定の送信元IPアドレス以外は通信を許可しないようにできそう
セキュリティモデルを知る
D1について
- 11/16現在 Public Beta
- sqliteベースでCDN Edgeに配置されるServerless DB
Cloudflare には AWS でいうところのリージョンの概念がなく、285以上のエッジがマスターとなります。
このマスターたちでマルチクラスター構成をとり、リレーショナルデータベースを作ることができるサービスなのです。
すごい(小並)
性能評価してる記事
書き込みが若干制約ありそうだけど、トリッキーな使い方しないならそんなに問題にはならなさそう
データが増えた時のReplicationの速度はもしかしたら問題が出てくる?
ホットスポットがしたら近くのCDN Edge上にマスターノードが移動する感じになるのかな?
書き込み自体は別のノードに行ってそれが各Read Replicaに同期される形になる?
→この辺がよくわからん
ちなみにD1以外の外部のDBも使える
公式ではPostgresとの連携の記事がたくさんあった。
最近TCP SocketのAPIにも対応したそうなので、Workersから直にPostgresを叩けるようになったらしい。
ただegressの場合セキュリティ気にしないといけないので、tunnelingとかのサービスを検討する必要がある。
ちなみにCloudflare Tunnelというのがある。
cloudflared(damon)をプライベートなサーバにインストールしてトンネリングできる。
Pub/Sub
非同期書き込みを実現したいのでtopicに突っ込みたい
11/16日現在private betaなので試せない
Queues
pubsubの大体でQueues使って別Workerで処理するようにするのはアリかなあ
11/16日現在open beta
Maximum batch wait time 30 seconds
らしいのでd1に何かを書き込むとかは十分できそう。
https://developers.cloudflare.com/queues/platform/limits/
- 事例
Miniflare
Workersの動作をシミュレートできるMiniflareというものがある
- KV、Durable Objects、WebSocket、モジュールなど、ほとんどの Workers 機能をサポート
若干miniflareからD1扱おうとした際に対応していないライブラリとかがありそう?
↓bun:sqliteが使えなくてbetter-sqlite3は使える的なことが書いてあった。(内部的にはdrizzleがbetter-sqlite3を必要としているらしい)
Thank you for providing clarify. Upon further inspection, it seems the opportunity for improvement lies with Drizzle. Their driver for D1 requires better-sqlite3 today. I will get in contact with them.
drizzleはd1のドライバーありそう。新しく追加された?
service bindingの時は少し工夫が必要そう
- 事例集め
ORM
Workers使うのでそれにあったものを選定したい。
Code Generator
D1と戯れる
複数DBをbindingさせるのにdatabase idとかtomlに直打ちするしか方法ないんかな、、、
CIでのmigrationのためにtomlを排除したいというissueはある
同じスキーマの複数DBのMigrationを行いたいとなった時に並列にいい感じに処理できる機構が欲しい。
issue作った。(別にスクリプト書けばできるが)
tomlに書いてworkersにバインディングするのは良いんだけどTS側でinterfaceに定義が必要で、これもD1の数だけ必要で管理が。。。。。
Workersの制限について
- Simultaneous outgoing connections/requestについて
これは1workerの1request中に同時に何個のコネクションを張れるか