Skip to content

非公式本サイトは非公式の日本語ドキュメントであり、Cloudflare 公式サイトではありません。最新情報はdevelopers.cloudflare.comをご確認ください。

ローカル開発

最終更新 Markdown で表示Agent セットアップ

Worker のコードは、Cloudflare のネットワークへデプロイする前に、自分のマシン上でビルド、実行、テストできます。これを可能にしているのが Miniflare です。本番と同じランタイム workerd で Worker コードを実行するシミュレーターです。

既定では、Worker のバインディングは ローカルでシミュレートしたリソース に接続します。リモートバインディング を設定すると、本番の実リソースとやり取りできます。

基本概念

Worker の実行とバインディング

Workers を開発するときは、次の 2 つを区別して考えることが大切です。

ローカル開発サーバーを起動する

ローカル開発サーバーは、次のいずれかで起動できます。

  1. Cloudflare Workers CLI の Wrangler と、組み込みの wrangler dev コマンド。
npx wrangler dev
  1. ViteCloudflare Vite plugin
npx vite dev

Wrangler も Cloudflare Vite plugin も、内部では Miniflare を使います。どちらも Cloudflare チームが開発・保守しています。Wrangler と Vite の使い分けは、ガイド Wrangler と Vite の選択 を参照してください。

既定の動作

既定では、wrangler dev / vite devVite plugin 使用時)は次のように動きます。

  • Worker コードは自分のマシン上で実行されます。
  • Wrangler 設定 でバインドしたリソースは、すべてローカルでシミュレートされます。
  • ローカルの workerd ランタイムは TZ=UTC で動きます。Worker 内の DateIntl API は UTC を観測し、マシンのタイムゾーンに関係なく本番の Cloudflare ランタイムと揃います。

ローカル開発中のバインディング

バインディング は、Worker が各種 Cloudflare リソース(KV 名前空間R2 バケットD1 データベースQueuesDurable Objects など)とやり取りするためのインターフェイスです。Worker コードでは env オブジェクト経由でアクセスします(例: env.MY_KV)。

ローカル開発中も、デプロイ先と同じ API 呼び出し(例: env.MY_KV.put())でこれらのバインディングを使います。ローカルリソースは最初は空です。データの入れ方は ローカルデータの追加 を参照してください。

  • 既定では、バインディングは ローカルのリソースシミュレーション に接続します(AI バインディング を除く。AI モデルは常にリモートで動きます)。
  • この既定動作は上書きでき、バインディングごとに リモートバインディングリモートリソースへ接続 できます。Worker コードはローカルのまま、本番の実リソースに接続できます。
  • wrangler dev では、--local フラグ(wrangler dev --local)を付けると、すべての リモートバインディング を一時的に無効化し、ローカルリソースだけに接続できます。

リモートバインディング

リモートバインディング は、ローカル開発中にローカルシミュレーションではなく、デプロイ済みのリモートリソースへ接続するよう設定したバインディングです。リモートバインディングは WranglerCloudflare Vite plugin@cloudflare/vitest-plugin パッケージで使えます。バインディング定義で remote: true を設定します。

設定例

{
	"name": "my-worker",
	// Set this to today's date
	"compatibility_date": "2026-09-20",

	"r2_buckets": [
		{
			"bucket_name": "screenshots-bucket",
			"binding": "screenshots_bucket",
			"remote": true,
		},
	],
}
name = "my-worker"
# Set this to today's date
compatibility_date = "2026-09-20"

[[r2_buckets]]
bucket_name = "screenshots-bucket"
binding = "screenshots_bucket"
remote = true

リモートバインディングを設定しても、Worker の 実行はローカル のままです。変わるのは、バインディングが接続する先のリソースだけです。remote: true が付いたバインディングについて、Miniflare はその操作(例: env.MY_KV.put())をデプロイ済みリソースへ送ります。remote: true を明示していないバインディングは、既定どおりローカルシミュレーションを使います。

環境との組み合わせ

リモートバインディングは Workers Environments と相性が良いです。本番データを守るために、開発用またはステージング用の環境を作り、Wrangler 設定 で本番とは別のリソースを指定できます。

例:

{
	"name": "my-worker",
	// Set this to today's date
	"compatibility_date": "2026-09-20",

	"env": {
		"production": {
			"r2_buckets": [
				{
					"bucket_name": "screenshots-bucket",
					"binding": "screenshots_bucket",
				},
			],
		},
		"staging": {
			"r2_buckets": [
				{
					"bucket_name": "preview-screenshots-bucket",
					"binding": "screenshots_bucket",
					"remote": true,
				},
			],
		},
	},
}
name = "my-worker"
# Set this to today's date
compatibility_date = "2026-09-20"

[[env.production.r2_buckets]]
bucket_name = "screenshots-bucket"
binding = "screenshots_bucket"

[[env.staging.r2_buckets]]
bucket_name = "preview-screenshots-bucket"
binding = "screenshots_bucket"
remote = true

上記の設定で wrangler dev -e staging(または CLOUDFLARE_ENV=staging vite dev)を実行すると、次のようになります。

  • Worker コードはローカルで動きます
  • env.screenshots_bucket への呼び出しは、本番の screenshots-bucket ではなく preview-screenshots-bucket を使います。

リモート接続を推奨するバインディング

一部のバインディングは、リモート側へ接続する設定をおすすめします。Cloudflare のネットワークインフラに依存していたり、ローカルでは十分にシミュレートできない複雑なバックエンドを持つことが多いためです。

次のバインディングは、Wrangler 設定で remote: true を付けることを推奨します。

描画用の実際のヘッドレスブラウザとやり取りします。Browser Run のローカルシミュレーションは、現時点ではありません。

{
	"browser": {
		"binding": "MY_BROWSER",
		"remote": true
	},
}
[browser]
binding = "MY_BROWSER"
remote = true

Cloudflare のネットワーク上にデプロイされた実際の AI モデルで推論します。Workers AI のローカルシミュレーションは、現時点ではありません。

{
	"ai": {
		"binding": "AI",
		"remote": true
	},
}
[ai]
binding = "AI"
remote = true

本番の Vectorize インデックスに接続し、正確なベクトル検索と類似度演算を行います。Vectorize のローカルシミュレーションは、現時点ではありません。

{
	"vectorize": [
		{
			"binding": "MY_VECTORIZE_INDEX",
			"index_name": "my-prod-index",
			"remote": true
		}
	],
}
[[vectorize]]
binding = "MY_VECTORIZE_INDEX"
index_name = "my-prod-index"
remote = true

証明書の交換と検証が期待どおり動くことを確認します。mTLS バインディングのローカルシミュレーションは、現時点ではありません。

{
	"mtls_certificates": [
		{
			"binding": "MY_CLIENT_CERT_FETCHER",
			"certificate_id": "<YOUR_UPLOADED_CERT_ID>",
			"remote": true
			}
	]
}
[[mtls_certificates]]
binding = "MY_CLIENT_CERT_FETCHER"
certificate_id = "<YOUR_UPLOADED_CERT_ID>"
remote = true

Images API の高忠実度版へ接続し、変換が期待どおり動くことを確認します。Cloudflare Images のローカルシミュレーションは 一部の機能だけに限られます

{
	"images": {
		"binding": "IMAGES" ,
		"remote": true
	}
}
[images]
binding = "IMAGES"
remote = true

Workers for Platforms の利用者は、dispatch namespace バインディング定義で remote: true を設定できます。

{
	"dispatch_namespaces": [
		{
			"binding": "DISPATCH_NAMESPACE",
			"namespace": "testing",
			"remote":true
		}
	]
}
[[dispatch_namespaces]]
binding = "DISPATCH_NAMESPACE"
namespace = "testing"
remote = true

これにより、動的ディスパッチ Worker をローカルで動かしつつ、リモートの dispatch namespace バインディングへ接続できます。コアのディスパッチロジックの変更を、実際にデプロイされた ユーザー Worker に対してテストできます。

リモート非対応のバインディング

一部のバインディングは、ローカル開発中のリモート接続(remote: true)に対応していません。これらは常にローカルシミュレーション、またはローカルの値を使います。

次の非対応バインディング種別で Wrangler 設定に remote: true を指定すると、Cloudflare は エラーを出しますリモートバインディングの対応・非対応一覧 を参照してください。

  • Durable Objects: Durable Objects のリモート接続は将来対応する可能性がありますが、現時点では常にローカルで動きます。ただし、Durable Objects とリモートバインディングの併用は可能です。後述の Durable Objects と Workflows でリモートリソースを使う を参照してください。

  • Workflows: Workflows のリモート接続は将来対応する可能性がありますが、現時点ではローカルでのみ動きます。ただし、Workflows とリモートバインディングの併用は可能です。後述の Durable Objects と Workflows でリモートリソースを使う を参照してください。

  • 環境変数(vars: 環境変数は、ローカル開発とデプロイ先で別の値にすることを想定しています。ローカルでは(.dev.vars ファイルや Wrangler 設定など)簡単に設定できます。

  • Secrets: 環境変数と同様、セキュリティ上、ローカル開発とデプロイ先で値を分ける想定です。ローカルのシークレット管理には .dev.vars を使います。

  • 静的アセット: 開発中の静的アセットは、速度と変更の即時反映のため、常にローカルディスクから配信されます。

  • Version Metadata: Worker コードはローカルで動いているため、特定のデプロイ版に紐づくバージョンメタデータ(コミットハッシュ、バージョンタグなど)は該当せず、正確でもありません。

  • Analytics Engine: ローカル開発セッションは、通常、本番の Analytics Engine に直接データを送りません。

  • Hyperdrive: 現在対応作業中ですが、現時点では非対応です。

  • Rate Limiting: ローカル開発セッションは、通常、デプロイ済み Worker のレート制限を共有したり影響したりすべきではありません。レート制限のロジックはローカルシミュレーションでテストしてください。

Durable Objects と Workflows でリモートリソースを使う

Durable Object と Workflow のバインディングは、現時点ではリモートにできません。それでもローカル開発中に使い、リモートリソースとやり取りすることはできます。

おすすめのパターンは次の 2 つです。

  • ローカルの Durable Objects / Workflows とリモートバインディング:

    Wrangler 設定 でリモートバインディングを有効にすると、ローカルで動いている Durable Objects と Workflows からリモートリソースへアクセスできます。これらのバインディングはローカル実行のまま、ローカル開発中にリモートリソースとやり取りできます。

  • サービスバインディング経由でリモートの Durable Objects / Workflows にアクセスする:

    リモートの Durable Object または Workflow インスタンスとやり取りするには、それらを定義した Worker をデプロイします。次に、ローカルの Worker で、デプロイ済み Worker を指すリモートの サービスバインディング を設定します。 ローカルの Worker はリモートのデプロイ済み Worker とやり取りでき、その Worker がリモートの Durable Objects / Workflows と通信します。この方法では、リモートのサービスバインディングを通信路にし、デプロイ済み Worker をローカル開発中のリモートバインディングへのプロキシとして使えます。

重要な注意点

  • Cloudflare Access: Worker が Cloudflare Access で保護されている場合、Wrangler はリモートバインディングへ接続するときに Access で認証する必要があります。Access で保護された Worker に接続する を参照してください。

  • データの変更: リモート接続したバインディングへの操作(書き込み、削除、更新)は、対象の Cloudflare リソース(プレビューでも本番でも)の実データに影響します。

  • 課金: これらの接続経由でリモートの Cloudflare サービスとやり取りすると、そのサービスの通常の運用コストが発生します(KV 操作、R2 のストレージ / 操作、AI リクエスト、D1 の使用量など)。

  • ネットワーク遅延: リモート接続したバインディングの操作には、インターネット経由の通信があるため、ネットワーク遅延を見込んでください。

Access で保護された Worker に接続する

Worker が Cloudflare Access で保護されている場合、Wrangler はリモートバインディングへ接続するときに Access で認証する必要があります。Access が Worker 本体、アカウント内のすべての Worker、workers.dev ホスト名、カスタムドメイン、または Worker へルーティングする別のホスト名やパスを保護している場合も同じです。

Access への認証方法は次の 2 通りです。

  • 対話型ログイン(ローカル開発): ユーザーログインを受け付けるポリシーがある場合、Wrangler はブラウザで対話型の cloudflared access login フローを起動します。正しいアカウントにサインインしていれば、追加の設定は不要です。ポリシーがサービストークン認証だけを許可している場合、Wrangler は対話型フローをスキップし、サービストークンの認証情報が必要である旨のエラーを出します。

  • サービストークン(CI / 非対話環境): CI/CD パイプラインなど非対話の場面、またはポリシーがサービストークン認証だけを許可する場合、Wrangler はブラウザの対話型フローを起動できません。代わりに Cloudflare Access のサービストークン で認証する必要があります。非対話環境でサービストークンを設定しないと、Wrangler は対話型フローを試さずエラーを出します。

サービストークン認証の設定手順は次のとおりです。

  1. サービストークンを作成します。

    Cloudflare ダッシュボードで Zero Trust > Access > Service Auth > Service Tokens を開き、新しいトークンを作成します。詳細は Service tokens を参照してください。Client ID と Client Secret が表示されるので、安全な場所に保存してください。シークレットは再表示されません。

  2. Worker を保護している Access アプリケーションに、Service Auth ポリシーを追加します。

    Worker またはリモートバインディングに使うホスト名をすでに保護している 既存の Access アプリケーションを開き、次の内容の新しいポリシーを付けます。

    • Action: Service Auth
    • Include: 作成したサービストークン、または任意のサービストークンからのアクセスを許可する場合は "Any Access Service Token"
  3. 認証情報を Wrangler に渡します。

    Wrangler を実行する環境で、CLOUDFLARE_ACCESS_CLIENT_IDCLOUDFLARE_ACCESS_CLIENT_SECRETシステム環境変数 を設定します。

    export CLOUDFLARE_ACCESS_CLIENT_ID=<CLIENT_ID>
    export CLOUDFLARE_ACCESS_CLIENT_SECRET=<CLIENT_SECRET>

    CI では値をシークレットとして保存し、Wrangler を実行するステップの環境変数として渡します。

API

Wrangler は、Miniflare で Worker コードを実行するツール作者向けに、リモートバインディング接続を支えるプログラム用ユーティリティを提供します。

主な API は次のとおりです。

startRemoteProxySession

指定したバインディング集合のプロキシセッションを開始します。セッションの動作を制御するオプションを受け取れます。リモートバインディングへアクセスするための Cloudflare アカウント ID と API トークンを含む auth オプションもあります。

返すオブジェクトは次のとおりです。

  • ready Promise<void>: セッションの準備ができたときに解決します。
  • dispose () => Promise<void>: セッションを停止します。
  • updateBindings (bindings: StartDevWorkerInput['bindings']) => Promise<void>: セッションのバインディングを更新します。
  • remoteProxyConnectionString remoteProxyConnectionString: リモートバインディングアクセス用に Miniflare へ渡す文字列です。

unstable_convertConfigBindingsToStartWorkerBindings

unstable_readConfig ユーティリティは、設定ファイルに含まれるバインディング定義を含む Unstable_Config オブジェクトを返します。ただし、これらのバインディング定義は startRemoteProxySession と直接は互換ではありません。unstable_readConfig でバインディング宣言を読み、それを startRemoteProxySession へ渡したい場面は多いです。そのため Wrangler は unstable_convertConfigBindingsToStartWorkerBindings を公開しています。Unstable_Config オブジェクト内のバインディングを、startRemoteProxySession へ渡せる構造へ変換する単純なユーティリティです。

maybeStartOrUpdateRemoteProxySession

このラッパーは、プロキシセッションの管理を簡単にします。受け取る引数は次のとおりです。

  • 次のいずれかを含むオブジェクト
    • Wrangler 設定へのパスと、対象になりうる環境
    • Worker の名前と、その Worker が使うバインディング
  • 現在のプロキシセッションの詳細(ない場合は null、または省略可)
  • リモートプロキシセッションに使う認証データ(任意)

開始または更新した場合はプロキシセッションの詳細を返し、プロキシセッションが不要なら null を返します。

関数の動きは次のとおりです。

  • 第 1 引数をもとに、プロキシセッション用の入力引数を用意します。
  • 使うリモートバインディングがなく(既存のプロキシセッションもない)場合は null を返し、プロキシセッションが不要であることを示します。
  • 既存のプロキシセッションの詳細が渡されていれば、それに合わせてプロキシセッションを更新します。
  • それ以外の場合は、新しいプロキシセッションを開始します。
  • プロキシセッションの詳細を返します(あとで maybeStartOrUpdateRemoteProxySession の第 2 引数として渡せます)。

Miniflare と maybeStartOrUpdateRemoteProxySession を使い、リモートバインディング付きのローカル開発セッションを提供する基本例です。この例では、ハードコードした KV バインディングを 1 つ使います。

import { Miniflare, MiniflareOptions } from "miniflare";
import { maybeStartOrUpdateRemoteProxySession } from "wrangler";

let mf;

let remoteProxySessionDetails = null;

async function startOrUpdateDevSession() {
	remoteProxySessionDetails = await maybeStartOrUpdateRemoteProxySession(
		{
			bindings: {
				MY_KV: {
					type: "kv_namespace",
					id: "kv-id",
					remote: true,
				},
			},
		},
		remoteProxySessionDetails,
	);

	const miniflareOptions = {
		scriptPath: "./worker.js",
		kvNamespaces: {
			MY_KV: {
				id: "kv-id",
				remoteProxyConnectionString:
					remoteProxySessionDetails?.session.remoteProxyConnectionString,
			},
		},
	};

	if (!mf) {
		mf = new Miniflare(miniflareOptions);
	} else {
		mf.setOptions(miniflareOptions);
	}
}

// ... tool logic that invokes `startOrUpdateDevSession()` ...

// ... once the dev session is no longer needed run
// `remoteProxySessionDetails?.session.dispose()`
import { Miniflare, MiniflareOptions } from "miniflare";
import { maybeStartOrUpdateRemoteProxySession } from "wrangler";

let mf: Miniflare | null;

let remoteProxySessionDetails: Awaited<
	ReturnType<typeof maybeStartOrUpdateRemoteProxySession>
> | null = null;

async function startOrUpdateDevSession() {
	remoteProxySessionDetails = await maybeStartOrUpdateRemoteProxySession(
		{
			bindings: {
				MY_KV: {
					type: "kv_namespace",
					id: "kv-id",
					remote: true,
				},
			},
		},
		remoteProxySessionDetails,
	);

	const miniflareOptions: MiniflareOptions = {
		scriptPath: "./worker.js",
		kvNamespaces: {
			MY_KV: {
				id: "kv-id",
				remoteProxyConnectionString:
					remoteProxySessionDetails?.session.remoteProxyConnectionString,
			},
		},
	};

	if (!mf) {
		mf = new Miniflare(miniflareOptions);
	} else {
		mf.setOptions(miniflareOptions);
	}
}

// ... tool logic that invokes `startOrUpdateDevSession()` ...

// ... once the dev session is no longer needed run
// `remoteProxySessionDetails?.session.dispose()`

wrangler dev --remote(レガシー)

Miniflare ベースのローカル開発とは別に、Wrangler は wrangler dev --remote による完全リモートの開発モードも提供します。リモート開発は Vite plugin では 非対応 です。

npx wrangler dev --remote

リモート開発 中は、Worker コードはすべて Cloudflare インフラ上の一時的なプレビュー環境へアップロードされ、保存するたびに変更が自動でアップロードされます。

リモート開発では、すべてのバインディングが自動でリモートリソースへ接続します。ローカル開発と違い、バインディングをローカルシミュレーションに切り替えられません。常に Cloudflare ネットワーク上のデプロイ済みリソースを使います。

リモート開発を使う場面

  • ほとんどの開発作業では、ローカル開発に加え、必要なときだけ リモートバインディング を使うのが、いちばん効率的で生産的です。
  • Cloudflare のネットワークに強く依存し、ローカルでは十分にシミュレートできず、リモートバインディングでも検証しにくい機能や挙動を試す場合は、wrangler dev --remote が向いています。

注意点

  • 変更のたびにアップロード / デプロイが入るため、反復はローカル開発よりかなり遅くなります。

制限

役に立ちましたか?