mcpField
D
dev-server

dev-server

github.com/editframe开发1954 次安装2 周前更新
代码仓库

关于 dev-server

dev-server 是 Editframe 技能,介绍如何将 Vite、Next.js 及其他工具链连接到已安装的本地运行时,并说明编辑器路由、源码镜像和可选媒体路由。

主要功能

  1. 01Vite 与 Next.js 运行时适配器
  2. 02镜像选定的源码文件
  3. 03本地媒体路由与转码
  4. 04字幕生成与 URL 签名
  5. 05独立服务器或中间件配置

适用场景

  1. 01将 Vite 或 Next.js 应用接入 Editframe
  2. 02开发时同步合成文件
  3. 03提供本地媒体与字幕
  4. 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 技能。

评论

支持 Markdown