使用hel-micro微服务实现在jsp项目中引入react组件
以下是一个完整的示例,涵盖 React子应用配置、JSP主应用集成 以及 样式隔离 的实现细节。我们将通过 CSS Modules 和 Shadow DOM 确保React样式与JSP样式互不干扰。
一、React子应用配置
1. 项目结构
react-module/
├── src/
│ ├── index.js # 模块入口文件
│ ├── App.js # React组件
│ └── App.module.css # 组件样式(CSS Modules)
├── webpack.config.js # Webpack配置
└── package.json
2. 关键文件代码
a. src/App.module.css
使用CSS Modules确保样式局部化:
.container {
padding: 20px;
background-color: #f0f0f0;
border: 1px solid #ccc;
}
.title {
font-size: 24px;
color: #333;
}
b. src/App.js
使用CSS Modules引入样式:
import React from 'react';
import styles from './App.module.css';
export default function App() {
return (
<div className={styles.container}>
<h1 className={styles.title}>动态加载的React微模块</h1>
<p>当前时间:{new Date().toLocaleString()}</p>
</div>
);
}
c. src/index.js
暴露组件:
import React from 'react';
import App from './App';
export { App };
d. webpack.config.js
配置Webpack支持CSS Modules和UMD输出:
const path = require('path');
module.exports = {
mode: 'production',
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'react-module.umd.js',
library: 'reactMicroModule',
libraryTarget: 'umd',
globalObject: 'this'
},
externals: {
'react': 'React',
'react-dom': 'ReactDOM'
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-react']
}
}
},
{
test: /\.css$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
modules: true // 启用CSS Modules
}
}
]
}
]
}
};
e. package.json
构建命令
{
"scripts": {
"build": "webpack --config webpack.config.js"
},
"devDependencies": {
"webpack": "^5.89.0",
"webpack-cli": "^5.1.4",
"babel-loader": "^9.1.3",
"@babel/core": "^7.23.2",
"@babel/preset-react": "^7.23.2",
"style-loader": "^3.3.3",
"css-loader": "^6.8.1"
}
}
3. 构建子应用
npm install
npm run build
生成dist/react-module.umd.js
,将其复制到JSP项目的静态资源目录(如webapp/static/js
)。
二、JSP主应用集成
1. JSP页面代码 (main.jsp
)
<!DOCTYPE html>
<html>
<head>
<title>JSP集成React微前端示例</title>
<!-- 引入React和ReactDOM(CDN) -->
<script src="https://cdn.jsdelivr.net/npm/react@17.0.2/umd/react.production.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/react-dom@17.0.2/umd/react-dom.production.min.js"></script>
<!-- 引入hel-micro SDK(CDN) -->
<script src="https://cdn.jsdelivr.net/npm/hel-micro@3.1.3/lib-core/hel-micromini.min.js"></script>
<!-- JSP样式 -->
<style>
.jsp-title {
font-size: 32px;
color: blue;
}
</style>
</head>
<body>
<!-- JSP内容 -->
<h1 class="jsp-title">JSP主应用</h1>
<div>当前用户:<%= request.getUserPrincipal().getName() %></div>
<!-- React模块容器 -->
<div id="react-root"></div>
<!-- 动态加载微模块 -->
<script>
// 使用Shadow DOM隔离React样式
const shadowRoot = document.getElementById('react-root').attachShadow({ mode: 'open' });
const reactContainer = document.createElement('div');
shadowRoot.appendChild(reactContainer);
// 加载React微模块
helMicro.preFetchLib({
name: 'reactMicroModule',
apiPath: '${pageContext.request.contextPath}/static/js/react-module.umd.js'
}).then(() => {
const { App } = window.reactMicroModule;
ReactDOM.render(React.createElement(App), reactContainer);
}).catch(err => {
console.error('模块加载失败:', err);
});
</script>
</body>
</html>
三、样式隔离实现
1. React样式隔离
- 使用 CSS Modules 确保React组件的样式局部化,不会影响外部JSP样式。
- 使用 Shadow DOM 将React组件渲染到一个隔离的DOM树中,确保React样式不会泄漏到JSP页面。
2. JSP样式隔离
- JSP页面的样式通过普通
<style>
标签或外部CSS文件定义,不会影响React组件。
四、效果验证
-
JSP页面效果
-
React微模块效果
-
样式隔离验证
- JSP的
.jsp-title
样式为蓝色,React的.title
样式为灰色,互不干扰。 - 通过浏览器开发者工具检查Shadow DOM,确认React样式被隔离。
- JSP的
五、总结
通过 CSS Modules 和 Shadow DOM,我们实现了React微模块与JSP页面的样式完全隔离。同时,React子应用通过Webpack打包为UMD格式,直接集成到JSP项目中,无需依赖CDN。此方案具有以下优势:
- 样式隔离:确保React和JSP样式互不干扰。
- 即插即用:React微模块可独立开发、构建和部署。
- 低侵入性:JSP项目无需改造,仅需引入静态文件。
希望这个示例能帮助您顺利完成JSP与React的微前端集成!