使用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的微前端集成!

相关推荐
佩奇的技术笔记1 小时前
Java学习手册:微服务设计原则
java·微服务
郝开2 小时前
扩展:React 项目执行 yarn eject 后的 scripts 目录结构详解
react.js·前端框架·react
代码的奴隶(艾伦·耶格尔)3 小时前
微服务!!
微服务·云原生·架构
weifont4 小时前
React中的useSyncExternalStore使用
前端·javascript·react.js
初遇你时动了情4 小时前
js fetch流式请求 AI动态生成文本,实现逐字生成渲染效果
前端·javascript·react.js
几何心凉5 小时前
如何使用 React Hooks 替代类组件的生命周期方法?
前端·javascript·react.js
码农飞哥5 小时前
互联网大厂Java面试实战:Spring Boot到微服务的技术问答解析
java·数据库·spring boot·缓存·微服务·消息队列·面试技巧
掘金-我是哪吒6 小时前
分布式微服务系统架构第126集:集群,数据库扩展,多节点分布,分库,分表,分片,分表,运维
运维·数据库·分布式·微服务·系统架构
RingWu11 小时前
微服务架构-限流、熔断:Alibaba Sentinel入门
微服务·架构·sentinel
李匠202411 小时前
C++GO语言微服务基础技术②
开发语言·c++·微服务·golang