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

Liferay 7.3.5中多React Widget能否共享组件与node_modules?

在Liferay 7.3.5中实现React Widget共享组件与依赖的方案

完全可以实现你要的需求,核心思路是通过本地共享包管理公共组件,结合peerDependencies复用node_modules,再配合打包工具配置,确保每个Widget最终能独立打包成符合Liferay要求的jar包。下面是具体落地步骤:

一、目录结构落地

严格按照你期望的结构搭建项目:

ReactSuperWidget/
├── components/
│   └── ReusablePart/
│       ├── index.jsx
│       └── package.json  # 将该组件封装为本地npm包
├── ReactWidgets/
│   ├── ReactWidget1/
│   │   ├── src/
│   │   │   └── index.jsx  # 你的业务代码
│   │   ├── package.json
│   │   └── liferay-plugin.json  # Liferay Widget配置文件
│   ├── ReactWidget2/
│   └── ReactWidget3/
└── package.json  # 根目录统一管理公共node_modules依赖

二、共享组件配置

  1. 在components/ReusablePart/package.json中定义包信息:
{
  "name": "@local/reusable-part",
  "version": "1.0.0",
  "main": "index.jsx",
  "peerDependencies": {
    "react": "^17.0.0"  # 与Widget使用的React版本保持一致
  }
}
  1. 在根目录执行npm link ./components/ReusablePart,然后在每个Widget目录执行npm link @local/reusable-part,这样每个Widget就能通过import ReusablePart from '@local/reusable-part'导入共享组件,比相对路径更稳定。

三、共享node_modules的处理

  1. 在根目录package.json中安装所有公共依赖(如react、react-dom、babel相关工具等):
npm install react react-dom @babel/core ...
  1. 在每个Widget的package.json中,将公共依赖声明为peerDependencies,避免重复安装:
{
  "name": "react-widget1",
  "peerDependencies": {
    "react": "^17.0.0",
    "react-dom": "^17.0.0"
  },
  "devDependencies": {
    # 仅保留当前Widget独有的开发依赖,比如特定的Liferay打包配置
  }
}
  1. 配置每个Widget的webpack(或其他打包工具),让它从根目录读取公共依赖:
    在webpack配置文件中添加resolve规则:
module.exports = {
  resolve: {
    modules: [path.resolve(__dirname, '../../node_modules'), 'node_modules']
  }
};

四、Liferay打包适配

每个Widget需要配置liferay-plugin.json,确保打包时只包含自身业务代码,不重复打包公共依赖:

{
  "liferayPlugin": {
    "type": "widget",
    "jsConfig": {
      "external": ["react", "react-dom", "@local/reusable-part"]  # 声明外部依赖,不打包进Widget的bundle
    }
  }
}

另外,需要在Liferay服务器上全局提供这些公共依赖:可以把公共依赖打包成一个独立的Liferay模块部署到Portal,然后让三个Widget依赖这个模块;也可以通过Portal的javascript.config配置加载公共CDN资源(前者更稳妥)。

五、示例代码调整

将原来的相对路径导入改为本地包导入:

import React from 'react';
import ReusablePart from '@local/reusable-part';

function ReactWidget1() {
  return (
    <div className="App">
      <header className="App-header">
        <ReusablePart />
      </header>
    </div>
  );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 01:11:18