无法在Jupyter Widget中使用指定版本的React
问题描述
基于jupyter-widgets的widget-ts-cookiecutter模板开发React版Jupyter Widget时,已通过jlpm/yarn add react@18.2.0 react-dom@18.2.0安装指定版本,且node_modules中仅存在该版本、无其他依赖引入React,但构建后JupyterLab前端实际使用的是React 17.0.2,导致useId等React 18特性无法使用,触发报错。
需要解决:
- 17.0.2版本的React来源
- 如何强制使用指定的React 18.2.0版本
复现步骤
- 按照模板README完成cookiecutter模板安装
- 执行命令安装指定版本依赖:
jlpm/yarn add react@18.2.0 react-dom@18.2.0 - 创建新文件并添加测试组件:
import React from 'react'; export const SimpleComponent = () => { console.log('React.version:', React.version); return <div>Simple Test</div>; }; - 在
index.ts的视图render()函数中渲染组件:render() { this.component = React.createElement(SimpleComponent); ReactDOM.render(this.component, this.el); } - 运行后控制台输出
React.version: 17.0.2
问题原因
17.0.2版本的React来自JupyterLab本身的核心依赖。你当前使用的JupyterLab版本(大概率是3.x系列)的前端框架依赖React 17.0.2,JupyterLab启动时会提前加载全局的React实例,你的Widget代码运行时会优先调用这个全局实例,而非你本地安装的版本。
解决方法
方案1:修改Webpack配置强制打包本地React版本(推荐)
修改项目的webpack.config.js,将React和ReactDOM从外部依赖列表中移除,强制Webpack把你安装的React版本打包进Widget的bundle:
module.exports = { // 保留其他原有配置 externals: { // 覆盖默认的外部化配置,不将React/ReactDOM视为外部依赖 'react': false, 'react-dom': false } };
修改后重新构建Widget,即可使用本地安装的React 18.2.0。注意:此方式会增大bundle体积,但能彻底隔离全局环境的影响。
方案2:升级JupyterLab到支持React 18的版本
JupyterLab 4.x及以上版本已将核心依赖升级到React 18。如果可以升级环境,直接将JupyterLab升级到4.x系列,全局环境的React会自动变为18.x版本,你的Widget无需额外配置即可使用React 18特性。
方案3:依赖隔离(进阶)
若无法升级JupyterLab且不想增大bundle体积,可使用Webpack模块联邦或动态加载机制,将你的React版本与全局环境隔离。此方式配置复杂度较高,适合有Webpack进阶经验的开发者。
内容的提问来源于stack exchange,提问作者LukasP

