
从 8.0 到 57.0Expo 仓库中 expo/config 的演进史与配置解析内核【免费下载链接】expoAn open-source framework for making universal native apps with React. Expo runs on Android, iOS, and the web.项目地址: https://gitcode.com/GitHub_Trending/ex/expo本篇以 Expo 官方仓库中 packages/expo/config/CHANGELOG.md 的完整版本记录为骨架梳理expo/config这个“与app.json交互的库”其 package.json 中的原始描述从 8.0.0 到 57.x 的演进脉络哪些 API 被移除、哪些能力被引入、依赖如何从sucrase迁移到expo/require-utils。读完本文你既能理解 Expo 项目静态/动态配置文件的解析流程与平台推断机制的源码级实现也能依据变更日志判断升级大版本时需要关注的不兼容点Breaking Changes。包定位与当前版本状态expo/config是 Expo CLI、expo prebuild、config plugins 等上层工具共同依赖的配置解析核心它负责定位项目中的app.json/app.config.*文件、评估动态配置、推导支持的平台列表并提供modifyConfigAsync等配置改写能力。当前仓库中该包的版本为57.0.6其 package.json 声明了双入口导出.—— 主入口暴露getConfig、modifyConfigAsync等核心 API./paths—— 独立子路径暴露项目根目录、入口点等路径解析工具如 paths/index.ts。其运行时依赖链也值得注意expo/config-plugins插件执行、expo/config-types类型定义、expo/json-fileJSON/JSON5 读写、expo/require-utils模块加载55.0.5 起取代require-from-string与sucrase、glob^13、semver、getenv、resolve-workspace-rootmonorepo 根检测。这条依赖链本身就是变更日志中一系列“Others”类条目的落点。配置解析流程静态、动态与平台推断理解变更日志中最有价值的部分是先把当前源码的解析流程讲清楚。src/Config.ts 中getConfig(projectRoot, options)的主干流程为定位配置文件getConfigFilePaths分别解析动态配置与静态配置路径。动态配置文件按 Config.ts 中的DYNAMIC_CONFIG_EXTS [.ts, .mts, .cts, .mjs, .cjs, .js]依次探测./app.config静态配置则依次回退app.config.json→app.json。这正是 55.0.7 版本“Support loading configs fromapp.config.{mts,cts,mjs,cjs}”条目的源码对应——该扩展名数组就是那次变更的产物。读取静态配置src/getConfig.ts 中getStaticConfig使用JsonFile.read(path, { json5: true })读取因此app.json允许 JSON5 语法注释、尾逗号。评估动态配置src/evalConfig.ts 的evalConfig通过expo/require-utils的loadModuleSync加载并转译配置文件这也是 55.0.5 用expo/require-utils替换require-from-stringsucrase的落点随后resolveConfigExport处理导出形态支持export default对象或接收ConfigContext参数的函数明确禁止返回 Promise抛出ConfigError(Config file ... cannot return a Promise.)因为 getConfig.ts 的注释说明“Next.js 尚不支持异步 Webpack 配置因此当前无法使用异步配置解析”。同时它会探测mayHaveUnusedStaticConfig——当静态配置存在、但动态配置返回结果未以静态配置为基底时置位供expo doctor等工具提示对应 8.4.0 中“Warn when dynamic config doesnt use static config present in project”这条变更记录。收敛expo对象reduceExpoObject处理顶层同时存在expo键与其他键的情况只取expo对象并打印黄色警告附https://expo.fyi/root-expo-object链接对应 9.0.1 的“Added warning when extraneous top-level keys are ignored in the final config”。推导平台列表getPlatformsFromConfig优先读取配置中显式的platforms字段缺省时调用getSupportedPlatformsConfig.ts能解析到react-native/package.json则加入ios、android能解析到react-dom/package.json则加入web当exp.experiments.outOfTreePlatforms开启时再检查react-native-tvos与react-native-macos分别加入tvos、macos。这与 10.0.0 的“Enable web as a default platform whenreact-domis installed”条目直接呼应——web 平台不再默认存在而是由依赖安装状态推断。应用静态插件fillAndReturnConfig最后调用withConfigPluginssrc/plugins/withConfigPlugins.ts执行配置中的静态插件。options.isPublicConfig为真时则会剥离_internal、hooks、ios.config、android.config、updates.codeSigningCertificate等私有字段使配置适合对外发布该分支源码见 Config.ts。配置改写modifyConfigAsyncConfig.ts支持三种情形——纯静态项目直接回写静态 函数式动态配置的组合且不涉及plugins字段时可安全改写否则返回warn/fail。10.0.0 的 breaking change“Change theconfigreturn type fromAppJSONConfigtoExpoConfiginmodifyConfigAsync”与“Attempting to modify a config and no file exists 时自动写入app.json”都发生在这里。版本演进主线按变更日志逐段解读8.x入口点与 entryFile 的清理期8.0.02023-02-03断言expo.entryPoint不被支持“never has been outside of classic builds”同时升级expo/json-file与expo/plist。8.0.1从导出的配置中移除originalFullName/currentFullName历史遗留字段。8.0.3 / 8.0.4resolveEntryPoint的exp参数改为可选并彻底停止使用entryPoint。8.3.02023-09-04移除 classic manifest 类型是包类型面向新版 manifest 模型的切换点。8.4.02023-10-17是 8.x 的重要节点Breaking从expo/config/paths移除getEntryPoint、getEntryPointWithExtensions、resolveFromSilentWithExtensions三个函数完全移除对app.json中expo.entryFile的支持重写了paths模块中的resolveEntryPoint修复匿名函数作为 config plugin 时withAnonymous的属性名问题新增“动态配置未使用静态配置”的警告能力。9.x–10.0modifyConfigAsync 能力成型与 monorepo 支持9.0.12024-04-24新增顶层多余键被忽略时的警告对应源码中reduceExpoObject的console.warn分支。10.0.02024-10-22是整个变更日志中条目最密集的大版本BreakingmodifyConfigAsync返回值中的config类型从AppJSONConfig收窄为ExpoConfig新特性目标配置文件不存在时自动创建app.json新增resolveRelativeEntryPoint考虑 server root导出getMetroServerRoot用于 monorepo 根检测支持 bun、npm、pnpm、yarn支持静态扩展动态配置的修改新增getMetroWorkspaceGlobs辅助 pnpm monorepo 配置修复入口点路径修改从 Gradle 插件移到 Node 脚本执行安装react-dom时默认启用 web 平台依赖glob7升级到glob10。10.0.2 / 10.0.4 / 10.0.6修复 manifest 插件修改的处理逻辑动态配置并存时跳过对app.json中plugins数组的修改移除改配置时意外打印的console.log。11.x–12.xbuild cache 与 API 收敛11.0.02025-04-04Breaking——从包导出中移除getAccountUsername。11.0.6 / 11.0.9引入 remote build cache provider 类型随后重命名为 build cache provider 并废弃remoteBuildCache字段——配置面从“远程构建缓存”泛化为通用“构建缓存 provider”类型定义落在 packages/expo/config-types 中。11.0.112025-07-01升级getenv2.0.0以支持大写布尔环境变量同时清理了警告/错误信息中的“Please”措辞。12.0.112025-12-04升级glob^13与sucrase~3.35.112.0.x 是 sucrase 路径的最后一段55.0.5 后被expo/require-utils取代。55.xrequire-utils 迁移与配置加载现代化55.0.02026-01-21从expo/config-types导出子类型sub-types改善包的类型引用方式。55.0.52026-02-16用expo/require-utils替换require-from-string与sucrase——动态配置文件的加载与转译自此统一走 evalConfig.ts 中的loadModuleSync。55.0.72026-02-20支持app.config.{mts,cts,mjs,cjs}即DYNAMIC_CONFIG_EXTS完整化的那次变更。55.0.112026-03-27memoize server root 检测降低 monorepo 场景下重复探测package.json/工作区根的开销。55.0.142026-04-09改用expo/require-utils的resolveFrom解析未定位到的 entrypointconvertEntryPointToRelative与expo/cli的mainModuleName期望对齐但被标记为 deprecated“不应该在未来被复用”55.0.152026-04-13紧接着修复了convertEntryPointToRelative未从真实 server root 解析到 entrypoint 的 bug。这条“实现→对齐→废弃→修复”的轨迹提示开发者不要在业务代码中依赖该内部转换函数。56.x–57.x类型细化与 out-of-tree 平台56.0.02026-05-05移除未使用的ExpoConfigSplash再导出。56.0.82026-05-20应用配置解析切换到expo/require-utils内部重构无用户可见变更。57.0.12026-06-27更新experiments.outOfTreePlatforms的类型定义。Unpublished57.0.7 方向新增实验性tvos与macos平台由experiments.outOfTreePlatforms门控PR #46344。这个实验开关的类型定义可以直接在仓库中查证——packages/expo/config-types/src/ExpoConfig.ts 中experiments对象注释为“Enable experimental features that may be unstable, unsupported, or removed without deprecation notices”其中outOfTreePlatforms?: boolean的说明是“Enable experimental support for select out-of-tree platforms, if their support packages are installed”。结合 Config.ts 中getPlatformsFromConfig的过滤逻辑可以确认其运行时语义未开启该开关时即便配置显式声明平台列表也会被过滤到android/ios/web三个值之内开启后仅当项目中实际安装了对应的react-native-tvos/react-native-macos支持包时tvos/macos才会进入平台列表。换言之该实验位是“配置声明 依赖安装”双重条件生效的。升级该包时需要关注的不兼容点清单综合变更日志历次标记为Breaking changes的条目可归纳为四组升级注意点版本变更升级影响8.0.0断言expo.entryPoint不被支持依赖entryPoint字段classic 构建之外从未生效的流程将直接失败8.3.0移除 classic manifest 类型仍引用旧版 manifest 类型的代码需迁移到新类型8.4.0移除paths导出中的getEntryPoint、getEntryPointWithExtensions、resolveFromSilentWithExtensions完全移除expo.entryFile依赖这三个工具函数或entryFile的插件/脚本需改用新resolveEntryPoint10.0.0 起为resolveRelativeEntryPoint10.0.0modifyConfigAsync的config返回类型改为ExpoConfig以AppJSONConfig形态消费返回值的 TS 代码需更新类型11.0.0移除getAccountUsername导出直接调用该 API 的工具需改为查询 EAS 账号信息的其他途径此外remoteBuildCache字段11.0.9 起废弃属于“未 breaking 但已废弃”的字段配置中仍在使用的话应迁移到buildCacheProvider的表述。小结packages/expo/config/CHANGELOG.md 的完整记录呈现出一条清晰的演进主线从 8.x 起持续剥离entryPoint/entryFile等经典构建遗留概念10.0.0 让modifyConfigAsync、monorepo 根检测getMetroServerRoot、getMetroWorkspaceGlobs与 web 平台自动推断成熟11.x 起 API 面收敛并引入 build cache provider55.x 之后加载机制全面迁移到expo/require-utils配置扩展名补齐到.mts/.cts/.mjs/.cjs57.x 则以experiments.outOfTreePlatforms开启了tvos/macos实验性平台的大门。对维护 Expo 插件或上层工具的开发者而言该变更日志与 src/Config.ts、src/evalConfig.ts 中的解析实现互为印证是评估配置相关行为与升级成本最可靠的仓库内依据。【免费下载链接】expoAn open-source framework for making universal native apps with React. Expo runs on Android, iOS, and the web.项目地址: https://gitcode.com/GitHub_Trending/ex/expo创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考