使用hel-micro微服务实现在jsp项目中引入react组件

以下是一个完整的示例,涵盖 React子应用配置JSP主应用集成 以及 样式隔离 的实现细节。我们将通过 CSS ModulesShadow 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确保样式局部化:

css 复制代码
.container {
  padding: 20px;
  background-color: #f0f0f0;
  border: 1px solid #ccc;
}

.title {
  font-size: 24px;
  color: #333;
}

b. src/App.js

使用CSS Modules引入样式:

javascript 复制代码
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

暴露组件:

javascript 复制代码
import React from 'react';
import App from './App';

export { App };

d. webpack.config.js

配置Webpack支持CSS Modules和UMD输出:

javascript 复制代码
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 构建命令

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. 构建子应用
bash 复制代码
npm install
npm run build

生成dist/react-module.umd.js,将其复制到JSP项目的静态资源目录(如webapp/static/js)。


二、JSP主应用集成

1. JSP页面代码 (main.jsp)
jsp 复制代码
<!DOCTYPE html>
<html>
<head>
    <title>JSP集成React微前端示例</title>
    <!-- 引入React和ReactDOM(CDN) -->
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/umd/react.production.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/umd/react-dom.production.min.js"></script>
    
    <!-- 引入hel-micro SDK(CDN) -->
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/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组件。

四、效果验证

  1. JSP页面效果

  2. React微模块效果

  3. 样式隔离验证

    • JSP的.jsp-title样式为蓝色,React的.title样式为灰色,互不干扰。
    • 通过浏览器开发者工具检查Shadow DOM,确认React样式被隔离。

五、总结

通过 CSS ModulesShadow DOM,我们实现了React微模块与JSP页面的样式完全隔离。同时,React子应用通过Webpack打包为UMD格式,直接集成到JSP项目中,无需依赖CDN。此方案具有以下优势:

  1. 样式隔离:确保React和JSP样式互不干扰。
  2. 即插即用:React微模块可独立开发、构建和部署。
  3. 低侵入性:JSP项目无需改造,仅需引入静态文件。

希望这个示例能帮助您顺利完成JSP与React的微前端集成!

相关推荐
祈澈菇凉39 分钟前
解释什么是受控组件和非受控组件
前端·javascript·react.js
理查der驾1 小时前
mini-react 第八天:做一个TODO 应用
react.js
Code额2 小时前
微服务的网关配置
网关·微服务·架构
极客先躯2 小时前
高级java每日一道面试题-2025年3月06日-微服务篇[Eureka篇]-Eureka服务注册与发现是什么?
java·微服务·eureka
情非得已小猿猿5 小时前
‌React Hooks主要解决什么
javascript·react.js·ecmascript
kong79069286 小时前
虚拟电商-延迟任务系统的微服务改造(二)
微服务·电商项目·延迟任务
NoneCoder6 小时前
Node.js系列(4)--微服务架构实践
微服务·架构·node.js
zhyoobo6 小时前
现代前端开发框架对比:React、Vue 和 Svelte 的选择指南
前端·vue.js·react.js
指尖的记忆8 小时前
React Hooks 深度解析:核心用法、最佳实践与实战场景
react.js
柯小慕8 小时前
React自定义Hooks入门指南:让函数组件更强大
前端·react.js