ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

构建 Apache Airflow React 插件:模板工程到宿主集成的完整指南

构建 Apache Airflow React 插件:模板工程到宿主集成的完整指南 构建 Apache Airflow React 插件模板工程到宿主集成的完整指南【免费下载链接】airflowApache Airflow - A platform to programmatically author, schedule, and monitor workflows项目地址: https://gitcode.com/GitHub_Trending/ai/airflowApache Airflow 3 的 React 插件体系允许开发者以独立前端库的形式扩展 Core UI而本指南聚焦于仓库中 dev/react-plugin-tools/react_plugin_template/ai-agent-rules/airflow-plugin.md 所定义的六条集成铁律。读完本文你将掌握插件 bundle 的动态加载机制、共享依赖的外部化配置、UMD 全局名的约定、主题继承方式、公共 API 的调用边界以及从pnpm dev本地调试到fastapi_apps静态托管的完整落地路径。插件集成规则全景Airflow React 插件的本质是以 Vite 库模式构建出一个 UMD bundle交给 Airflow Core UI 在运行时动态加载。为了让插件与宿主应用Airflow UI共存而不互相破坏模板的 AI agent 规则文档 airflow-plugin.md 明确了六条约束它们是判断一个插件集成是否正确的验收标准保留库构建与src/main.tsx的默认组件导出Airflow 动态加载生成的 bundleReact、React DOM、React Router、JSX runtime 在vite.config.ts中保持 external与宿主共享禁止重复打包保持AirflowPlugin这个 UMD 全局名不变用 Chakra 组件与语义主题 token 构建 UI避免裸颜色值继承 Airflow 主题通过 Airflow 文档化的公共插件与 REST API 表面集成绝不触碰如 UI API 这类私有接口将 React 插件接口视为实验性特性升级与 Airflow 共享的外部依赖时必须验证兼容性。以下逐条展开并佐以仓库源码证据。规则一保留库构建与默认组件导出插件必须保留 Vite 的库构建方式以及 src/main.tsx 中的默认导出。因为 Airflow 宿主加载插件时就是通过动态import()拉取 bundle然后从模块上取回默认组件来渲染的宿主端实现见 airflow-core/src/airflow/ui/src/pages/ReactPlugin.tsxexport const loadPlugin ( reactApp: ReactAppResponse, importBundle: (url: string) Promiseunknown (url) import(/* vite-ignore */ url), ): Promise{ default: PluginComponentType } { (globalThis as Recordstring, unknown).AirflowPlugin undefined; return importBundle(new URL(reactApp.bundle_url, document.baseURI).href) .then(() { let pluginComponent (globalThis as Recordstring, unknown)[reactApp.name] as PluginComponentType | undefined; if (pluginComponent undefined) { pluginComponent (globalThis as Recordstring, unknown).AirflowPlugin as PluginComponentType; (globalThis as Recordstring, unknown)[reactApp.name] pluginComponent; } ...loadPlugin先将globalThis.AirflowPlugin复位为undefined避免上一次加载的残留再加载bundle_url最后按插件名全局变量 → AirflowPlugin 全局变量的顺序取回组件并要求它必须是函数。这意味着插件 bundle 的副作用UMD 全局注册必须在加载时同步完成main.tsx必须保持默认导出组件任何对入口的改动都可能让宿主的取回逻辑失效。模板 src/main.tsx 的默认组件形如export interface PluginComponentProps { // Add any props your plugin component needs } const PluginComponent (props: PluginComponentProps) { const system (globalThis.ChakraUISystem) ?? localSystem; return ( ChakraProvider value{system} ColorModeProvider HomePage / /ColorModeProvider /ChakraProvider ); }; export default PluginComponent;规则二外部化 React 生态依赖React、React DOM、React Router 与 JSX runtime 必须标记为 external。Airflow Core UI 本身就是 React 应用这些依赖由宿主以全局变量的形式提供如果插件再打包一份会出现两份 React 实例并存导致 hooks 状态错乱、路由失效。模板的 vite.config.ts 是这样配置的rollupOptions: { external: [react, react-dom, react-router-dom, react/jsx-runtime], output: { globals: { react: React, react-dom: ReactDOM, react-router-dom: ReactRouterDOM, react/jsx-runtime: ReactJSXRuntime, }, }, },external声明这些模块不打进 bundleglobals则告诉 Rollup 在 UMD 包装层把它们映射为宿主暴露的全局名。如果漏配globals产出的 UMD 包会引用无法解析的模块标识符运行时报Failed to resolve module specifier react如果漏配external则会出现经典报错Cannot read properties of null (reading useState)——这是 React 实例不匹配的典型信号。模板 README 的 Troubleshooting 一节 对这两类问题有直接对应。需要注意的是模板 package.json 中 React 仍保留在dependencies里react、react-dom均为^19.2.8保证本地开发与测试有可用实例external 只作用于生产库构建。规则三保持AirflowPluginUMD 全局名Vite 库模式的name字段决定 UMD bundle 注册到globalThis上的变量名。模板 vite.config.ts 固定为lib: { entry: resolve(src, main.tsx), fileName: main, formats: [umd], name: AirflowPlugin, },宿主 ReactPlugin.tsx 正是回退读取globalThis.AirflowPlugin作为组件来源。因此除非宿主集成方式同步变更插件不得随意改名。宿主加载后还会把组件按reactApp.name存回globalThis以隔离多个插件避免全局命名冲突——这是保持默认全局名与宿主侧去冲突的分工设计。规则四Chakra 组件与语义主题 tokenAirflow Core UI 基于 Chakra UI 构建并向外暴露了全局主题对象。模板通过 global.d.ts 声明declare global { var ChakraUISystem: SystemContext | undefined; }在 src/main.tsx 中优先取globalThis.ChakraUISystem取不到才回退到 src/theme.ts 定义的本地系统createSystem(defaultConfig)。这样生产环境自动继承 Airflow 宿主主题含深色/浅色模式本地开发也有可用兜底主题保证观感一致。UI 层则要求只用语义 token禁止裸颜色值。模板页面 src/pages/HomePage.tsx 是示范用法Box p{8} bgbg.subtle flexGrow{1} height100% VStack gap{8} aligncenter justifycenter flexGrow{1} height100% Heading size2xl textAligncenter colorfg Welcome to Your New React App! /Heading Text fontSizelg colorfg.muted This project was bootstrapped with the Airflow React Plugin tool. /Text Button onClick{() setColorMode(colorMode dark ? light : dark)} colorPalettebrand Toggle Theme /Button /VStack /Boxbg.subtle、fg、fg.muted、colorPalettebrand都是语义 token它们在不同主题明/暗下自动解析为合适的颜色。直接写color#123456会让插件在切换主题后显得突兀属于被规则明确禁止的写法。插件的明暗切换由 src/context/colorMode/ColorModeProvider.tsx 基于next-themes实现。规则五公共 API 集成边界插件对 Airflow 的数据访问必须走文档化的公共表面公共插件接口如fastapi_apps、flask_blueprints、appbuilder_views与 Public REST API。插件管理器 airflow-core/src/airflow/plugins_manager.py 中可以看到fastapi_apps的收集逻辑fastapi_apps: list[Any] [] ... fastapi_apps.extend({**app, team_name: plugin.team_name} for app in plugin.fastapi_apps)即插件声明的 FastAPI 应用会被合并进 Airflow 的 API 服务器。与之相对UI API/ui前缀下的接口是 Airflow Core UI 的私有实现细节不遵循 SemVer随时可能变更插件不应依赖。判断依据很简单凡是在 v2-rest-api-generated.yaml 中生成、由稳定 REST API 文档覆盖的端点才是公共面UI 内部数据接口则不在其列。ReactPlugin 宿主本身在渲染详情页时通过useDagServiceGetDagDetails、useAssetServiceGetAsset等 OpenAPI 生成客户端取数见 ReactPlugin.tsx插件应遵循同样的公共契约。规则六实验性接口与依赖升级兼容性React 插件机制是 Airflow 的实验性接口不提供 SemVer 级别的稳定性保证。因此规则文档要求升级与宿主共享的外部依赖React、React Router、Chakra 等时必须先验证与 Airflow 宿主版本的兼容性。模板 README.md 也提示vite.config.ts中标记为 external 的依赖就是与宿主共享的依赖应保持在兼容版本区间内避免 hooks、路由等基础能力因版本漂移而失效。宿主端加载机制与插件生命周期综合宿主角度的 ReactPlugin.tsx插件从加载到渲染的完整链路是Airflow API 返回ReactAppResponse含name、bundle_url元数据loadPlugin把globalThis.AirflowPlugin复位动态import()插件 bundleURL 基于document.baseURI解析bundle 执行时按 UMD 约定注册globalThis.AirflowPlugin或按插件名注册宿主校验取回的组件是函数后将其作为default渲染加载失败时回退到ErrorPageReactPlugin.tsx保证宿主 UI 不崩溃。宿主还会把路由参数dagId、runId、taskId、assetId、mapIndex解析后传给插件组件插件可以据此在详情页上下文中工作。注意宿主明确假设plugin manager 是可信的、bundle_url是安全的这从侧面说明插件 bundle 的托管与分发属于运维安全边界应由可信基础设施提供。从开发到部署的完整流程模板 README.md 给出的脚本package.json 中的定义如下命令作用pnpm dev启动开发服务器端口 5173--strictPort以 src/dev.tsx 为入口热更新调试pnpm build库模式生产构建产出dist/main.jsUMD、dist/main.d.ts与 source mappnpm build:types仅生成 TypeScript 声明文件tsc --p tsconfig.lib.jsonpnpm build:lib仅构建 JS 库pnpm test运行 Vitest 测试happy-dom 环境pnpm lint/pnpm format静态检查与代码格式化开发模式下模板使用本地默认 Chakra 主题渲染createSystem(defaultConfig)生产环境加载进 Airflow Core UI 后main.tsx会优先使用globalThis.ChakraUISystem继承宿主主题。因此本地预览与真实宿主中的观感可能略有差异属预期行为。构建完成后将dist目录内容托管起来即可。两种典型方式自有基础设施托管把dist/main.js放到任意静态服务器通过 Airflow 插件元数据指向 bundle URL托管在 Airflow 内在 Python 插件中通过fastapi_apps注册静态文件服务Airflow 侧收集逻辑见 plugins_manager.py让 API 服务器直接服务插件 bundle。集成自检清单把规则文档转成可执行的验收清单供插件提交前自查src/main.tsx保留默认组件导出未改动构建入口vite.config.ts中external至少包含react、react-dom、react-router-dom、react/jsx-runtime且globals映射完整库构建formats为[umd]、name保持AirflowPlugin全站 UI 只用 Chakra 组件与语义 tokenbg.subtle、fg、colorPalette等无裸色值数据访问全部走 Public REST API / 公共插件表面未依赖/ui私有接口升级 React、React Router、Chakra 等共享依赖后已在目标 Airflow 版本上验证 hooks、路由与主题行为。遵循这六条规则插件就能在 Airflow Core UI 中以最小耦合的方式加载、取数与渲染并在宿主升级时保持最大程度的可维护性。【免费下载链接】airflowApache Airflow - A platform to programmatically author, schedule, and monitor workflows项目地址: https://gitcode.com/GitHub_Trending/ai/airflow创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表