基于JHipster的React应用动态自定义表单加载方案咨询
问题:无需重建预编译JHipster应用,动态加载自定义React表单
背景
我们有一个基于Spring Boot+React的JHipster应用,包含多个UI页面和默认实体界面。现在需要实现表单构建器,用来生成带自定义钩子、验证逻辑的复杂自定义表单,且表单数量不固定。核心要求是不重建主应用的前提下,将这些自定义表单作为主应用的一部分托管。
已评估方案及缺陷
- JSON驱动表单渲染:会限制表单灵活性,复杂的JSON结构还会导致调试困难。
- Module Federation:需要额外处理多端口应用,对于内部简单应用属于过度设计。
我们的表单构建器可输出编译后的表单包,也能生成原生JSX格式的React表单,这些文件可复制到主应用子目录按映射使用。想寻求更简易的实现方式。
已尝试方案:脚本加载动态渲染表单
已通过脚本加载方式成功渲染表单,相关代码如下:
主应用App.js代码
import React, { useEffect, useState } from 'react'; function App() { const [ChildBundle, setChildBundle] = useState(null); const loadForm = (fm) =>{ const script = document.createElement('script'); script.src = '/forms/' + fm +'/bundle.js'; script.async = true; script.onload = () => { setChildBundle(window.ChildBundle); }; document.body.appendChild(script); return () => { document.body.removeChild(script); }; } if (!ChildBundle) { return ( <div> <ul> <li onClick={() => loadForm("Form1")}>Form1 </li> <li onClick={() => loadForm("Form2")}>Form2 </li> </ul> </div> ); } return <ChildBundle />; } export default App;
表单示例(Form1)代码
import React, { useState, useEffect } from "react"; const Form1 = () => { return ( <div> <h2>This is a Form1 Component</h2> </div> ); } export default Form1;
Form1的Webpack配置
const path = require('path'); module.exports = { mode: 'production', entry: './src/forms/Form1/index.js', output: { path: path.resolve(__dirname, 'dist/forms/Form1'), filename: 'bundle.js', }, module: { rules: [ { test: /\.jsx?$/, exclude: /node_modules/, use: 'babel-loader', }, { test: /\.(sa|sc|c)ss$/, // styles files use: ["style-loader", "css-loader", "sass-loader"], } ], }, };
Form1的入口文件index.js
import React from 'react'; import { createRoot } from 'react-dom/client'; import ReactDOM from 'react-dom'; import Form1 from './Form1'; const container = document.getElementById('taskForm'); const root = createRoot(container); root.render(<Form1 />);
当前方案存在的问题
不确定该方案后续会出现哪些潜在问题,目前仍需处理表单的钩子映射(提交、验证)及数据传递,且当前加载的组件无法接入React上下文,也无法正确调用上下文相关功能。
后续尝试
目前正在尝试Remote Component,此前因配置问题未成功,现参考官方示例进行测试。
内容的提问来源于stack exchange,提问作者Sariq Shaikh
相关产品推荐
相关产品推荐

