@effect/platform
Node.js・Bun・ブラウザなど向けのインターフェイスを共通化する仕組み
というやつ
Introduction
Command
FileSystem
KeyValueStore
Path
PlatformLogger
Runtime
Terminal
GPT-4.icon
1. @effect/platformとは?
目的:
環境(Node, Deno, Bun, Browser)ごとに違うAPI(例: ファイル操作とか端末操作)を、共通インターフェースで扱えるようにするライブラリ。
イメージ:
例えば「ファイルを作る」という処理を、Node用、Deno用、Bun用、ブラウザ用にそれぞれ書き分けたくない。
→ @effect/platformを使えば、共通のコードを書いて、あとから実行環境ごとの実装を注入できる。
なるほどwwmrsekut.icon
わかるけど、頑張りすぎやろ
でもまあ、「後でruntimeを決める」というのは本来effect systemでやりたかったこと感があるから、
説得力を持たせるために、こういう機能を作りたくなっちゃうのはわかる
2. モジュール一覧
Stable(安定版)モジュール(普通に使ってOKなやつ)
table:table
モジュール 役割
:--- :---
Command コマンドラインとのやり取り(コマンド実行とか)
FileSystem ファイル操作(読み書きなど)
KeyValueStore キーと値を保存する簡易DBみたいなもの
Path パスをつなぐ・解釈する便利関数群
PlatformLogger ログをファイルに出力する
Runtime 例外処理・ログを含んだ「実行環境」を作る
Terminal 端末とのやり取り(表示・入力)
Unstable(開発中)モジュール(まだ仕様が変わるかも)
table:table
モジュール 役割
:--- :---
Http API HTTP APIを宣言的に定義する
Http Client HTTPリクエストを送るクライアント
Http Server HTTPリクエストを受けるサーバ
Socket ソケット通信
Worker ワーカースレッド(並列処理)
3. インストール方法
環境に合わせて
を入れる
Platform utilities for the browser
Shared utilities for Node.js
4. 実際のコード例
まず共通コードを書く:
code:ts
import { Path } from "@effect/platform"
import { Effect } from "effect"
const program = Effect.gen(function* () {
const path = yield* Path.Path
const mypath = path.join("tmp", "file.txt")
console.log(mypath)
})
→ このコードは「tmp/file.txt というパスを作る」だけ。
Node、Bun、Denoどれでも動かせる形になっています。
5. じゃあ、どの環境で動かすの?
ここからがポイント。
最後の実行環境に応じた「Context(コンテキスト)」を提供することで、動くようになります。
Node.jsの場合
Node.js向けContextを使う:
code:ts
import { NodeContext, NodeRuntime } from "@effect/platform-node"
NodeRuntime.runMain(
program.pipe(Effect.provide(NodeContext.layer))
)
これでNode用の「Pathサービス」や他のサービスが注入されるので、動きます。
(npx tsx index.tsなどで実行)
Bunの場合
同様に、Bun向けContextを使う:
code:ts
import { BunContext, BunRuntime } from "@effect/platform-bun"
BunRuntime.runMain(
program.pipe(Effect.provide(BunContext.layer))
)
(bun index.tsで実行)