微前端
微前端是一种架构模式,它将 Web 应用分解为更小的、独立开发和部署的应用,这些应用协同工作。
¥Microfrontends are an architectural pattern where a web application is decomposed into smaller, independently developed and deployed applications that work together.
Turborepo 通过集成的代理服务器,为在开发过程中本地运行垂直微前端(有时称为 "zones")提供了内置支持。代理协调多个应用并在它们之间路由流量。
¥Turborepo provides built-in support for running vertical microfrontends (sometimes called "zones") locally during development through an integrated proxy server. The proxy coordinates multiple applications and routes traffic between them.
假设你有一个包含多个前端应用的单体仓库:
¥Let's imagine you have a monorepo with multiple frontend applications:
在生产环境中,这些应用可以单独部署,然后使用反向代理或边缘路由组合在一起。但在开发过程中,你需要:
¥In production, these applications might be deployed separately and composed together using a reverse proxy or edge routing. But during development, you want to:
-
使用单个命令同时运行所有应用
¥Run all applications simultaneously with a single command
-
通过统一 URL(例如
http://localhost:3024)访问它们¥Access them through a unified URL (e.g.,
http://localhost:3024) -
根据路径模式将请求路由到正确的应用
¥Route requests to the correct application based on path patterns
-
支持热模块重载和 WebSocket 连接。
¥Support hot module reloading and WebSocket connections
-
避免端口冲突和手动协调
¥Avoid port conflicts and manual coordination
入门
¥Getting started
Turborepo 提供了一个内置代理服务器,可在开发过程中自动路由微前端应用之间的流量。代理读取 microfrontends.json 配置文件,并在你运行 turbo dev 时启动。
¥Turborepo provides a built-in proxy server that automatically routes traffic between your microfrontend applications during development. The proxy reads a microfrontends.json configuration file and starts when you run turbo dev.
你可以尝试使用 npx create-turbo@latest -e with-microfrontends 创建的 monorepo 执行以下说明。
¥You can try the following instructions with the monorepo created by npx create-turbo@latest -e with-microfrontends.
创建 microfrontends.json
¥Create microfrontends.json
在父应用中创建 microfrontends.json 文件。当没有其他应用匹配时,所有请求都将回退到此应用。
¥Create a microfrontends.json file in your parent application. This application is the one that all requests will fall through to when not matched by another application.
设置应用端口
¥Set application ports
接下来,使用 turbo get-mfe-port 命令在应用的开发脚本中设置端口。此命令在运行 turbo dev 时注入端口号:
¥Next, use the turbo get-mfe-port command to set the ports in your application's development scripts. This command injects the port number when running turbo dev:
处理基本路径
¥Handle base paths
如果你使用的是框架,请根据框架的要求设置基本路径。
¥If you're using a framework, set the base path according to the needs of the framework.
有关框架特定指南,请参阅 访问框架的微前端部分。
¥Visit the Microfrontends section of your framework for framework-specific guidance.
运行 turbo dev
¥Run turbo dev
运行 turbo dev 时,Turborepo 将执行以下操作:
¥When you run turbo dev, Turborepo will:
-
在配置的端口上启动代理服务器(默认端口:
3024)。¥Start the proxy server on the configured port (default:
3024) -
在任务中注入
TURBO_MFE_PORT环境变量以设置应用的端口¥Inject the
TURBO_MFE_PORTenvironment variable in tasks to set the applications' port -
为所有已配置的应用运行开发任务
¥Run development tasks for all configured applications
-
根据路径模式将传入请求路由到相应的应用
¥Route incoming requests based on path patterns to the appropriate application
现在,你可以通过 http://localhost:3024 访问所有微前端应用。
¥Now you can access all of your microfrontends applications at http://localhost:3024.
配置
¥Configuration
applications 对象中的每个应用都可以具有以下属性:
¥Each application in the applications object can have the following properties:
如果未提供,则使用应用密钥来匹配 package.json 中的名称。
¥If not provided, the application key is used to match the name in `package.json.
development.local
应用在本地运行的端口。
¥The port where the application runs locally.
如果省略端口,Turborepo 将根据应用名称生成一个确定的端口(介于 3000 到 8000 之间)。
¥If you omit the port, Turborepo will generate a deterministic port based on the application name (between 3000-8000).
development.fallback
可选地,在应用未在本地运行时,提供要代理的目标。这最常用于将请求路由到生产环境,从而使像 turbo dev --filter=web 这样仅运行部分应用的命令获得无缝体验。
¥Optionally provide a target to proxy to when an application is not running locally. This is most frequently used to route to production to make commands like turbo dev --filter=web that only run a subset of applications a seamless experience.
routing
应路由到此应用的路径组数组。如果没有提供路由,则应用将成为默认应用,捕获所有未匹配的路由。
¥An array of path groups that should route to this application. If no routing is provided, the application becomes the default application that catches all unmatched routes.
只能有一个应用没有 routing 配置。这是你的 "root" 应用,用于处理所有其他应用未匹配的路由。
¥Only one application can have no routing configuration. This is your "root" application that handles all routes not matched by other applications.
-
路径区分大小写:
/Blog和/blog是不同的路由¥Paths are case-sensitive:
/Blogand/blogare different routes -
尾部斜杠已规范化:
/home和/home/匹配同一路由¥Trailing slashes are normalized:
/homeand/home/match the same route
精确匹配
¥Exact matches
这些路径与原文完全一致。
¥These paths match exactly as written.
参数
¥Parameters
以 : 开头的段匹配任何单个路径段。例如,/blog/:slug 匹配 /blog/hello,但不匹配 /blog/hello/world。
¥Segments starting with : match any single path segment. For example, /blog/:slug matches /blog/hello but not /blog/hello/world.
通配符
¥Wildcards
以 * 结尾的参数匹配零个或多个路径段。例如,/docs/:path* 匹配 /docs、/docs/intro 和 /docs/api/reference。
¥Parameters ending with * match zero or more path segments. For example, /docs/:path* matches /docs, /docs/intro, and /docs/api/reference.
你还可以使用 + 修饰符来匹配一个或多个段(不包括空路径):
¥You can also use the + modifier to match one or more segments (excluding the empty path):
这匹配 /api/users 和 /api/users/123,但不匹配 /api 或 /api/。
¥This matches /api/users and /api/users/123, but not /api or /api/.
复杂的路由模式
¥Complex routing patterns
你可以使用嵌套参数定义复杂的路由:
¥You can define sophisticated routing with nested parameters:
分组标签
¥Group labels
将路由组织成逻辑组,以提高可维护性:
¥Organize routes into logical groups for better maintainability:
group 字段用于组织管理,不影响路由行为。
¥The group field is for organizational purposes and doesn't affect routing behavior.
packageName
可选地,使用工作区中 package.json 中的包名称。
¥Optionally use the name of the package from package.json in your workspace.
options.localProxyPort
可选地,使用 localProxyPort 选项更改代理端口
¥Optionally change the proxy port using the localProxyPort option
默认为 3024。
¥Defaults to 3024.
与生产环境集成
¥Integrating with production
Turborepo 微前端代理仅供本地使用。你如何实现和集成生产微前端取决于你的生产基础架构。但是,我们可以集成你的本地环境和生产环境,从而创建跨环境的无缝体验。
¥The Turborepo microfrontends proxy is meant for local usage only. How you implement and integrate your production microfrontends depends on your production infrastructure. However, we can integrate your local and production environments to create a seamless experience across environments.
首先,我们构建了 Turborepo 的本地代理,以便与 Vercel 的微前端集成。我们期待与任何有意集成 Vercel 的基础架构提供商合作。
¥To start, we've built Turborepo's local proxy to integrate with Vercel's microfrontends. We look forward to working with any infrastructure providers that would also like to integrate.
Vercel 上的微前端
¥Microfrontends on Vercel
Vercel 原生支持以下微前端:
¥Vercel has native support for microfrontends that provide:
-
增强性能的生产代理实现
¥Production proxy implementation with enhance performance
-
跨环境的回退 URL 支持。
¥Fallback URL support across environments
-
Vercel 工具栏集成
¥Vercel toolbar integration
-
功能标志支持
¥Feature flag support
-
资源前缀处理
¥Asset prefix handling
¥Learn more in Vercel's documentation.
迁移到 @vercel/microfrontends
¥Migrating to @vercel/microfrontends
如果在任何包中安装 @vercel/microfrontends 或将其添加到你的工作区,Turborepo 将自动使用它,而不是使用内置代理。这允许逐步迁移。
¥If you install @vercel/microfrontends in any package or add it to your workspace, Turborepo will automatically defer to it instead of using the built-in proxy. This allows for a gradual migration path.
你可以使用与 Turborepo 相同的 microfrontends.json 配置。Turborepo 的 microfrontends.json 架构是 Vercel 架构的子集,因此与 @vercel/microfrontends 兼容。
¥You can use the same microfrontends.json configuration as for Turborepo. Turborepo's microfrontends.json schema is a subset of Vercel's schema, so it is compatible with @vercel/microfrontends.
了解更多关于 @vercel/microfrontends 和 访问 npm 上的软件包 的信息。
¥To learn more about @vercel/microfrontends, visit the package on npm.
故障排除
¥Troubleshooting
端口已被占用
¥Port already in use
默认情况下,微前端代理将尝试使用端口 3024。如果你已将该端口用于其他用途,则可以使用 options.localProxyPort 更改 Turborepo 的端口。
¥By default, the microfrontends proxy will try to use port 3024. If you already use that port for a different purpose, you can change Turborepo's port using the options.localProxyPort.
缺少 CSS、图片或其他资源,或路由不匹配
¥Missing CSS, images, or other assets, or routes not matching
确保微前端在其 routing 配置 中匹配的路径包含资源的路由。检查你的网络选项卡,查找与预期匹配或不匹配的路径。
¥Ensure that the paths that the microfrontends matches for in its routing configuration include the routes for the assets. Check your network tab to find paths that are or aren't matching as expected.
跨应用的链接导致错误
¥Links across applications causing errors
如果使用单页应用 (SPA) 链接(例如 Next.js <Link> 组件)进行跨应用链接,则可能会导致错误。即使端口和域名保持不变,应用也是不同的。这意味着根据定义,该路由不是 "单页应用"。
¥If you use a Single-Page Application (SPA) link (like the Next.js <Link> component) to link across applications, this can result in errors. Even though the port and domain remain the same, the applications are different. This means the routing is, by definition, not a "single-page application".
访问代理端口未重定向
¥Visiting a proxied port does not redirect
你仍然可以直接访问代理端口。例如,如果 localhost:3000 被代理到 localhost:3042,你仍然可以在浏览器中访问 localhost:3000。
¥You are still be able to reach a proxied port directly. For example, if localhost:3000 is proxied to localhost:3042, you can still visit localhost:3000 in your browser.
如果你希望 localhost:3000 重定向到 localhost:3024,则必须在应用中手动设置。
¥If you would like for localhost:3000 to redirect to localhost:3024, you must set this up manually in your application.
应用无法启动
¥Applications not starting
验证以下内容:
¥Verify that:
-
packageName与你的实际包名匹配。¥The
packageNamematches your actual package name -
指定的
task存在于包的package.json中。¥The
taskspecified exists in the package'spackage.json -
每个应用的端口都可用。
¥Each application's port is available
-
所有依赖均已安装
¥All dependencies are installed
turbo get-mfe-port 无法正常工作
¥turbo get-mfe-port not working
如果在运行 turbo get-mfe-port 时遇到错误,请确保:
¥If you're getting an error when running turbo get-mfe-port, ensure that:
-
你正在从包目录(而非仓库根目录)运行命令。
¥You're running the command from a package directory (not the repository root)
-
包的
package.json中包含name字段。¥The package has a
namefield in itspackage.json -
某个包中存在
microfrontends.json文件¥A
microfrontends.jsonfile exists in one of the packages -
当前包列在
microfrontends.json的applications部分。¥The current package is listed in the
applicationssection ofmicrofrontends.json -
如果使用
--skip-infer,则还必须指定指向仓库根目录的--cwd:¥If using
--skip-infer, you must also specify--cwdpointing to your repository root:
完整示例
¥Complete example
以下是一个完整的电子商务平台微前端配置示例:
¥Here's a full example of a microfrontends configuration for an e-commerce platform:
使用此配置:
¥With this configuration:
-
web应用处理首页和任何未匹配的路由。¥The
webapp handles the homepage and any unmatched routes -
docs应用处理所有文档。¥The
docsapp handles all documentation -
blog应用处理博客文章和作者页面。¥The
blogapp handles blog posts and author pages -
shop应用处理电子商务功能。¥The
shopapp handles e-commerce functionality