跳转到内容
搜索文档

微前端

最后更新 查看 MarkdownAgent 设置

微前端允许你将单个应用拆分为更小、可独立部署的单元,这些单元会渲染为一个统一的应用。不同团队可以使用不同技术来开发、测试和部署各个微前端。

在以下场景中适合使用微前端:

  • 让多个团队独立部署,无需协调发布
  • 逐步从单体架构迁移到分布式架构
  • 构建多框架应用(例如,在一个应用中同时使用 Astro、Remix 和 Next.js)

快速入门

创建微前端项目:

Deploy to Cloudflare

此模板会自动创建一个带有预配置路由逻辑的 router worker,并允许你配置指向已部署到 Cloudflare 账户的 Worker 的 Service bindings。该模板的代码可在 GitHub 上的 cloudflare/templates 获取。

工作原理

graph LR
    A[Browser Request] --> B[Router Worker]
    B -->|Service Binding| C[Microfrontend A]
    B -->|Service Binding| D[Microfrontend B]
    B -->|Service Binding| E[Microfrontend C]

router worker 会:

  1. 分析传入请求的路径
  2. 与已配置的路由进行匹配
  3. 通过 service binding 将请求转发到相应的微前端
  4. 重写 HTML、CSS 和 header,确保资源正确加载
  5. 将响应返回给浏览器

每个微前端可以是:

  • 完整的框架应用(Next.js、SvelteKit、Astro 等)
  • 使用 Workers Static Assets 的静态站点
  • 使用不同框架和技术构建

路由逻辑

router worker 使用 ROUTES 环境变量 来确定哪个微前端处理每条路径。路由按特异性匹配,路径更长的优先。

ROUTES 配置示例:

{
	"routes": [
		{ "path": "/app-a", "binding": "MICROFRONTEND_A", "preload": true },
		{ "path": "/app-b", "binding": "MICROFRONTEND_B", "preload": true },
		{ "path": "/", "binding": "MICROFRONTEND_HOME" }
	],
	"smoothTransitions": true
}

每条路由需要:

  • path:微前端的挂载路径(必须与其他路由不同)
  • bindingWrangler 配置文件 中 service binding 的名称
  • preload(可选):是否预取此微前端以加快导航

当请求 /app-a/dashboard 时,router 会:

  1. 将其匹配到 /app-a 路由
  2. 将请求转发到 MICROFRONTEND_A
  3. 剥离 /app-a 前缀,使微前端收到 /dashboard

router 包含支持以下模式的路径匹配逻辑:

// Static paths
{ "path": "/dashboard" }

// Dynamic parameters
{ "path": "/users/:id" }

// Wildcard matching (zero or more segments)
{ "path": "/docs/:path*" }

// Required segments (one or more segments)
{ "path": "/api/:path+" }

路径重写

router worker 使用 HTMLRewriter 自动重写 HTML 属性以包含挂载路径前缀,确保资源从正确位置加载。

当挂载在 /app-a 的微前端返回 HTML 时:

<link rel="stylesheet" href="/assets/styles.css" />
<script src="/assets/app.js"></script>
<img src="/static/logo.png" />

router 会将其重写为:

<link rel="stylesheet" href="/app-a/assets/styles.css" />
<script src="/app-a/assets/app.js"></script>
<img src="/app-a/static/logo.png" />

重写器会处理所有 HTML 元素中的以下属性:

  • hrefsrcposteractionsrcset
  • data-* 属性,如 data-srcdata-hrefdata-background
  • 框架特定属性,如 astro-component-url

router 仅重写以已配置资源前缀开头的路径,以避免破坏外部 URL:

// Default asset prefixes
const DEFAULT_ASSET_PREFIXES = [
	"/assets/",
	"/static/",
	"/build/",
	"/_astro/",
	"/fonts/",
];

大多数框架使用默认前缀即可。对于构建输出不同的框架(例如 Next.js 使用 /_next/),可以使用 ASSET_PREFIXES 环境变量 配置自定义前缀:

["/_next/", "/public/"]

资源处理

router 还会重写 CSS 文件,确保 url() 引用正常工作。当挂载在 /app-a 的微前端返回 CSS 时:

.hero {
	background: url(/assets/hero.jpg);
}

.icon {
	background: url("/static/icon.svg");
}

router 会将其重写为:

.hero {
	background: url(/app-a/assets/hero.jpg);
}

.icon {
	background: url("/app-a/static/icon.svg");
}

router 还会处理:

  • 重定向 header:重写 Location header 以包含挂载路径
  • Cookie 路径:更新 Set-Cookie header,将 cookie 限定在挂载路径范围内

路由预加载

当在静态挂载路由上设置 preload: true 时,router 会自动预加载这些路由以实现更快的导航。router 使用浏览器特定优化为每种浏览器提供最佳性能:

Chromium 浏览器(Chrome、Edge、Opera、Brave)

对于基于 Chromium 的浏览器,router 使用 Speculation Rules API——一种现代的、浏览器原生的预取机制:

  • <head> 元素注入 <script type="speculationrules">
  • 浏览器自动处理预取并进行最优优先级管理
  • 尊重用户偏好(省电模式、省流量模式)
  • 使用每文档内存缓存以加快访问
  • 不受 Cache-Control header 阻塞
  • 比基于 JavaScript 的 fetch 更高效

注入的 speculation rules 示例:

{
	"prefetch": [
		{
			"urls": ["/app1", "/app2", "/dashboard"]
		}
	]
}

平滑过渡

你可以使用 View Transitions API 在微前端之间启用平滑页面过渡。

要启用平滑过渡,在 ROUTES 配置中设置 "smoothTransitions": true

{
	"routes": [
		{ "path": "/app-a", "binding": "MICROFRONTEND_A" },
		{ "path": "/app-b", "binding": "MICROFRONTEND_B" }
	],
	"smoothTransitions": true
}

router 会自动向 HTML 响应注入 CSS:

@supports (view-transition-name: none) {
	::view-transition-old(root),
	::view-transition-new(root) {
		animation-duration: 0.3s;
		animation-timing-function: ease-in-out;
	}
	main {
		view-transition-name: main-content;
	}
	nav {
		view-transition-name: navigation;
	}
}

此功能仅在支持 View Transitions API 的浏览器中有效。不支持的浏览器将正常导航,无动画效果。

添加新微前端

在初始设置后向应用添加新微前端:

  1. 创建并部署新的微前端 Worker

    将新微前端部署为独立的 Worker。可以是框架应用(Next.js、Astro 等)或使用 Workers Static Assets 的静态站点。

  2. 在 router 的 Wrangler 配置文件中添加 service binding

    {
      "$schema": "./node_modules/wrangler/config-schema.json",
      "services": [
        {
          "binding": "MICROFRONTEND_C",
          "service": "my-new-microfrontend"
        }
      ]
    }
    [[services]]
    binding = "MICROFRONTEND_C"
    service = "my-new-microfrontend"
  3. 更新 ROUTES 环境变量

    将新路由添加到 ROUTES 配置:

    {
    	"routes": [
    		{ "path": "/app-a", "binding": "MICROFRONTEND_A", "preload": true },
    		{ "path": "/app-b", "binding": "MICROFRONTEND_B", "preload": true },
    		{ "path": "/app-c", "binding": "MICROFRONTEND_C", "preload": true },
    		{ "path": "/", "binding": "MICROFRONTEND_HOME" }
    	]
    }
  4. 重新部署 router worker

    npx wrangler deploy

新微前端现在可通过配置的路径访问(例如 /app-c)。

本地开发

在开发期间,你可以使用 Wrangler 的 service binding 支持在本地测试微前端架构。使用 wrangler dev 在本地运行 router Worker,然后在单独的终端中运行各个微前端。

如果只需要处理其中一个微前端,可以使用远程绑定(remote bindings) 远程运行其他微前端,无需访问源代码或运行本地开发服务器。

对于要在本地开发期间远程运行的每个微前端,在其 service binding 配置中设置 remote 标志:

{
"services": [
	{
	"binding": "<BINDING_NAME>",
	"service": "<WORKER_NAME>",
	"remote": true
	}
]
}
[[services]]
binding = "<BINDING_NAME>"
service = "<WORKER_NAME>"
remote = true

部署

每个微前端可以独立部署,无需重新部署 router 或其他微前端。这使团队能够:

  • 按自己的节奏部署更新
  • 回滚单个微前端而不影响其他微前端
  • 独立测试和发布功能

部署微前端 Worker 时,router 会通过 service binding 自动将请求路由到最新版本。除非添加新路由或更新 ROUTES 配置,否则无需更改 router。

要部署到生产环境,可以为 router worker 使用自定义域名,并配置 Workers Builds 以从 Git 仓库持续部署。

这篇文档对您有帮助吗?