Day6的一个tips:Electron在Monorepo React 渲染错误排查:从 Hook 崩溃到根治

简介: 记录 Monorepo 中 Web 与 Electron 端 React "Invalid hook call" 的完整排查过程,涵盖版本错配、实例混用、CSP 拦截等根因分析与修复方案。

渲染层报错复盘(Web + Electron)

1. 背景

在完成 Zustand Store 迁移后,webdesktop(electron renderer) 先后出现 React 渲染错误,主要表现为:

  • Invalid hook call
  • Cannot read properties of null (reading 'useRef' / 'useState')
  • Incompatible React versions

这些错误会导致页面无法渲染,属于高优先级阻塞问题。


2. 问题现象

2.1 Web 端

关键报错:

  • Invalid hook call. Hooks can only be called inside of the body of a function component.
  • 触发点:<BrowserRouter>main.tsx:9
  • 连带报错:Cannot read properties of null (reading 'useRef')

2.2 Web 端二次报错(修复过程中的中间态)

关键报错:

  • Incompatible React versions
  • react: 19.1.0
  • react-dom: 19.2.5

说明渲染时拿到的 reactreact-dom 不是同一版本。

2.3 Electron 渲染进程

关键报错:

  • Invalid hook call
  • Cannot read properties of null (reading 'useState')
  • 触发组件:Versions.tsx

3. 根因分析

根因 A:Monorepo 下 React 实例混用

在 workspace 场景下,不同 app 的 reactreact-dom 解析路径可能不同,导致:

  • 业务代码使用了一份 react
  • 渲染器(react-dom / router)使用了另一份 react

从而触发 Invalid hook call

根因 B:一次错误修复带来的版本错配

为修复 Web 端 Invalid hook call,曾尝试在 Vite 中把 react alias 到 workspace 根。随后发现根目录实际版本为:

  • root react = 19.1.0
  • root react-dom = 19.2.5

这会直接触发 Incompatible React versions

根因 C:Electron 渲染端依赖归类导致运行时解析不稳定

apps/desktop 初始将 reactreact-dom 放在 devDependencies,配合 monorepo hoist 后,渲染进程更容易解析到非预期位置的包。


4. 排查路径(实际执行)

  1. 定位异常入口:

    • apps/web/src/main.tsx<BrowserRouter>
    • apps/desktop/src/renderer/src/components/Versions.tsx
  2. 检查版本与依赖树:

    • pnpm --filter @aitodos/web why react
    • pnpm --filter @aitodos/store why react
    • pnpm --filter desktop why react
  3. 检查运行时解析路径(关键):

    • require.resolve('react')
    • require.resolve('react-dom')
    • 分别在 apps/webapps/adminapps/desktop 目录执行
  4. 检查本地安装版本:

    • node_modules/react/package.json
    • node_modules/react-dom/package.json

5. 修复动作(按时间顺序)

5.1 Web/Admin 首轮修复

文件:

  • apps/web/vite.config.ts
  • apps/admin/vite.config.ts

动作:

  • 增加 resolve.dedupe: ['react', 'react-dom']

作用:

  • 降低同一应用加载多份 React 的风险。

5.2 修复过程中的错误动作(已回滚)

动作:

  • 在 Web/Admin Vite 里把 react/react-dom alias 到 workspace 根

结果:

  • 命中了 root react=19.1.0react-dom=19.2.5 的版本错配
  • 出现 Incompatible React versions

处理:

  • 回滚该 alias,仅保留 dedupe

5.3 Electron Renderer 修复

文件:

  • apps/desktop/electron.vite.config.ts
  • apps/desktop/package.json

动作 1(解析一致化):

  • renderer.resolve 中保留 dedupe: ['react', 'react-dom']
  • 显式增加:react: resolve('node_modules/react')

动作 2(依赖归类修正):

  • reactreact-domdevDependencies 移到 dependencies

目的:

  • 保证 Electron 渲染进程运行时拿到同一套 React 运行时依赖。

5.4 依赖重装与重启

执行:

pnpm install --filter desktop
pnpm --filter desktop dev

结果:

  • 安装成功(exit code 0)
  • Electron renderer dev server 启动成功

6. 最终状态

  • Web 端渲染恢复正常
  • Electron 渲染进程可启动并进入页面
  • Invalid hook call 链路已完成定向修复

7. 可复用修复模板

当再次出现 Invalid hook call 时,建议按以下顺序:

  1. 先查“版本一致性”

    • reactreact-dom 必须完全同版本
  2. 再查“解析路径一致性”

    • 比较 require.resolve('react')require.resolve('react-dom')
  3. 在 bundler 中启用去重

    • resolve.dedupe: ['react', 'react-dom']
  4. 对 Electron/运行时 app,确保 React 是运行时依赖

    • 放在 dependencies 而非仅 devDependencies
  5. 每次改完配置必须重启进程

    • 停掉旧的 dev 进程
    • 重新启动并强刷页面

8. 备注

  • apps/desktoppnpm.onlyBuiltDependencies 配置警告属于配置位置提示,不是本次渲染错误根因。
  • 若后续仍偶发异常,优先加运行时日志打印 React 解析路径和版本再定位。

9. 补充:Electron 复用 Web 后样式丢失与 CSP 报错

9.1 问题现象 A:页面“有结构、无样式”

现象:

  • Electron 页面能渲染文本和结构,但 Tailwind 视觉样式几乎全部失效。
  • 页面看起来像纯 HTML 默认样式。

关联报错(阶段性):

  • [plugin:vite:import-analysis] Failed to resolve import "@web/index.css"

根因:

  1. main.tsx 直接从 @web/index.css 引入时,CSS alias 在 Electron + Vite 场景下解析不稳定。
  2. apps/desktop 原模板样式文件未显式扫描 apps/web/src,导致 Tailwind 未生成 Web 页面实际使用的 utility class。

修复:

  • apps/desktop/src/renderer/src/main.tsx
    • 使用 desktop 本地样式入口:import './assets/main.css'
  • apps/desktop/src/renderer/src/assets/main.css
    • 保留 @import "tailwindcss";
    • 增加扫描源:
      • @source "../../../../../web/src/**/*.{ts,tsx}";
      • @source "../**/*.{ts,tsx}";
    • 移除 Electron 模板页遗留样式,保留通用基础规则(html/body/#root)。

验证:

  • pnpm --filter desktop build 通过。
  • 构建后的 renderer CSS 体积明显增大(说明 Tailwind utility 已成功生成)。

9.2 问题现象 B:CSP 拒绝 unsafe-eval

关键报错:

  • Uncaught EvalError: Evaluating a string as JavaScript violates CSP ... 'unsafe-eval'
  • 触发点:packages/shared/src/storage.ts

根因:

  • 为了条件加载 Taro/RN 存储实现,代码中使用了 new Function(...) 进行动态导入;
  • Electron 渲染进程默认 CSP 不允许 unsafe-eval,因此直接报错。

修复:

  • packages/shared/src/storage.ts
    • new Function(...) 改为 CSP 安全写法:
      • import(/* @vite-ignore */ modulePath)

验证:

  • pnpm --filter @aitodos/shared type-check 通过。
  • pnpm --filter desktop typecheck 通过。
  • Electron 运行时不再出现 unsafe-eval 相关异常。

9.3 结论

  • 复用 Web 到 Electron 时,样式链路要以 desktop 为入口统一管理;
  • Tailwind v4 需要在 desktop 的 CSS 入口显式声明 @source 扫描 Web 源码;
  • 渲染层共享代码必须避免 eval/new Function,否则容易被 CSP 拦截。
相关文章
|
2月前
|
人工智能 安全 网络虚拟化
为什么总显示请求超时或者一直运行中无反应,卸载重装了好几次,把各种安全软件和vpn等都关了也不行
该问题表现为AI工具频繁超时、卡在“生成中”无响应,强制停止无效甚至导致程序卡死。已尝试重装、关闭安全软件及VPN仍无效,疑似网络连接异常、服务端故障或本地环境兼容性问题。
|
27天前
|
人工智能 资源调度 调度
AI时代,大学生应该提前准备什么?
AI时代,大学生面临就业重塑与能力升级的双重挑战。本文聚焦认知重构、三大核心能力(统筹力、技术力、实战力)及行动路径,倡导从“工具使用者”进阶为“AI决策者”,以T型+AI复合素养应对变革,在人机协同中抢占未来先机。
|
27天前
|
安全 人机交互 调度
《零基础搭建OpenClaw迁移训练环境指南》
智能体仿真完美、落地即崩的行业死结,根源从来不是仿真精度不足,而是传统Sim2Real始终困在视觉特征匹配的表层逻辑里。本文拆解OpenClaw颠覆性的虚实迁移方案,它彻底抛弃暴力域随机化的老路,构建了一套以跨感官因果认知为核心的迁移体系。通过阶梯式虚实过渡、动态经验权重调节、执行器在线自校准与虚实数据双向闭环,让智能体学习物理世界的本质规律而非表面特征。
137 6
|
27天前
|
人工智能 数据挖掘 BI
本体论 vs 语义层:两种 AI 业务语义底座的区别、场景与建设路径
本体论和语义层并不是互斥关系,也不是简单的“谁替代谁”。本体论表达了企业 AI 的高阶目标,语义层提供了多数企业更容易落地的起点。
|
24天前
|
SQL 存储 数据库
SQL Server Management Studio (SSMS) 22.7 - 微软数据库管理工具
SQL Server Management Studio (SSMS) 22.7 是微软官方推出的数据库管理集成环境,支持 SQL Server 2014+ 及 Azure SQL、Synapse、Fabric 等云服务,具备 AI 辅助(GitHub Copilot)、查询格式化、架构对比等新特性。(239字)
143 4
|
27天前
|
缓存 人工智能
Qwen3.7-Max评测——阿里云百炼智能体Agent模型,免费100万tokens快速体验
阿里云百炼发布Qwen3.7-Max智能体大模型,专为Agent场景优化。现享5折优惠:输入6元/百万tokens、输出18元/百万tokens,并免费赠送100万tokens快速体验!Arena盲测国产第一,性能领先Kimi、DeepSeek等。立即领取折扣券,上阿里云百炼平台快速体验:https://t.aliyun.com/U/fPVHqY
470 1
|
24天前
|
存储 监控 调度
阿里云弹性高性能计算E-HPC全流程对接与实战指南
本文详细讲解阿里云弹性高性能计算E-HPC的完整对接流程,从基础概念、RAM授权、集群创建(含公共云/混合云)、存储配置、用户管理、作业提交(控制台/命令行/SDK)、集群监控运维、安全优化到成本控制,结合大量实操代码与配置示例,帮助用户快速掌握E-HPC的对接与使用,适配科学计算、工业仿真、AI训练等高性能场景。
|
2月前
|
人工智能 缓存 前端开发
Day4-5:Web 双端适配与 Admin 系统全栈落地实录
本文档整合了 Day 4 与 Day 5 的开发进展,核心涵盖 Web 端响应式 UI 复现、云端资讯 API 接入,以及 Admin 管理系统的架构设计与模块化开发步骤,打通了从用户体验到后台管理的完整链路。
|
2月前
|
人工智能 安全
深度测评:2026年中国医院精子SDF检测产品实测推荐
本文基于WHO标准与临床实测,从准确性、质控、报告维度及合规性四方面对比目前国内生殖中心常见的精子DFI检测四大品牌。结果显示:星博生物凭借AI纠错、双平台技术、全流程质控及首批二类证,综合表现最优,是精准评估男性生育力的首选。
|
2月前
|
人工智能 NoSQL API
从 0 到后端闭环: Day2 跑通 Prisma 7 + NestJS + Redis 的实战记录
记录我在 AiTodos Day2 打通后端闭环的过程:完成 Prisma 7 迁移、NestJS + Fastify 接入,以及 AI 资讯/Todo/统计接口和 Redis 日缓存落地。

热门文章

最新文章