SQLite
使用 sqlite({ url: "file:./data.db" }) 进行本地开发
EmDash 与 Astro 深度集成,提供完整的 CMS 体验。本页解释了关键的架构决策以及各个部分如何协同工作。
┌──────────────────────────────────────────────────────────────────┐│ Your Astro Site ││ ││ ┌────────────────────────────────────────────────────────────┐ ││ │ EmDash Integration │ ││ │ │ ││ │ ┌──────────────┐ ┌──────────────┐ ┌───────────────┐ │ ││ │ │ Content │ │ Admin │ │ Plugins │ │ ││ │ │ APIs │ │ Panel │ │ │ │ ││ │ └──────────────┘ └──────────────┘ └───────────────┘ │ ││ │ │ ││ │ ┌──────────────────────────────────────────────────────┐ │ ││ │ │ Data Layer │ │ ││ │ │ Database (D1/SQLite) + Storage (R2/S3) │ │ ││ │ └──────────────────────────────────────────────────────┘ │ ││ └────────────────────────────────────────────────────────────┘ ││ ││ ┌────────────────────────────────────────────────────────────┐ ││ │ Astro Framework │ ││ │ Live Collections · Middleware · Sessions │ ││ └────────────────────────────────────────────────────────────┘ │└──────────────────────────────────────────────────────────────────┘EmDash 作为 Astro 集成运行。它注入管理面板和 REST API 的路由,为实时集合提供内容加载器,并管理数据库迁移和存储连接。
与传统 CMS 在代码中定义架构不同,EmDash 将架构定义存储在数据库本身。两个系统表跟踪您的内容结构:
_emdash_collections — 集合元数据(slug、标签、功能)_emdash_fields — 每个集合的字段定义当您通过管理界面创建带有标题和价格字段的 “products” 集合时,EmDash 会:
_emdash_collections 和 _emdash_fieldsALTER TABLE 以创建具有适当列的 ec_products这种设计实现了:
每个集合都有自己的 SQLite 表,带有 ec_ 前缀:
-- Created when "posts" collection is addedCREATE TABLE ec_posts ( -- System columns (always present) id TEXT PRIMARY KEY, slug TEXT UNIQUE, status TEXT DEFAULT 'draft', -- draft, published, scheduled author_id TEXT, created_at TEXT DEFAULT (datetime('now')), updated_at TEXT DEFAULT (datetime('now')), published_at TEXT, deleted_at TEXT, -- Soft delete version INTEGER DEFAULT 1, -- Optimistic locking
-- Content columns (from your field definitions) title TEXT NOT NULL, content JSON, -- Portable Text excerpt TEXT);为什么使用按集合分表,而不是使用带有 JSON 的单一内容表?
EmDash 使用 Astro 6 的实时集合在运行时提供内容。内容更改立即可用,无需静态重新构建。
emdashLoader() 实现了 Astro 的 LiveLoader 接口:
import { defineLiveCollection } from "astro:content";import { emdashLoader } from "emdash/runtime";
export const collections = { _emdash: defineLiveCollection({ loader: emdashLoader() }),};使用提供的包装函数查询内容:
import { getEmDashCollection, getEmDashEntry } from "emdash";
// Get all published postsconst { entries: posts } = await getEmDashCollection("posts");
// Get draftsconst { entries: drafts } = await getEmDashCollection("posts", { status: "draft",});
// Get a single entry by slugconst { entry: post } = await getEmDashEntry("posts", "my-post-slug");EmDash 集成使用 Astro 的 injectRoute API 来添加管理和 API 路由:
| 路径模式 | 用途 |
|---|---|
/_emdash/admin/[...path] | 管理面板 SPA |
/_emdash/api/manifest | 管理清单(集合、插件) |
/_emdash/api/content/[collection] | 内容条目的 CRUD |
/_emdash/api/media/* | 媒体库操作 |
/_emdash/api/schema/* | 架构管理 |
/_emdash/api/settings | 站点设置 |
/_emdash/api/menus/* | 导航菜单 |
/_emdash/api/taxonomies/* | 分类、标签、自定义分类法 |
路由从 emdash 包注入——没有任何内容被复制到您的项目中。
EmDash 使用 Kysely 在所有支持的数据库中进行类型安全的 SQL 查询:
SQLite
使用 sqlite({ url: "file:./data.db" }) 进行本地开发
D1
使用 d1({ binding: "DB" }) 的 Cloudflare 无服务器 SQL
libSQL
使用 libsql({ url: "...", authToken: "..." }) 的远程 SQLite
数据库配置在 astro.config.mjs 中传递给集成:
import { defineConfig } from "astro/config";import emdash from "emdash/astro";import { sqlite } from "emdash/db";import { local } from "emdash/storage";
export default defineConfig({ integrations: [ emdash({ database: sqlite({ url: "file:./data.db" }), storage: local({ directory: "./uploads", baseUrl: "/_emdash/api/media/file", }), }), ],});媒体文件与数据库分开存储。EmDash 支持:
上传使用签名 URL 进行客户端到存储的直接上传,绕过 Workers 的请求体大小限制。
插件通过受 WordPress 启发的钩子系统扩展 EmDash:
content:beforeSave、content:afterSave、content:beforeDelete、content:afterDeletemedia:beforeUpload、media:afterUpload插件可以在两种模式下运行:
import { seoPlugin } from "@emdash-cms/plugin-seo";
emdash({ plugins: [seoPlugin({ maxTitleLength: 60 })],});典型的内容请求遵循以下路径:
getEmDashCollection() 调用 Astro 的 getLiveCollection() 3. 加载器执行 —
emdashLoader 通过 Kysely 查询相应的 ec_* 表 4. 数据返回 — 条目
被映射到 Astro 的条目格式,包含 id、slug 和 data 5. 页面渲染 — 您的
组件接收内容并渲染 HTML对于管理请求:
beforeCreate、afterUpdate 等 4. 数据库
更新 — Kysely 执行 SQL 5. 返回响应 — 向管理 SPA 返回 JSON 响应EmDash 在构建时生成虚拟模块以配置运行时:
| 模块 | 用途 |
|---|---|
virtual:emdash/config | 数据库和存储配置 |
virtual:emdash/dialect | 数据库方言工厂 |
virtual:emdash/plugin-admins | 插件管理界面的静态导入 |
这种方法确保打包工具能够正确解析和 tree-shake 插件代码。