You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Liferay 7.4中如何在其他React Portlet复用共享React组件?

Liferay中React可复用组件的正确实现方案

你当前操作的问题

  • 直接跨Portlet导入源码文件:Liferay的OSGi模块是隔离的,不能通过相对路径直接引用其他Portlet的源码文件,这会导致模块加载器无法解析依赖,出现Exports is not defined和加载失败的错误。
  • 未按Liferay模块规范导出可复用组件:你的可复用组件没有被打包成可被其他模块识别的OSGi模块或者npm包,无法被消费端Portlet正确加载。

正确实现方案(两种可选)

方案一:基于OSGi模块的组件复用(Liferay原生方式)

  1. 改造可复用组件为OSGi模块

    • 在可复用组件的项目中,确保bnd.bnd文件配置正确,将组件打包成js-module类型的OSGi模块:
      Bundle-SymbolicName: com.example.reusable-react-component
      Bundle-Version: 1.0.0
      Web-ContextPath: /reusable-react-component
      Export-Package: com.example.reusable.component
      Js-Module: src/main/resources/jsx/ReusableComponent.js
      
    • 修改ReusableComponent.js,用Liferay的模块导出方式暴露组件:
      import React from 'react';
      
      const ReusableComponent = () => {
        return <div>This is a reusable React component.</div>;
      };
      
      // 用Liferay的模块导出API暴露组件
      Liferay.Loader.define('com.example.reusable-react-component/src/main/resources/jsx/ReusableComponent', ['exports', 'react'], function (exports, React) {
        Object.defineProperty(exports, '__esModule', {value: true});
        exports.default = ReusableComponent;
      });
      
  2. 消费端Portlet导入组件

    • 在消费端Portlet的Portlet1.js中,通过Liferay的模块加载器导入:
      import React from 'react';
      import ReusableComponent from 'com.example.reusable-react-component/src/main/resources/jsx/ReusableComponent';
      
      const Portlet1 = () => {
        return (
          <div>
            <h2>Portlet 1</h2>
            <ReusableComponent />
          </div>
        );
      };
      
      export default Portlet1;
      
    • 确保消费端Portlet的bnd.bnd中声明对可复用模块的依赖:
      Require-Bundle: com.example.reusable-react-component;bundle-version="[1.0.0,2.0.0)"
      

方案二:基于npm包的组件复用(适合用Liferay npm工具链的场景)

  1. 将可复用组件打包为npm包

    • 在可复用组件项目中初始化npm项目,修改package.json:
      {
        "name": "@example/reusable-react-component",
        "version": "1.0.0",
        "main": "dist/ReusableComponent.js",
        "peerDependencies": {
          "react": "^17.0.0 || ^18.0.0"
        }
      }
      
    • 用babel打包组件,配置babel.config.json:
      {
        "presets": ["@babel/preset-env", "@babel/preset-react"]
      }
      
    • 执行打包命令生成dist目录:
      npx babel src/main/resources/jsx/ReusableComponent.js --out-dir dist
      
    • 将npm包发布到私有npm仓库或者本地link。
  2. 消费端Portlet安装并使用组件

    • 在消费端Portlet的npm项目中安装依赖:
      npm install @example/reusable-react-component
      
    • 在Portlet1.js中正常导入使用:
      import React from 'react';
      import ReusableComponent from '@example/reusable-react-component';
      
      const Portlet1 = () => {
        return (
          <div>
            <h2>Portlet 1</h2>
            <ReusableComponent />
          </div>
        );
      };
      
      export default Portlet1;
      
    • 用Liferay npm工具链打包部署消费端Portlet:
      npm run build
      blade deploy
      

额外注意事项

  • 确保React版本在可复用组件和消费端Portlet中保持一致,避免版本冲突。
  • 如果使用Liferay 7.4+,推荐使用@liferay/js-toolkit来构建React模块,它会自动处理模块导出和依赖问题。

内容的提问来源于stack exchange,提问作者Geek

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 21:27:35