跳转到内容
搜索文档

本地开发

最后更新 查看 MarkdownAgent 设置

D1 对本地开发提供完整支持,运行与 Cloudflare 全球部署相同版本的 D1。本地开发使用 Wrangler(Workers 的命令行接口)来管理本地开发会话和状态。

启动本地开发会话

本地开发会话会创建一个独立的、仅本地的环境,镜像 D1 在 production 中运行的环境,以便在部署到 production 之前测试 Worker 和 D1。

现有的 D1 绑定(binding) DB 在本地运行时可被 Worker 使用。

要启动本地开发会话:

  1. 确认您使用的是 wrangler v3.0+。

    wrangler --version
    ⛅️ wrangler 3.0.0
  2. 启动本地开发会话

    wrangler dev
    ------------------
    wrangler dev now uses local mode by default, powered by 🔥 Miniflare and 👷 workerd.
    To run an edge preview session for your Worker, use wrangler dev --remote
    Your worker has access to the following bindings:
    - D1 Databases:
    	- DB: test-db (c020574a-5623-407b-be0c-cd192bab9545)
     Starting local server...
    
    [mf:inf] Ready on http://127.0.0.1:8787/
    [b] open a browser, [d] open Devtools, [l] turn off local mode, [c] clear console, [x] to exit

在此示例中,Worker 可访问仅本地的 D1 数据库。您的 Wrangler 配置文件 中对应的 D1 绑定如下所示:

{
	"d1_databases": [
		{
			"binding": "DB",
			"database_name": "test-db",
			"database_id": "c020574a-5623-407b-be0c-cd192bab9545"
		}
	]
}
[[d1_databases]]
binding = "DB"
database_name = "test-db"
database_id = "c020574a-5623-407b-be0c-cd192bab9545"

请注意,wrangler dev 将本地数据与 production(远程)数据分开。默认情况下,本地会话无法访问 production 数据。要访问 production(远程)数据库,请在 D1 绑定配置中设置 "remote" : true。请参阅远程绑定文档 了解更多信息。针对远程数据库运行时所做的任何更改都无法撤销。

请参阅 wrangler dev 文档 了解如何配置本地开发会话。

使用 Pages 进行本地开发

使用 Cloudflare Pages 时,您只能通过在 Pages 项目根目录创建最小化的 Wrangler 配置文件 来针对_本地_ D1 数据库进行开发。这在创建 schema、填充数据或直接管理 D1 数据库时很有用,而无需添加到应用逻辑中。

您的 Wrangler 配置文件 应如下所示:

{
	// If you are only using Pages + D1, you only need the below in your Wrangler config file to interact with D1 locally.
	"d1_databases": [
		{
			"binding": "DB", // Should match preview_database_id
			"database_name": "YOUR_DATABASE_NAME",
			"database_id": "the-id-of-your-D1-database-goes-here", // wrangler d1 info YOUR_DATABASE_NAME
			"preview_database_id": "DB" // Required for Pages local development
		}
	]
}
[[d1_databases]]
binding = "DB"
database_name = "YOUR_DATABASE_NAME"
database_id = "the-id-of-your-D1-database-goes-here"
preview_database_id = "DB"

然后,您可以通过向 wrangler 传递 --local 标志,在本地开发流程中针对本地数据库执行查询和/或运行迁移:

wrangler d1 execute YOUR_DATABASE_NAME \
  --local --command "CREATE TABLE IF NOT EXISTS users ( user_id INTEGER PRIMARY KEY, email_address TEXT, created_at INTEGER, deleted INTEGER, settings TEXT);"

上述命令会在 D1 数据库的仅本地版本上执行查询。如果不带 --local 标志,命令将在 Cloudflare 网络上运行的远程 D1 数据库上执行。

持久化数据

使用 wrangler dev --persist-to=/path/to/file 将数据持久化到指定位置。这在团队协作(允许共享同一副本)、通过 CI/CD 部署(确保相同的初始状态)或在机器之间迁移时保留数据时很有用。

wrangler 2.x 用户必须使用 --persist 标志:早期版本的 wrangler 默认不持久化数据。

编程式测试

Miniflare

Miniflare 允许您使用与 production 相同的底层运行时和代码来模拟 Workers 和 D1 等资源。

您可以使用 Miniflare 的 D1 支持 创建用于测试的 D1 数据库:

{
	"d1_databases": [
		{
			"binding": "DB",
			"database_name": "test-db",
			"database_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
		}
	]
}
[[d1_databases]]
binding = "DB"
database_name = "test-db"
database_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
const mf = new Miniflare({
	d1Databases: {
		DB: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
	},
});

然后,您可以使用 getD1Database() 方法检索模拟数据库并对其运行查询,就像使用真实的 production D1 数据库一样:

const db = await mf.getD1Database("DB");

const stmt = db.prepare("SELECT name, age FROM users LIMIT 3");
const { results } = await stmt.run();

console.log(results);

unstable_dev

Wrangler 暴露了 unstable_dev(),允许您运行本地 HTTP 服务器来测试 Workers 和 D1。通过在 Wrangler 配置中设置 preview_database_id,针对本地数据库运行迁移

给定以下 Wrangler 配置:

{
	"d1_databases": [
		{
			"binding": "DB", // i.e. if you set this to "DB", it will be available in your Worker at `env.DB`
			"database_name": "your-database", // the name of your D1 database, set when created
			"database_id": "<UUID>", // The unique ID of your D1 database, returned when you create your database or run `
			"preview_database_id": "local-test-db" // A user-defined ID for your local test database.
		}
	]
}
[[d1_databases]]
binding = "DB"
database_name = "your-database"
database_id = "<UUID>"
preview_database_id = "local-test-db"

作为 CI/CD 设置的一部分,可通过向 wrangler 传递 --local 标志在本地运行迁移:

wrangler d1 migrations apply your-database --local

用法示例

以下示例展示如何使用 Wrangler 的 unstable_dev() API 来:

  • 针对由 preview_database_id 定义的本地测试数据库运行迁移。
  • 向 Worker 中定义的端点发起请求。此示例使用 /api/users/?limit=2
  • 验证返回结果是否匹配,包括 Response.status 和 API 返回的 JSON。
import { unstable_dev } from "wrangler";
import type { UnstableDevWorker } from "wrangler";

describe("Test D1 Worker endpoint", () => {
	let worker: UnstableDevWorker;

	beforeAll(async () => {
		// Optional: Run any migrations to set up your `--local` database
		// By default, this will default to the preview_database_id
		execSync(`NO_D1_WARNING=true wrangler d1 migrations apply db --local`);

		worker = await unstable_dev("src/index.ts", {
			experimental: { disableExperimentalWarning: true },
		});
	});

	afterAll(async () => {
		await worker.stop();
	});

	it("should return an array of users", async () => {
		// Our expected results
		const expectedResults = `{"results": [{"user_id": 1234, "email": "[email protected]"},{"user_id": 6789, "email": "[email protected]"}]}`;
		// Pass an optional URL to fetch to trigger any routing within your Worker
		const resp = await worker.fetch("/api/users/?limit=2");
		if (resp) {
			// https://jestjs.io/docs/expect#tobevalue
			expect(resp.status).toBe(200);
			const data = await resp.json();
			// https://jestjs.io/docs/expect#tomatchobjectobject
			expect(data).toMatchObject(expectedResults);
		}
	});
});

请参阅 unstable_dev() 文档,了解如何在测试中使用该 API。

相关资源

这篇文档对您有帮助吗?