Metro 打包器
编辑页面
了解可以自定义的不同 Metro 打包器配置。
For the complete documentation index, see llms.txt. Use this Use this file to discover all available pages.
Expo CLI 在 npx expo start 和 npx expo export 期间使用 Metro 来打包你的 JavaScript 代码和资源。Metro 是为 React Native 构建并优化的,也被 Facebook 和 Instagram 等大型应用所使用。
自定义
你可以通过在项目根目录创建一个 metro.config.js 文件来自定义 Metro 打包器。此文件应导出一个扩展了 expo/metro-config 的 Metro 配置。请导入 expo/metro-config 而不是 @expo/metro-config,以确保版本一致性。
运行以下命令以生成模板文件:
- npx expo customize metro.config.jsmetro.config.js 文件如下所示:
const { getDefaultConfig } = require('expo/metro-config'); const config = getDefaultConfig(__dirname); module.exports = config;
有关更多信息,请参阅 metro.config.js 文档。
资源
Metro 会将文件解析为源代码或资源。源代码包括 JavaScript、TypeScript、JSON 以及应用程序使用的其他文件。资源 是图片、字体和其他不应被 Metro 转换的文件。为了适应大规模代码库,Metro 要求在启动打包器之前,必须显式定义源代码和资源的所有扩展名。这可以通过在 Metro 配置中添加 resolver.sourceExts 和 resolver.assetExts 选项来实现。默认情况下,包含以下扩展名:
向 assetExts 添加更多文件扩展名
最常见的自定义方式是向 Metro 添加额外的资源扩展名。
在 metro.config.js 文件中,将文件扩展名(不带前导 .)添加到 resolver.assetExts 数组中:
const { getDefaultConfig } = require('expo/metro-config'); const config = getDefaultConfig(__dirname); config.resolver.assetExts.push( // 为 SQLite 数据库添加对 `.db` 文件的支持 'db' ); module.exports = config;
别名
有时你希望某个导入被重定向到另一个模块或文件。这称为别名。由于 Metro 会同时为多个平台打包,我们建议使用自定义解析器来处理别名。
在以下示例中,我们将为 old-module 添加一个指向 new-module 的别名:
const { getDefaultConfig } = require('expo/metro-config'); /** @type {import('expo/metro-config').MetroConfig} */ const config = getDefaultConfig(__dirname); const ALIASES = { 'old-module': 'new-module', }; config.resolver.resolveRequest = (context, moduleName, platform) => { // 确保你调用默认解析器。 return context.resolveRequest( context, // 如果存在别名则使用别名。 ALIASES[moduleName] ?? moduleName, platform ); }; module.exports = config;
如果你只想在某个平台上应用该别名,可以检查 platform 参数:
config.resolver.resolveRequest = (context, moduleName, platform) => { if (platform === 'web') { // 该别名只会在打包 web 时使用。 return context.resolveRequest(context, ALIASES[moduleName] ?? moduleName, platform); } // 确保你调用默认解析器。 return context.resolveRequest(context, moduleName, platform); };
你将在下次重启开发服务器时看到这些更改。解析结果不会被缓存,因此无需使用 --clear 标志来更新。如果你使用像 babel-plugin-module-resolver 这样的基于转换的系统,则需要清除缓存才能看到应用的更改。
了解项目中更高级的 Metro 解析方式。
包拆分
Expo CLI 会根据异步导入(仅限 web)自动拆分包。
这种技术可与 Expo Router 一起使用,根据 app 目录中的路由文件自动拆分包。它只会加载当前路由所需的代码,并推迟加载额外的 JavaScript,直到用户导航到其他页面。有关更多信息,请参阅 异步路由。
Tree shaking
了解 Expo CLI 如何优化生产环境的 JavaScript 包。
压缩
了解如何在 Expo CLI 中使用 Metro 打包器自定义 JavaScript 压缩过程。
Web 支持
Expo CLI 支持使用 Metro 打包网站。这与原生应用使用的是同一个打包器,并且它被设计为跨平台通用。它是 web 项目的推荐打包器。
Expo webpack 与 Expo Metro
如果你之前使用已弃用的 @expo/webpack-adapter 编写网站,请参阅 迁移指南 和 对比图表。
为 Metro 添加 Web 支持
修改你的 应用配置,通过 expo.web.bundler 字段启用该功能:
{ "expo": { "web": { "bundler": "metro" } } }
开发
要启动开发服务器,请运行以下命令:
- npx expo start --web或者,在 Expo CLI 终端 UI 中按 W。
静态文件
Expo 的 Metro 实现支持通过将静态文件放在根目录 public/ 中,由开发服务器提供托管。这与许多其他 Web 框架类似。
使用 npx expo export 导出时,public 目录中的内容会被复制到 dist/ 目录中。这意味着你的应用可以按相对于主机 URL 的路径去获取这些资源。最常见的例子是 public/favicon.ico,网站会用它来渲染标签页图标。
你可以通过在项目中创建 public/index.html 文件来覆盖 Metro web 中默认的 index.html。
未来,这将通过 EAS Update 托管在所有平台上通用。目前,此功能仅限 web,并且基于原生应用所使用的静态主机,例如,旧版 Expo 服务更新不支持此功能。
警告 某些路径(如
/assets)被 Metro 保留。避免将文件放在 public/assets/ 或其他保留路径中。有关完整列表,请参阅 保留路径。
TypeScript
Expo 的 Metro 配置支持项目 tsconfig.json(或 jsconfig.json)文件中的 compilerOptions.paths 和 compilerOptions.baseUrl 字段。这使项目支持绝对导入和别名。有关更多信息,请参阅 TypeScript 指南。
此功能在裸项目中需要额外设置。有关更多信息,请参阅 Metro 设置指南。
CSS
了解如何在由 Expo CLI 和 Metro 打包器打包的网站中使用 CSS。