构建reactR Shiny Widget失败:react-flow封装问题求助
解决R中reactR/htmlwidgets封装react-flow的构建与渲染问题
一、先修复webpack无法解析react/jsx-runtime的构建错误
这个错误本质是Babel/React 18的JSX编译配置不匹配,按以下步骤调整:
- 安装Babel JSX转换插件
执行命令安装依赖:
yarn add -D @babel/plugin-transform-react-jsx
- 修改Babel配置文件(
.babelrc或babel.config.js)
确保开启自动JSX runtime,配置示例:
{ "presets": [ ["@babel/preset-env", { "targets": "> 0.25%, not dead" }], "@babel/preset-react" ], "plugins": [ ["@babel/plugin-transform-react-jsx", { "runtime": "automatic" }] ] }
- 调整webpack.config.js的resolve配置
替换之前无效的别名配置,确保React相关模块能被正确解析:
const path = require('path'); module.exports = { // ...其他配置 resolve: { extensions: [".js", ".jsx", ".json"], modules: ["node_modules"], alias: { 'react': path.resolve(__dirname, 'node_modules/react'), 'react-dom': path.resolve(__dirname, 'node_modules/react-dom'), 'react/jsx-runtime': path.resolve(__dirname, 'node_modules/react/jsx-runtime') } } };
- 清理缓存重新构建
删除node_modules和dist文件夹,重新执行:
yarn install yarn run webpack
二、修复Shiny应用元素空白及JS控制台报错
构建成功后,重点排查React 18的渲染方式和react-flow的初始化逻辑:
- 改用React 18的
createRoot渲染API
React 18已废弃ReactDOM.render,修改srcjs/reactflow.jsx的渲染逻辑:
import React from 'react'; import ReactFlow from 'reactflow'; import 'reactflow/dist/style.css'; import { createRoot } from 'react-dom/client'; const ReactFlowWidget = function(el, props) { // 解析R端传递的props(无需手动转JSON,htmlwidgets已处理) const { nodes, edges } = props; // 使用createRoot初始化渲染 const root = createRoot(el); root.render(<ReactFlow nodes={nodes} edges={edges} />); }; export default ReactFlowWidget;
- 确保R端props传递正确
修改R/reactflow.R,保证nodes/edges以正确格式传递:
reactflow <- function(nodes, edges, width = NULL, height = NULL, elementId = NULL) { # 无需手动转JSON,htmlwidgets会自动处理R对象到JS的转换 x <- list( nodes = nodes, edges = edges ) htmlwidgets::createWidget( name = 'reactflow', x = x, width = width, height = height, package = 'reactflow', elementId = elementId ) }
Shiny调用时,传递符合react-flow要求的结构:
library(shiny) library(reactflow) ui <- fluidPage( reactflow( nodes = list( list(id = "1", position = list(x = 0, y = 0), data = list(label = "Node 1")), list(id = "2", position = list(x = 200, y = 0), data = list(label = "Node 2")) ), edges = list( list(id = "e1-2", source = "1", target = "2") ) ) ) server <- function(input, output) {} shinyApp(ui, server)
- 排查JS控制台具体报错
如果仍有报错,根据提示针对性处理:
- 若提示
ReactFlow is not defined:检查react-flow的导入语句是否正确,确认已执行yarn add reactflow - 若提示
Cannot read property 'xxx' of undefined:检查R端传递的nodes/edges是否缺失必填字段(如id、position)
内容的提问来源于stack exchange,提问作者David
相关产品推荐
相关产品推荐

