React项目GitHub Actions构建部署EC2时报错:'useInsertionEffect'未从'react'导出求助
首先明确核心:useInsertionEffect是React 18才引入的内置Hook,你的React 17.0.2并不包含这个API,所以出现导入错误。而本地正常、CI报错的差异,大概率和依赖版本不一致或构建环境差异有关,具体原因和解决办法如下:
可能的原因
1. 依赖版本锁定失效,CI安装了更高版本的@emotion/react
如果你的package.json中@emotion/react的版本号带^前缀(比如^11.7.1),npm install会自动拉取该大版本下的最新子版本。而@emotion/react在11.x的后续更新中,新增了对React 18 useInsertionEffect的依赖(用于CSS-in-JS的样式插入优化):
- 本地环境因为node_modules缓存,还是使用旧的11.7.1版本,不会触发这个钩子;
- GitHub Actions每次构建都是全新环境,安装了最新的11.x版本,导致代码尝试导入React 17没有的API。
2. 构建环境的NODE_ENV差异触发不同代码分支
@emotion/react可能在生产构建(NODE_ENV=production)下启用了依赖React 18的优化逻辑,而本地开发环境(NODE_ENV=development)的代码路径并不涉及useInsertionEffect。GitHub Actions构建时默认是生产环境,因此触发了报错。
3. 间接依赖的包引入了React 18的API
你的项目中某个其他依赖包(比如UI组件库、工具库)可能内部使用了高版本的@emotion/react,或者直接调用了useInsertionEffect,导致CI环境中该依赖被安装,进而引发冲突。
解决方案
1. 强制锁定依赖版本,确保CI与本地一致
- 确保项目根目录有
package-lock.json(npm)或yarn.lock(yarn)文件,并且已经提交到GitHub; - 在GitHub Actions的构建步骤中,使用
npm ci(而非npm install)安装依赖。npm ci会严格按照lock文件的版本安装,避免自动升级依赖; - 如果lock文件已被污染,可以删除node_modules和lock文件,重新运行
npm install生成新的lock文件(确保@emotion/react是11.7.1版本),然后提交lock文件。
2. 降级@emotion/react到明确兼容React 17的版本
如果不想使用版本前缀自动升级,可以直接指定固定版本:
{ "@emotion/react": "11.7.1" }
重新安装依赖后,提交package.json和lock文件到GitHub。
3. 升级React到18.x版本(推荐长期方案)
如果项目没有React 17的强依赖,建议升级React到18.x版本,原生支持useInsertionEffect:
npm install react@^18.2.0 react-dom@^18.2.0
同时记得更新项目中的ReactDOM渲染逻辑(比如从ReactDOM.render切换到createRoot),避免兼容性警告。
4. 检查间接依赖,排除冲突包
使用以下命令找出哪个包间接引入了useInsertionEffect,再针对性降级或替换:
# npm 用户 npm ls useInsertionEffect # yarn 用户 yarn why useInsertionEffect
内容的提问来源于stack exchange,提问作者Mohammad Barjabeen

