Closed8

TypeScript環境 for Backend 2023ざっくりメモ

sugarsugar

Linter

ESLintに変わるものを探す(コードベースが肥大化した時にJSベースのlinterだとパフォーマンスが気になる)

Biome(Romeの後継 いつの間にかRomeの開発終わってた)

https://biomejs.dev/
https://zenn.dev/cybozu_frontend/articles/biome-eslint-compatibility

  • 最近流行り?のRust製
  • eslintにあるルールは大体ありそう
  • formatterも兼ねてる
  • bunでも使える
  • editorのplugin(vscode, intelliJ)もある
  • CLIベースのCIもサポート/GitHub Actionsとの連携も容易そう(Actionsがある)
  • JSXまで行けるのでmonorepo環境でFE/BEの共通フォーマッターとして良さそう
  • オールインワンツールとしてかなり優秀そうな印象を受けた

Formatter

dprint

https://dprint.dev/
https://zenn.dev/riya_amemiya/articles/3cfb09104804be

  • 最近流行り?のRust製
  • Markdown/TOMLとかのフォーマットもできる
  • Prettier等のWasmプラグインが用意されていて,既存のフォーマット方法の踏襲もできる
  • CLIベースのCIもサポート/GitHub Actionsとの連携も容易そう(Actionsがある)
  • Monorepoに特化している?
sugarsugar

JSランタイム

https://zenn.dev/mryhryki/articles/2023-09-24-javascript-runtimes

Deno

https://deno.com/
https://speakerdeck.com/yosuke_furukawa/deno-che-di-tao-lun-falseshi-falsesuraido

  • Rustベース
  • JS実行エンジンV8
  • Node.jsのセキュリティ周りの強化(ファイル、ネットワーク、および環境へのアクセスを明示的に有効にする必要がある)
  • ングルバイナリとして出力されデプロイしやすい
  • Fresh(Web Framework)やLume(Static Site Genarator)などの周辺エコシステムも充実
  • いつの間にかnpmモジュールの互換性ができてた

Bun

https://bun.sh/
https://zenn.dev/k41531/articles/dbedb88f06898a
https://www.ai-shift.co.jp/techblog/3113
https://speakerdeck.com/yosuke_furukawa/bun-first-impressions

  • Zigベース
  • JS実行エンジンJSC
  • スピード、バンドル、テスト、Node.jsパッケージとの互換性に重点を置いたオールインワンのランタイムとツールキット(バンドル、トランスパイラ、パッケージマネージャが全部含まれる)
  • Denoと同様、シングルバイナリで出てくる
  • JSXとTypeScriptをネイティブサポート(そのままトランスパイルする)

Package Manager

pnpm

https://zenn.dev/saggggo/articles/dbd739508ac212
https://speakerdeck.com/mh4gf/pnpm-workspaceshi-jian-nouhau

  • node_modules内でsymboliclinkを使用されており、ローカルPCの.pnpm_store内にハードリンクされる
  • ワークスペースモードが使用可能(ユーティリティ系のパッケージの管理に良さそう)

bun

https://azukiazusa.dev/blog/bun-workspace/
https://medium.com/@laiso/what-makes-bun-install-faster-than-npm-install-370ec673bf0b

  • Bunでもワークスペースモードが使えるらしい
  • node_modules内は実体らしい。キャッシュが挟まれていて早いのだとか(?)

Test

jest以外の選択肢を探す
というかそもそもJestって何で遅いんだ。。。

  • ts-jest で型も含めたトランスパイルを行っている
    というかトランスパイルが基本的に重いぽい(babel-jest使ってても)

https://jestjs.io/ja/docs/troubleshooting

Vitestは bun testどっちもjest互換
対応状況
https://github.com/oven-sh/bun/issues/1825

Vitest

https://speakerdeck.com/dojineko/vite-is-good?slide=15

bun test

複雑じゃないテストなら大体できそうな印象を受けた

TypeScript and JSX
Lifecycle hooks
Snapshot testing
UI & DOM testing
Watch mode with --watch
Script pre-loading with --preload

mockも問題なさそう
spyとかもいける
https://bun.sh/docs/test/mocks#spyon

sugarsugar

Cloudflare

Cloudflare Workers

I/O Wait大きめでもコストを抑えつつStreamingできるサーバーレス環境が欲しいので検討する
https://developers.cloudflare.com/workers/

  • price(2023/10/31より)
    • 基本的にCPU使用中にのみ課金されるようになった。
    • タイムアウトは30秒

https://blog.cloudflare.com/workers-pricing-scale-to-zero

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で課金されない理由:

https://blog.cloudflare.com/workers-optimization-reduces-your-bill/

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で完結する。

https://zenn.dev/moutend/articles/f9409d43724da5

  • IP制限はできない??
    • Cloudflare WAFでできそう
    • Zone Lockdown で特定の送信元IPアドレス以外は通信を許可しないようにできそう

セキュリティモデルを知る

https://developers.cloudflare.com/workers/learning/security-model/

D1について

https://developers.cloudflare.com/d1/

  • 11/16現在 Public Beta
  • sqliteベースでCDN Edgeに配置されるServerless DB

https://qiita.com/yoshii0110/items/d82c158c40bd146e7fcf

Cloudflare には AWS でいうところのリージョンの概念がなく、285以上のエッジがマスターとなります。
このマスターたちでマルチクラスター構成をとり、リレーショナルデータベースを作ることができるサービスなのです。

すごい(小並)

性能評価してる記事
書き込みが若干制約ありそうだけど、トリッキーな使い方しないならそんなに問題にはならなさそう
データが増えた時のReplicationの速度はもしかしたら問題が出てくる?
https://zenn.dev/chimame/scraps/0816765458c267

ホットスポットがしたら近くのCDN Edge上にマスターノードが移動する感じになるのかな?
書き込み自体は別のノードに行ってそれが各Read Replicaに同期される形になる?
→この辺がよくわからん

ちなみにD1以外の外部のDBも使える
https://developers.cloudflare.com/workers/databases/connecting-to-databases/

公式ではPostgresとの連携の記事がたくさんあった。
https://blog.cloudflare.com/ja-jp/relational-database-connectors-ja-jp/

最近TCP SocketのAPIにも対応したそうなので、Workersから直にPostgresを叩けるようになったらしい。
https://blog.cloudflare.com/workers-tcp-socket-api-connect-databases/

https://speakerdeck.com/hmatsu47/cloudflare-workers-connect-to-postgresql

ただegressの場合セキュリティ気にしないといけないので、tunnelingとかのサービスを検討する必要がある。

ちなみにCloudflare Tunnelというのがある。
cloudflared(damon)をプライベートなサーバにインストールしてトンネリングできる。
https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/

https://blog.cloudflare.com/cloudflare-tunnel-for-postgres/

Pub/Sub

非同期書き込みを実現したいのでtopicに突っ込みたい
11/16日現在private betaなので試せない
https://developers.cloudflare.com/pub-sub/

Queues

pubsubの大体でQueues使って別Workerで処理するようにするのはアリかなあ
11/16日現在open beta
https://developers.cloudflare.com/queues/

Maximum batch wait time 30 seconds
らしいのでd1に何かを書き込むとかは十分できそう。
https://developers.cloudflare.com/queues/platform/limits/

  • 事例

https://speakerdeck.com/nmemoto/chatgpt-apiwoshi-tutalinebotutodecloudflare-workerswoshi-u?slide=12
https://blog.shibayu36.org/entry/2023/05/25/173000

Miniflare

Workersの動作をシミュレートできるMiniflareというものがある
https://miniflare.dev/

  • 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.

https://github.com/cloudflare/workers-sdk/issues/3941

drizzleはd1のドライバーありそう。新しく追加された?
https://orm.drizzle.team/docs/quick-sqlite/d1

service bindingの時は少し工夫が必要そう
https://zenn.dev/naporin24690/articles/1229650b8fd991

sugarsugar

D1と戯れる

複数DBをbindingさせるのにdatabase idとかtomlに直打ちするしか方法ないんかな、、、

CIでのmigrationのためにtomlを排除したいというissueはある

https://github.com/cloudflare/workers-sdk/issues/3581

同じスキーマの複数DBのMigrationを行いたいとなった時に並列にいい感じに処理できる機構が欲しい。

issue作った。(別にスクリプト書けばできるが)
https://github.com/cloudflare/workers-sdk/issues/4471

tomlに書いてworkersにバインディングするのは良いんだけどTS側でinterfaceに定義が必要で、これもD1の数だけ必要で管理が。。。。。

このスクラップは1ヶ月前にクローズされました