用 qiankun Agent Skill 让编码 Agent 自动搭建微前端项目:安装、使用与源码解析
2026/9/21 23:16:44 网站建设 项目流程

用 qiankun Agent Skill 让编码 Agent 自动搭建微前端项目:安装、使用与源码解析

【免费下载链接】qiankun📦 🚀 Blazing fast, simple and complete solution for micro frontends.项目地址: https://gitcode.com/gh_mirrors/qi/qiankun

qiankun 在主仓库中随附了一套面向编码 Agent 的 Agent Skill 技能包(skills/qiankun/),采用 Agent Skills 格式,直接从主仓库分发。安装后,Claude Code、Cursor 等编码 Agent 可以按照官方约定为你创建主应用(host)与微应用(micro-app),或将现有 Vite 应用转换为微应用。读完本文,你将掌握该技能包的安装方式、内部结构与任务路由机制、Agent 执行任务时的完整操作链路,以及它与仓库源码(Vite/Webpack 打包插件、React/Vue UI 绑定)之间的对应关系,从而让 Agent 生成的工程与官方教程手工搭建的结果保持一致。

Agent Skill 是什么:qiankun 的 Agent 使用手册

Agent Skill 是一种把"使用手册"打包给编码 Agent 执行的格式:技能包内包含描述文件与参考文档,Agent 在收到自然语言任务后按其中的步骤、模板和约定执行。qiankun 将这一手册随主仓库一起维护,目录结构如下:

  • skills/qiankun/SKILL.md:技能入口,包含任务路由表、开始前必读的关键约定与包版本表;
  • skills/qiankun/references/create-micro-app.md:创建微应用 / 转换现有 Vite 应用的详细步骤与 React、Vue 入口模板;
  • skills/qiankun/references/create-main-app.md:创建主应用的三种加载方式与验证清单。

该技能与本文档站点同步维护:Agent 生成的项目结构与教程:手工构建主应用与微应用所搭建的完全一致——技能本质上是把这份"应用契约"交给 Agent 去执行。文档站点中还给出了对它的引用提示,见 Prepare a Vite micro-app 开头的说明:新建应用时可以直接交给 Agent 生成,而该篇指南则面向手工改造现有 React/Vue 应用的场景。

安装:一条命令将技能装进 Agent

在计划创建项目的目录中执行:

npx skills add umijs/qiankun

该命令从 qiankun 仓库拉取名为qiankun的技能,并安装到 Agent 的技能目录(例如.claude/skills/)。仓库始终分发与最新文档匹配的技能版本,因此不需要管理技能版本号——升级文档即升级技能。

安装后的技能包即为仓库中的 skills/qiankun 目录:SKILL.md通过 front-matter 声明技能名称与描述("Usage manual for building micro-frontend projects with qiankun 3.x"),Agent 会根据该描述判断何时启用此技能。

任务路由与开始前必读

SKILL.md的核心是一张任务路由表:Agent 只读取当前任务需要的参考文件,避免上下文浪费。

任务应读取的参考文件
创建微应用,或转换现有 Vite 应用create-micro-app.md
创建主应用create-main-app.md
其他主题(迁移、样式隔离、沙箱、调试)查阅本站点对应文档与examples/目录

开始任何创建任务前,Agent 需先确定四项信息(无法从上下文推断时才询问用户):

  1. 应用类型:主应用(host/shell)还是微应用(sub/micro app)。
  2. 应用名称:小写字母、数字、连字符。主应用注册时使用的名称必须与微应用在 classic 模式 fallback 中使用的名称完全一致(下文入口模板中的<app-name>)。
  3. 框架:React 或 Vue;TypeScript 或 JavaScript。参考文件中的模板为 TS,若选 JS 则去除类型标注。
  4. 开发端口:必须固定且每个应用唯一,因为主应用在entry中硬引用该端口。约定:主应用7099,微应用71017102……依次递增。

包版本也有明确约定——在 qiankun 3.0 稳定版发布前,核心包使用rc作为 dist-tag:

Dist-tag安装位置
qiankunrc主应用dependencies
@qiankunjs/react/@qiankunjs/vuerc主应用dependencies(可选 UI 绑定)
@qiankunjs/bundler-pluginrc微应用devDependencies

必须牢记的 Key Facts

技能中的"关键事实"是所有任务的前提,理解它们才能正确使用技能(也对应着仓库的实际行为):

  • Vite 微应用无需专用构建模式。qiankun 3 通过 ESM 沙箱原生加载<script type="module">,常规vite dev/vite build产物开箱即用。这一点在 Vite 插件源码 中有明确注释:不涉及 legacy/SystemJS 转换。
  • JS 沙箱默认开启;CSS 隔离按应用开启,通过styleIsolation: true启用运行时 CSS@scope
  • 微应用必须保持可独立运行:当未被 qiankun 加载(window.__POWERED_BY_QIANKUN__为 undefined)时,它直接渲染自身——这就是入口模板中的 standalone 分支。
  • 挂载了就必须卸载loadMicroApp返回的句柄在应用离开时必须调用.unmount()MicroApp组件绑定在组件卸载时自动完成。
  • Webpack 微应用使用@qiankunjs/bundler-plugin/webpack而非 Vite 插件,详见 @qiankunjs/bundler-plugin。

每个创建任务完成后,都必须按照所用参考文件末尾的验证清单检查结果;若 Agent 有浏览器工具,应自行验证而不是让用户代劳。

使用方式:一句自然语言启动

安装后,直接用自然语言向 Agent 描述目标即可,例如:

Use qiankun to create a React host app (port 7099) and a Vue micro-app (port 7101)

按照技能指示,Agent 会执行以下完整动作:

  1. 用 create-vite 创建项目(React 或 Vue、TS 或 JS);
  2. 微应用侧:安装@qiankunjs/bundler-plugin,在 Vite 插件中注册qiankun()并固定端口,将入口模块改写为导出bootstrap/mount/update/unmount生命周期,同时保留 standalone 分支;
  3. 主应用侧:安装qiankun及可选的 React/VueMicroApp组件绑定,并接入加载代码;
  4. 启动两个 dev server,验证微应用既能独立运行,也能被主应用挂载和卸载。

微应用创建与现有 Vite 应用转换

新建应用从第 1 步开始;转换现有 Vite 应用则直接跳到第 2 步——转换恰好就是第 2~4 步,不触碰其他任何文件(index.htmlApp组件、构建脚本均无需改动)。

第 1 步:脚手架(官方 Vite 脚手架,模板支持react-tsreactvue-tsvue):

pnpm create vite <app-name> --template react-ts

第 2 步:安装打包插件

pnpm add -D @qiankunjs/bundler-plugin@rc

第 3 步:编辑vite.config.ts——注册插件并固定端口:

import { defineConfig } from 'vite'; import react from '@vitejs/plugin-react'; // vue: @vitejs/plugin-vue import { qiankun } from '@qiankunjs/bundler-plugin/vite'; export default defineConfig({ plugins: [react(), qiankun()], server: { port: 7101, strictPort: true, }, });

Vite 插件无任何选项,其两个可观察行为都能在插件源码中找到印证:其一,通过config()钩子为 dev/preview server 注入Access-Control-Allow-Origin: *的 CORS 头,使主应用可以跨源拉取 HTML 入口与模块图;其二,通过transformIndexHtml钩子在构建产物中为入口模块脚本打上entry属性(与QiankunWebpackPlugin的约定一致),让加载器确定性地识别入口,而不是回退到最后一个 module script。注意导入路径必须为@qiankunjs/bundler-plugin/vite——该包的裸导入指向的是 Webpack 插件,bundler-plugin 文档 对此有明确的导出表。

第 4 步:改写入口导出生命周期。以 React 模板(src/main.tsx)为例(将两处<app-name>替换为实际注册名):

import React from 'react'; import ReactDOM from 'react-dom/client'; import App from './App'; import './index.css'; declare global { interface Window { __POWERED_BY_QIANKUN__?: boolean; [key: string]: unknown; } } let root: ReactDOM.Root | undefined; function render(props: { container?: Element } = {}) { // 被 qiankun 加载时,在宿主提供的 container 内解析 #root,而不是顶层 document const container = props.container?.querySelector('#root') ?? document.getElementById('root'); if (!container) return; root = ReactDOM.createRoot(container); root.render( <React.StrictMode> <App /> </React.StrictMode>, ); } export async function bootstrap() {} export async function mount(props: { container?: Element }) { render(props); } // 宿主在 props 变化时重新投递,响应变化时无需重挂载 export async function update(_props: Record<string, unknown>) {} export async function unmount(_props: { container?: Element }) { root?.unmount(); root = undefined; } if (window.__POWERED_BY_QIANKUN__) { // classic 模式 fallback:以注册名暴露生命周期到 window window['<app-name>'] = { bootstrap, mount, update, unmount }; } else { render(); }

Vue 模板(src/main.ts)采用同样的结构,差异在于使用createApp(App, { hostProps })并利用reactivehostProps承接宿主 props:mountupdate均通过Object.assign(hostProps, props)保持数据最新,容器选择器为#app

import { createApp, reactive } from 'vue'; import App from './App.vue'; import './style.css'; declare global { interface Window { __POWERED_BY_QIANKUN__?: boolean; [key: string]: unknown; } } let app: ReturnType<typeof createApp> | undefined; // 宿主投递的 props——mount 时播种,update 时保持最新 const hostProps = reactive<Record<string, unknown>>({}); function render(props: { container?: Element } = {}) { const container = props.container?.querySelector('#app') ?? document.getElementById('app'); if (!container) return; app = createApp(App, { hostProps }); app.mount(container); } export async function bootstrap() {} export async function mount(props: { container?: Element }) { Object.assign(hostProps, props); render(props); } export async function update(props: Record<string, unknown>) { Object.assign(hostProps, props); } export async function unmount(_props: { container?: Element }) { app?.unmount(); app = undefined; } if (window.__POWERED_BY_QIANKUN__) { window['<app-name>'] = { bootstrap, mount, update, unmount }; } else { render(); }

验证清单:在微应用内运行pnpm dev,打开http://localhost:7101,必须能独立渲染(走入口的非 qiankun 分支);若主应用已存在,则同时运行并确认微应用在宿主内正常挂载、控制台无报错(见 create-main-app.md 的验证清单)。

主应用创建与三种加载方式

第 1 步:搭建 shell 并安装依赖(以下假设 React + TS、端口7099):

pnpm create vite <main-app-name> --template react-ts pnpm add qiankun@rc @qiankunjs/react@rc # vue shell: @qiankunjs/vue@rc

同样在vite.config.ts中固定端口(server: { port: 7099, strictPort: true })。

第 2 步:选择一种加载方式(三选一):

MicroApp组件(React/Vue shell 推荐)——渲染时挂载、组件卸载时自动卸载,内置 loading/error 插槽;额外 props 会转发给微应用(变化时通过其update生命周期投递):

import { MicroApp } from '@qiankunjs/react'; // @qiankunjs/vue 中组件同名 export default function SubAppPage() { return <MicroApp name="<app-name>" entry="//localhost:7101" autoSetLoading />; }

该组件在仓库中的实现位于 MicroApp.tsx:它通过 effect 链串行化挂载/卸载(专门处理 StrictMode 下 mount 未完成即触发 cleanup 的竞态),以name定义挂载身份、用深度比较(useDeepCompare)判断 props 变化以触发updateMicroApp,并在 wrapper 内先渲染容器再渲染插槽,避免条件渲染的 loader/error 面板改变容器 XPath 导致 parcel 缓存分裂。

路由驱动注册(框架无关)——qiankun 在 URL 匹配activeRule时挂载/卸载应用,在 shell 入口只放一次:

import { registerMicroApps, start } from 'qiankun'; registerMicroApps([ { name: '<app-name>', entry: '//localhost:7101', container: '#micro-app-container', // shell 始终渲染的元素 activeRule: '/<app-name>', }, ]); start();

完全手动控制——loadMicroApp({ name, entry, container }, configuration)返回句柄,由你负责在应用离开时调用.unmount()

import { loadMicroApp } from 'qiankun'; const microApp = loadMicroApp({ name: '<app-name>', entry: '//localhost:7101', container: document.getElementById('micro-app-slot')!, }); // 不再需要时: await microApp.unmount();

这些 API 均可从 qiankun 包入口 中看到统一导出(loadMicroAppregisterMicroAppsstart相关 effect 等)。

第 3 步:按应用配置——loadMicroApp的第三参数、MicroApp组件的configurationprop、或registerMicroApps的逐应用字段均可用:sandbox默认为开启;添加styleIsolation: true@scope限定微应用 CSS。

验证清单:同时运行两个 dev server,打开主应用http://localhost:7099,导航到微应用路由——必须无报错地挂载进 shell;离开微应用路由——其 DOM 必须被移除(说明 unmount 确实执行了);微应用在http://localhost:7101仍可独立渲染。

覆盖范围与边界

当前版本的技能覆盖项目创建:搭建新的 host/micro-app 以及转换现有 Vite 应用。其余主题——迁移、样式隔离、问题排查——请查阅本站点对应章节:

  • 快速开始
  • 教程:构建主应用与微应用,其中 run-and-verify 步骤 还给出了常见首跑问题的排查表(容器空白查端口与entry、CORS 报错查 Vite 插件、找不到生命周期查导出、无法干净重挂载查 unmount 清理、端口漂移加strictPort: true
  • 准备一个 Vite 微应用
  • @qiankunjs/bundler-plugin(Vite/Webpack 双插件、packageName选项与入口约束)
  • 可参考的成品示例位于 examples 目录(React、Vue、vue-host、webpack、streaming、standalone-sandbox 等)

与源码对应的实现要点小结

技能中的步骤仓库中的对应实现
微应用安装qiankun()Vite 插件packages/bundler-plugin/src/vite/index.ts(CORS 头 +entry属性标记)
Webpack 微应用使用QiankunWebpackPluginpackages/bundler-plugin/src/webpack/index.ts(配置 window 全局 library 并标记入口脚本)
主应用使用MicroApp组件packages/ui-bindings/react/src/MicroApp.tsx(挂载/卸载串行化、props 更新、插槽渲染)
主应用调用loadMicroApp/registerMicroApps/startpackages/qiankun/src/index.ts(统一导出)

技能生成的项目与文档教程手工搭建的契约完全一致:主应用提供nameentry(指向微应用 HTML)、container(已存在的HTMLElement);微应用提供bootstrapmount(必要时含update)与unmount;qiankun 连接两侧并返回句柄,主应用负责在实例不再需要时调用句柄的unmount()。理解了这条契约,你就能审阅、修改甚至绕过 Agent 生成的项目——所有模板与步骤都沉淀在 skills/qiankun 目录中,随时可供查阅。

【免费下载链接】qiankun📦 🚀 Blazing fast, simple and complete solution for micro frontends.项目地址: https://gitcode.com/gh_mirrors/qi/qiankun

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询