Expo EAS构建中的ESmodule配置问题排查求助
解决方案:Expo + Node/Express 模块规范冲突处理
核心问题根源
Expo React Native 客户端运行在移动端环境,不支持 Node.js 核心模块(如 fs),而 Express 服务端依赖这些模块。当统一使用 ESModule 时,EAS 构建会误将服务端代码纳入客户端打包流程,导致 fs 模块无法解析;转回 CommonJS 则与客户端的 ESModule 配置冲突,引发本地编译错误。
分步解决配置方案
1. 隔离客户端与服务端代码目录
将服务端代码单独放在项目根目录的 server/ 文件夹下,彻底避免 Expo 打包工具(Metro)处理服务端文件。
2. 配置 Metro 排除服务端目录
修改项目根目录的 metro.config.js,添加规则排除服务端目录,确保 Metro 只处理客户端代码:
const { getDefaultConfig } = require('expo/metro-config'); const config = getDefaultConfig(__dirname); // 排除服务端目录 config.resolver.blockList = [/server\/.*/]; // 优先解析浏览器/客户端模块字段 config.resolver.resolverMainFields = ['browser', 'module', 'main']; module.exports = config;
3. 客户端保持 ESModule 配置
客户端(Expo)继续使用 ESModule,确保以下配置:
- 根目录
package.json:{ "type": "module", "scripts": { "start": "expo start", "build": "eas build" } } - 根目录
tsconfig.json(若使用 TypeScript):{ "compilerOptions": { "module": "ESNext", "target": "ES6", "moduleResolution": "NodeNext", "allowImportingTsExtensions": true } }
4. 服务端灵活选择模块规范
根据需求,服务端可选择两种配置方式:
方式一:服务端使用 CommonJS
- 在
server/目录下创建独立的package.json:{ "type": "commonjs" } - 服务端代码继续使用
require()和module.exports,启动脚本配置在根目录package.json:"scripts": { "server": "node server/index.js" }
方式二:服务端使用 ESModule
- 在
server/目录下的package.json中设置:{ "type": "module" } - 服务端的
tsconfig.json(若用 TS)配置:{ "compilerOptions": { "module": "NodeNext", "target": "ES6", "moduleResolution": "NodeNext" } } - 启动脚本调整为:
"scripts": { "server": "node --experimental-specifier-resolution=node server/index.js" }
5. 验证本地与构建流程
- 本地开发:分别启动客户端(
npm start)和服务端(npm run server),确认无编译错误 - EAS 构建:执行
eas build,此时 Metro 已排除服务端代码,不会再出现fs模块解析错误
内容的提问来源于stack exchange,提问作者Yafim Simanovsky
相关产品推荐
相关产品推荐

