关于 dev-server
dev-server 是 Editframe 技能,介绍如何将 Vite、Next.js 及其他工具链连接到已安装的本地运行时,并说明编辑器路由、源码镜像和可选媒体路由。
主要功能
- 01Vite 与 Next.js 运行时适配器
- 02镜像选定的源码文件
- 03本地媒体路由与转码
- 04字幕生成与 URL 签名
- 05独立服务器或中间件配置
适用场景
- 01将 Vite 或 Next.js 应用接入 Editframe
- 02开发时同步合成文件
- 03提供本地媒体与字幕
- 04为其他工具链添加 Editframe 路由
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ editframe/ skills --skill dev-server安装后在 Claude Code 中输入/dev-server确认已加载。
详细介绍
开发服务器
Editframe 框架适配器可将你的应用连接到已安装的 Editframe 运行时。该运行时是一个本地桥接程序,负责管理运行时状态、编译、媒体和导出。适配器会在浏览器编辑器中添加一个本地路由。它们还可以将选定的源文件同步到合成中。
请先从 https://editframe.com/agent 安装运行时。npm 包不会安装桥接程序。
根据你的框架选择一种集成方式。
- Vite(
npm create @editframe中的html/react模板):@editframe/vite-plugin。 - Next.js(
nextjs模板):@editframe/nextjs-plugin。 - 不使用桥接程序的本地媒体路由(JIT 转码、本地字幕、URL 签名):使用这些插件的
/advanced条目,或使用@editframe/dev-server。请参阅“高级:本地媒体路由”。
脚手架生成的项目已包含合适的适配器。请参阅 editframe-create 技能。
选择桥接程序
每个适配器都需要一个绝对路径的 projectRoot 和一个已安装的桥接程序。可通过以下选项之一选择桥接程序:
executable:桥接程序可执行文件的绝对路径。componentRoot:已验证组件安装位置的绝对路径。- 如果省略这两个选项,则使用
EDITFRAME_BRIDGE_PATH或EDITFRAME_COMPONENT_ROOT环境变量。
脚手架模板会省略这两个选项,因此会读取环境变量。裸桥接程序可执行文件可能还需要其编辑器和编译器资源(editorDir、compilerPack)。已验证的组件会提供这些资源。
editframe CLI 也以相同方式选择桥接程序,可通过 --bridge、--component 或相同的环境变量进行选择。请参阅 editframe-api 技能。
Vite 设置
// vite.config.ts
import path from "node:path";
import { defineConfig } from "vite";
import { vitePluginEditframe } from "@editframe/vite-plugin";
export default defineConfig({
plugins: [
vitePluginEditframe({
projectRoot: path.resolve(__dirname),
executable: "/absolute/editframe-bridge", // or componentRoot, or an environment variable
}),
],
});
在 Vite 开发服务器上打开 /@ef/workspace。插件会将请求重定向到经过身份验证的浏览器编辑器。你的应用永远不会收到编辑器持有者令牌。此路由仅接受本地请求。请勿将其作为托管编辑器端点公开。
旧版 root 和 cacheRoot 选项属于 @editframe/vite-plugin/advanced。默认插件不会启动媒体服务器。
Next.js 设置
将选项放在一个仅供服务器使用的文件中。这样,下面的两次调用就会使用相同的值。
// editframe.config.mjs
import path from "node:path";
import { fileURLToPath } from "node:url";
export default {
projectRoot: path.dirname(fileURLToPath(import.meta.url)),
executable: "/absolute/editframe-bridge", // or componentRoot, or an environment variable
};
// next.config.mjs
import { withEditframe } from "@editframe/nextjs-plugin";
import editframe from "./editframe.config.mjs";
export default withEditframe(editframe, {
// your Next.js config
});
添加一个 Node.js 路由处理程序。根据 app 目录的位置调整相对导入路径。
// src/app/api/editframe/workspace/route.ts
import { createEditframeRoute } from "@editframe/nextjs-plugin";
import editframe from "../../../../../editframe.config.mjs";
export const runtime = "nodejs";
export const GET = createEditframeRoute(editframe);
在 Next.js 开发服务器上打开 /@ef/workspace。重写规则会将请求转发到路由处理程序。处理程序会将请求重定向到经过身份验证的浏览器编辑器。有关本地请求和令牌的 Vite 规则在此处同样适用。
旧版 sidecar 选项属于 @editframe/nextjs-plugin/advanced。
同步应用源文件
将 source 设置为把选定的项目文件同步到合成中。桥接程序会编译这些文件并检查每个修订版本。
vitePluginEditframe({
projectRoot: path.resolve(__dirname),
source: {
kind: "html", // "source" for a React or TypeScript entry
entryPath: "src/composition.html",
files: ["src/composition.html"],
onError: console.error,
},
}),
- 使用相对于
projectRoot的路径。 - 在
files中列出合成中的每个文件。包括入口文件。 files最多接受 256 个不重复路径。- 适配器不会查找新文件或资源。请自行将每个新文件添加到
files中。 - 可选字段:
compositionId、title、width、height、durationMs和onCommitted。
即使运行时不可用,Vite 开发服务器也会启动并提供你的应用。此时,适配器会将同步错误发送给 onError 一次。如果省略 onError,Vite 会显示一条警告。在运行时可用之前,/@ef/workspace 会返回 503 和设置提示。
Next.js 适配器接受相同的 source 对象。请将其放在共享配置文件中。
高级:本地媒体路由
/advanced 条目会保留早期版本中的本地媒体服务器。对于不使用桥接程序而提供本地媒体的自定义设置,请使用这些条目。这些路由会在本地处理媒体,不调用云 API。URL 签名路由会使用 Editframe 云 API。
Vite
// vite.config.ts
import { defineConfig } from "vite";
import { vitePluginEditframe } from "@editframe/vite-plugin/advanced";
export default defineConfig({
plugins: [
vitePluginEditframe({
root: "./src", // base directory local `src=` paths resolve against
cacheRoot: "./cache", // directory for cached transcoded assets
}),
],
});
该插件会挂载到 Vite 自身的开发服务器上。按下方所示,将合成的 api-host 设置为浏览器的 Vite 源站。这样,请求就会使用同一源站。
Next.js
// next.config.mjs
import { withEditframe } from "@editframe/nextjs-plugin/advanced";
export default withEditframe(
{ root: "./src", cacheRoot: "./cache" },
{
// your Next.js config
},
);
这个 withEditframe 会在 next dev 旁边启动一个 sidecar HTTP 服务器,默认端口为 3099。使用 port 选项覆盖端口。它的 rewrites() 规则会将 Editframe 请求代理到 sidecar。将合成的 api-host 设置为浏览器所用的 Next.js 源站,而不是端口 3099。照常运行 next dev。
sidecar 不会在生产环境中启动。请改用真实媒体(云端渲染、上传的文件)进行部署。
其他工具链
对于没有 Vite 或 Next.js 集成的工具链,直接调用 @editframe/dev-server。从 @editframe/assets 获取六个资产处理函数。使用 createProdEfHandlers 提供 URL 签名处理程序。
import { createEditframeDevServer, createProdEfHandlers } from "@editframe/dev-server";
import {
generateTrack,
generateScrubTrack,
generateTrackFragmentIndex,
cacheImage,
findOrCreateCaptions,
md5FilePath,
} from "@editframe/assets";
import { Client, createURLToken } from "@editframe/api";
const server = createEditframeDevServer(
{ root: "./src", cacheRoot: "./cache" },
{ generateTrack, generateScrubTrack, generateTrackFragmentIndex, cacheImage, findOrCreateCaptions, md5FilePath },
createProdEfHandlers({
createURLToken,
getClient: () => new Client(process.env.EF_TOKEN, process.env.EF_HOST),
}),
);
server.listen(3001, () => console.log("Editframe dev server running on http://localhost:3001"));
如果你的工具链已经提供兼容 Connect 的中间件栈(Express、Connect 或自定义 Vite 集成),则改为使用相同的三个参数调用 createEditframeRouter(...)。使用 .use() 挂载返回结果。createEditframeDevServer 会将同一个路由器包装在独立的 http.Server 中,适用于自身没有中间件栈的工具链。
对于独立服务器,将应用服务器上的 /api/v1/* 和 /@ef-* 代理到 http://localhost:3001。将合成的 api-host 设置为应用在浏览器中的源站。这样媒体和签名请求就会使用同一源站。独立服务器不会配置应用代理或合成。
连接合成
在媒体子元素连接之前,在其祖先 ef-configuration 上设置 api-host。使用向浏览器公开媒体路由的源站。
<ef-configuration api-host="http://localhost:5173">
<ef-timegroup mode="contain">
<ef-video src="clip.mp4"></ef-video>
</ef-timegroup>
</ef-configuration>
对于 Next.js,使用 Next.js 源站,例如 http://localhost:3000。对于使用代理的独立集成,使用应用的源站。React 使用 <Configuration apiHost="…">,并设置相同的值。
当前元素会从 ef-configuration 读取 api-host。它们不会读取插件的 window.__EDITFRAME__.apiHost 值。api-host 为空时,会跳过对作者媒体 URL 的 JIT 发现。
路由的功能
连接服务器和合成后,元素会使用这些路由,无需你的代码直接发起请求。
- JIT 视频转码。 直接引用本地视频文件,例如
<ef-video src="clip.mp4">。开发服务器会在首次请求时将其转码为片段。后续请求会获取缓存的片段。 - 本地图片。 服务器会公开本地图片路由。
- 本地字幕。 将
ef-captions的captions-src设置为/api/v1/assets/captions?src=<path>。路径相对于root。服务器会对该文件运行whisper_timestamped并缓存字幕 JSON。请先在主机上安装whisper_timestamped。该路由只转录英语语音。 - 本地文件 API,其结构与生产环境的文件 API 相同。使用本地媒体编写的代码,在切换到上传文件或云端文件后仍可继续使用。
- URL 签名。
ef-configuration的默认signing-url会将请求转发到真正的 Editframe 云 API,以生成播放令牌。启动开发服务器前,设置EF_TOKEN环境变量。若要指向非默认 API 主机,请设置EF_HOST。
有关 ef-video、ef-image 和 ef-captions 如何使用本地媒体,请参阅 composition 技能。有关 EF_TOKEN 和 EF_HOST,请参阅 editframe-api 技能。
视觉回归测试
使用项目的浏览器截图测试检查合成输出。已发布的 Vite 插件不会导出仓库内部的 src/index.vitest.js 适配器。不要从已安装的包中导入该源代码路径。
调试日志
使用本地媒体路由时,请在启动开发服务器前设置 DEBUG。这会跟踪特定子系统。
DEBUG=ef:dev-server:jit npm run dev # transcode middleware
DEBUG=ef:dev-server:assets npm run dev # local image/caption serving
DEBUG=ef:dev-server:files npm run dev # local files API
DEBUG=ef:dev-server:sign-url npm run dev # URL signing
DEBUG=ef:dev-server:snapshot npm run dev # visual regression testing
发送反馈
向 Editframe 反馈问题和改进建议:
- 如果 Editframe 或此技能导致问题,请找到解决方法并继续任务。然后报告问题和解决方法。
- 如果你发现某项改进也能帮助其他任务,而不仅仅是当前任务,请发送建议。例如,建议更清晰的说明、补充示例、更好的默认设置或新功能。
每个不同的问题或建议分别发送一份报告。如果报告发送失败,请继续任务。
curl -sS https://editframe.com/api/v1/feedback \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $EDITFRAME_API_KEY" \
--data-binary @- <<'JSON'
{
"category": "bug",
"skill": "dev-server",
"summary": "One line that names the problem or the suggestion",
"details": "For a problem: steps, expected result, actual result, and errors. For a suggestion: the change and how it helps.",
"workaround": "The workaround that you used. Omit this field for a suggestion."
}
JSON
将 category 设为 bug、documentation、feature_request、performance 或 other。API 密钥为可选项。不提供密钥的报告将以匿名方式提交。请勿在报告中填写机密信息、API 密钥或个人数据。所有字段、限制和响应请参阅 editframe-api 技能。