You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 07:45:29