Vite本地构建正常,部署至AWS后出现React useContext空值错误
Vite构建React项目部署AWS后出现useContext报错的排查与解决
问题概述
使用Vite构建的React项目本地运行正常,但通过相同构建命令部署至AWS后,出现TypeError: ee.current is null错误,该错误溯源至React的useContext方法调用,涉及SwitchThemeButton.tsx组件对ThemeContext的使用。项目使用react-scripts构建时,本地及部署均无异常。
相关配置与代码
Vite配置
import react from '@vitejs/plugin-react'; import { defineConfig } from 'vite'; import svgr from 'vite-plugin-svgr'; import tsconfigPaths from 'vite-tsconfig-paths'; export default defineConfig({ plugins: [tsconfigPaths(), svgr(), react()], server: { port: 3000, }, preview: { port: 3000, }, resolve: { alias: { // This is needed for builds './runtimeConfig': './runtimeConfig.browser', }, }, build: { outDir: 'build', sourcemap: true, commonjsOptions: { include: [], }, }, optimizeDeps: { disabled: false, }, });
构建命令
NODE_ENV=test env-cmd -f ./config/.env.test node --max_old_space_size=16384 ./node_modules/vite/bin/vite.js build
完整错误栈
TypeError: ee.current is null useContext chunk-HBFDPAXM.js:258 vWe chunk-FG2S2VZJ.js:38 F8 chunk-OVR575D5.js:2971 Bxr SwitchThemeButton.tsx:11 z3 chunk-DTP5RXYY.js:4050 Ws chunk-DTP5RXYY.js:7186 Gs chunk-DTP5RXYY.js:6853 $3 chunk-DTP5RXYY.js:6846 Um chunk-DTP5RXYY.js:6829 vv chunk-DTP5RXYY.js:6545 n7 chunk-DTP5RXYY.js:6606 He chunk-DTP5RXYY.js:3179 fo chunk-DTP5RXYY.js:6417 fo chunk-DTP5RXYY.js:6416 $s chunk-DTP5RXYY.js:6405 K8 chunk-DTP5RXYY.js:4362 call react-router-dom.js:532 call react-router-dom.js:531 S react-router-dom.js:136 C react-router-dom.js:154 I4 react-router-dom.js:943 xei react-router-dom.js:1386 v react-router-dom.js:1316 vt chunk-DTP5RXYY.js:1500 Ar chunk-DTP5RXYY.js:1516 Ur chunk-DTP5RXYY.js:1519 Rd chunk-DTP5RXYY.js:2612 C3 chunk-DTP5RXYY.js:2639 Hp chunk-DTP5RXYY.js:2942 yv chunk-DTP5RXYY.js:6622 nt chunk-DTP5RXYY.js:1445 Hp chunk-DTP5RXYY.js:2720 N1 chunk-DTP5RXYY.js:2010 Vi chunk-DTP5RXYY.js:1992 q4 chunk-DTP5RXYY.js:2683 nc chunk-DTP5RXYY.js:2656 Yu chunk-DTP5RXYY.js:2663 Yu chunk-DTP5RXYY.js:2662 createRoot chunk-DTP5RXYY.js:7813 <anonymous> index.tsx:11 react_devtools_backend.js:4026:25 overrideMethod react_devtools_backend.js:4026 Fd chunk-DTP5RXYY.js:4518 callback chunk-DTP5RXYY.js:4533 gu chunk-DTP5RXYY.js:3565 t6 chunk-DTP5RXYY.js:6215 Op chunk-DTP5RXYY.js:6175 d5 chunk-DTP5RXYY.js:6152 a6 chunk-DTP5RXYY.js:6939 s0 chunk-DTP5RXYY.js:6895 n7 chunk-DTP5RXYY.js:6614 He chunk-DTP5RXYY.js:3179 fo chunk-DTP5RXYY.js:6417 (Async: VoidFunction) fo chunk-DTP5RXYY.js:6416 $s chunk-DTP5RXYY.js:6405 K8 chunk-DTP5RXYY.js:4362 call react-router-dom.js:532 call react-router-dom.js:531 S react-router-dom.js:136 C react-router-dom.js:154 I4 react-router-dom.js:943 xei react-router-dom.js:1386 v react-router-dom.js:1316 vt chunk-DTP5RXYY.js:1500 Ar chunk-DTP5RXYY.js:1516 Ur chunk-DTP5RXYY.js:1519 Rd chunk-DTP5RXYY.js:2612 C3 chunk-DTP5RXYY.js:2639 Hp chunk-DTP5RXYY.js:2942 yv chunk-DTP5RXYY.js:6622 nt chunk-DTP5RXYY.js:1445 Hp chunk-DTP5RXYY.js:2720 N1 chunk-DTP5RXYY.js:2010 Vi chunk-DTP5RXYY.js:1992 q4 chunk-DTP5RXYY.js:2683 nc chunk-DTP5RXYY.js:2656 Yu chunk-DTP5RXYY.js:2663 Yu chunk-DTP5RXYY.js:2662 createRoot chunk-DTP5RXYY.js:7813 <anonymous> index.tsx:11
SwitchThemeButton.tsx组件代码
export function SwitchThemeButton() { const classes = useStyles(); const { setCurrentTheme, currentThemeKey: currentTheme } = useContext(ThemeContext); const isDarkMode = currentTheme === 'dark'; const switchTheme = useCallback(() => { setCurrentTheme(isDarkMode ? 'light' : 'dark'); }, [isDarkMode, setCurrentTheme]); const nextTheme = isDarkMode ? 'light' : 'dark'; return ( <Tooltip sx={{ '&:hover': { background: 'none' }, '&:focus': { outline: 'none' } }} title={`Switch to ${nextTheme} mode`} > <IconButton onClick={switchTheme}> { isDarkMode ? <LightModeIcon className={classes.iconBtn} /> : <DarkModeIcon className={classes.iconBtn} /> } </IconButton> </Tooltip> ); }
Nginx配置
server { listen 80; server_name localhost; location / { root /usr/share/nginx/html; index index.html index.htm; try_files $uri /index.html; } error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; } }
排查思路与解决方案
- 确认Context Provider层级:检查
SwitchThemeButton是否被ThemeContext.Provider正确包裹。Vite的tree-shaking可能在生产构建中误优化了Provider的引入,需确保Provider在所有使用该Context的组件上层(比如路由组件之外)。 - 调整Vite构建配置:
- 移除
build.commonjsOptions.include: []配置,或添加react、react-dom到数组中,避免CommonJS依赖处理异常。 - 检查
optimizeDeps配置,尝试将react、react-dom或自定义Context相关文件加入include列表,确保依赖被正确预构建。
- 移除
- 环境变量一致性检查:本地开发环境为
development,部署构建用NODE_ENV=test,确认ThemeContext的初始化逻辑是否依赖环境变量,避免在test环境下出现初始值缺失。 - 清理部署缓存:AWS部署时可能存在旧缓存,清理CloudFront或Nginx的缓存,确保部署的是最新构建产物。
- 本地模拟生产构建:在本地执行相同的构建命令,用
serve工具或本地Nginx预览构建产物,复现问题后直接排查构建产物的差异,排除AWS环境因素。 - 检查Context初始化:确认
ThemeContext的初始值是否合理,比如是否给currentThemeKey设置默认值,setCurrentTheme方法是否在Provider中正确传入,避免解构时出现null/undefined。
内容的提问来源于stack exchange,提问作者Alex Ironside
相关产品推荐
相关产品推荐

