了解为什么 Metro 是 React Native 中通用打包的未来以及它如何使开发者受益。
Metro 是 Expo 和 React Native 的官方打包器。它是 Expo 框架中的核心构建工具。打包器包含数千种意见和权衡。本文档概述了围绕 Metro 开发 Expo 的主要原因以及它如何使开发者受益。
¥Metro is the official bundler for Expo and React Native. It's a central build tool in the Expo framework. Bundlers comprise thousands of opinions and trade-offs. This document outlines the key reasons why Expo is developed around Metro and how it benefits developers.
¥Official Meta bundler
Metro 由 Meta 维护,Meta 是 React、React Native、Yoga 和 Hermes 的维护者。它用于开发一些世界上最大的应用,涵盖应用商店中的所有类别。
¥Metro is maintained by Meta, the maintainers of React, React Native, Yoga, and Hermes. It's used for developing some of the world's largest apps, ranging across all categories in the app stores.
Meta 工程师积极开发 Metro,明确要求将所有应用(超过 40 万个源文件)打包在一起,同时保持快速可靠。
¥Meta engineers actively develop Metro with the express requirement of bundling all their apps, across 400k+ source files, while remaining fast and reliable.
通过一流的 Metro 支持,我们确保 Expo 开发者在 Meta 的工具中具有连续性并可以即时访问新兴功能。这包括:
¥By having first-class Metro support, we ensure Expo developers have continuity across Meta's tools and get instant access to emerging features. This includes:
React Fast Refresh 是 2019 年作为 Metro 功能推出的 首次引入。React Web 社区于次年通过 Webpack 采用了它。
¥React Fast Refresh was first introduced as a Metro feature in 2019. The React web community adopted it the following year via Webpack.
将 JavaScript 转换为 Hermes 字节码以实现即时原生启动。
¥Transforming JavaScript to Hermes bytecode for instant native startup.
React Native DevTools(包括对 网络和 JS 调试 的一流支持)仅与 Metro 和 Hermes 一起使用。
¥React Native DevTools, including first-class support for network and JS debugging, is exclusively available with Metro and Hermes.
React Compiler 最初是作为 Metro 兼容的 Babel 插件推出的。
¥React Compiler was initially rolled out as a Metro-compatible Babel plugin.
计划加入 Metro 的新功能和即将推出的功能包括:
¥New and upcoming features that are planned to come to Metro include:
使用 Static Hermes 将 Flow 代码编译为原生机器代码。在 Tzvetan Mikov 的 Static Hermes 演讲中了解更多信息。
¥Compiling Flow code to native machine code with Static Hermes. Learn more in the Static Hermes talk by Tzvetan Mikov.
使用适用于所有平台的通用 React Server Components 进行数据提取、流式传输、React Suspense、服务器渲染和构建时静态渲染。在 React Conf 2024 的 通用 React 服务器组件 演讲中了解更多信息。
¥Data fetching, streaming, React Suspense, server rendering, and build-time static rendering with universal React Server Components for all platforms. Learn more in the Universal React Server Components talk at React Conf 2024.
Expo 团队与 Meta 合作开发 Metro for Expo Router,添加了 基于文件的路由、网络支持、打包包拆分、使用部分、CSS、DOM 组件、服务器组件和 API 路由 等功能。
¥The Expo team collaborates with Meta to develop Metro for Expo Router, adding features like file-based routing, web support, bundle splitting, tree shaking, CSS, DOM components, server components, and API routes.
¥Battle-tested at scale
世界上几乎每个 React Native 应用都使用 Metro,使其成为针对大型项目优化的久经考验的解决方案。这使其适合各种规模的开发者,从业余爱好者到大型公司。Metro 专为处理大型 Meta 应用而设计,这就是它具有使用 Watchman 和 共享远程缓存 进行原生文件监视等功能的原因。
¥Nearly every React Native app in the world uses Metro, making it a battle-tested solution optimized for large-scale projects. This makes it suitable for developers of all sizes, from hobbyists to large companies. Metro is designed specifically to handle large-scale Meta apps, which is why it has features such as native file watching with Watchman and shared remote caches.
¥On-demand processing
在开发过程中,Metro 不会执行任何特定于平台的工作,直到收到请求。这允许开发者在大型项目上工作,而无需为他们支持的平台数量支付性能成本。结合积极缓存和 异步路由,开发者可以逐步打包他们正在积极开发的应用部分。
¥In development, Metro doesn't perform any platform-specific work until requested. This allows developers to work on large projects without paying a performance cost for the number of platforms they support. In conjunction with aggressive caching and async routes, developers can incrementally bundle only the parts of the app that they're actively working on.
¥Multi-dimensional
与创建多个实例来打包服务器和客户端代码的传统打包器不同,Metro 可最大限度地跨平台和环境(服务器、客户端、DOM 组件)重用资源。这种架构非常适合多平台和服务器开发。
¥Unlike traditional bundlers, which create multiple instances to bundle server and client code, Metro maximizes resource reuse across platforms and environments (server, client, DOM components). This architecture is ideal for multiplatform and server development.
¥Reusable transform memoization
Metro 是增量式的,可以创建可跨机器使用的缓存转换工件。这使大型团队能够重用远程构建器的工作,这是 Meta 用于所有大型项目的一种技术。
¥Metro is incremental and can create cached transform artifacts that can be used across machines. This enables large teams to reuse work from remote builders, a technique used at Meta for all large projects.
¥Optimized for custom runtimes
虽然其他打包器是围绕 Web 浏览器的静态规范设计的,但 Metro 针对 React Native 的灵活性进行了优化。这将启用诸如生成 Hermes 字节码编译所需的特定受支持语言功能集等功能,从而加快生产中的应用启动速度。这还将扩展到 Static Hermes,它将静态类型信息编译为原生应用的机器代码。
¥While other bundlers are designed around the static specification of web browsers, Metro is optimized for the flexibility of React Native. This enables features like generating the specific set of supported language features required for Hermes bytecode compilation which enables faster app startup in production. This will also extend to Static Hermes, which will compile static type information into machine code for native apps.
¥Cross-technology support
Expo 利用 Metro 的技术创建了像 DOM 组件 这样的新功能。这允许原生应用中的 React 组件根据需要动态打包为整个网站,所有默认值与父应用相同。
¥Expo leverages Metro's technology to create novel functionality like DOM components. This allows a React component in a native app to be dynamically bundled as an entire website with all the same defaults as the parent app, on-demand.
¥Native asset exports
与最终结果是完全托管的应用的传统打包器不同,Metro 的配置选项支持导出打包包以作为独立应用二进制文件中的原生工件嵌入。这利用了特定于操作系统的优化,例如 Apple 平台上的 xcassets
。
¥Unlike traditional bundlers, where the end result is a fully hosted app, Metro's configuration options support exporting bundles to embed as native artifacts in standalone app binaries. This leverages OS-specific optimizations such as xcassets
on Apple platforms.
¥Concurrent processing
Metro 中的所有 AST 转换都是在所有可用线程上同时执行的,从而最大限度地利用硬件。
¥All AST transformation in Metro is performed concurrently across all available threads, maximizing the use of hardware.
¥Comparison with other approaches
虽然 Metro 是为通用应用开发而设计的,但它经常与其他仅限网络的打包器进行比较。以下是一些主要区别:
¥While Metro is designed for universal app development, it's often compared to other web-only bundlers. Here are some key differences:
¥Browser ESM versus bundling
虽然像 Vite 这样的打包器利用了浏览器中内置的 ESM 支持,但由于数千个级联网络请求,这种方法可能会导致中型到大型规模的实际开发时间变慢。Metro 在本地开发中执行打包,使开发结果更接近生产结果,更适合 React Native 更大的模块数量。
¥While bundlers like Vite leverage built-in ESM support in the browser, this approach can lead to slower practical development times at medium to large scales due to thousands of cascading network requests. Metro performs bundling in local development, which aligns the development results much closer to the production results and is better suited for React Native's larger module count.
¥JavaScript versus native languages
出于性能原因,一些打包器选择用 Rust 编写其核心,但这也带来了一些权衡,例如更具挑战性的贡献、补丁和开发。Metro 根据操作使用多种技术:
¥Several bundlers are opting to write their core in Rust for performance reasons, but this comes with some trade-offs, such as more challenging contributions, patches, and development. Metro uses a mix of technologies based on the operation:
核心打包器和实用程序是用 JS/Flow 编写的。
¥The core bundler and utilities are written in JS/Flow.
文件监视通过 Watchman 用 C++ 编写,并带有 JS 回退。然后,Watchman 可用于你计算机上的项目。
¥File watching is written in C++ via Watchman, with a JS fallback. Watchman is then used across projects on your computer.
AST 使用 Hermes 解析器 (WebAssembly) 解析为 Babel 兼容格式。
¥AST is parsed with Hermes parser (WebAssembly) to a Babel-compatible format.
AST 转换由 Babel 完成。这最大限度地提高了开发者的自定义能力。
¥AST transformation is done with Babel. This maximizes developer customization.
Minification 在原生平台上使用 Hermes,在 Web 上使用 Terser(带有可选的 ESBuild 支持)。
¥Minification uses Hermes on native platforms and Terser (with optional ESBuild support) for web.
CSS 解析和压缩由 LightningCSS(Rust)执行。
¥CSS parsing and minification is performed with LightningCSS (Rust).
这种方法与 Meta 和社区工具保持一致,同时允许开发者更轻松地进行调试、分析和修补。
¥This approach aligns with Meta and community tools while allowing easier debugging, profiling, and patching for developers.