Skip to content

组件模块共享

当多个自定义组件需要复用同一段代码逻辑(工具函数、业务子模块、UI功能组件等)时,可在各自定义组件项目的 neo.config.js 中通过 neoCommonModule模块联邦 方式实现跨组件共享:由一方 导出模块,另一方声明 远程依赖 后按模块名 import。可避免在多个自定义组件产物中重复打包同一份代码,便于集中维护公共代码逻辑的同时,也可减小自定义组件资源体积,提升运行时加载性能。

下文用 组件 A(提供方)与 组件 B(消费方)代称;工程内的目录名、以及 package.json 中的组件名,请替换为你的实际自定义组件标识(与 Neo 平台中注册的名称一致,下文示例记为 customCmpA / customCmpB)。

1. 在组件 A 中导出模块

在提供方的 neo.config.js 中配置 neoCommonModule.exports

  • 数组写法:按模块名列表导出 第三方依赖 等(例如 echarts、moment等)。
  • 对象写法:用于导出 自定义组件内的子模块;值为绝对路径(建议用 path.resolve(__dirname, '...')),避免相对路径在解析时出错。
javascript
// customCmpA 的 neo.config.js
const path = require('path');

module.exports = {
  neoCommonModule: {
    // 数组写法:可用于导出第三方依赖(例如 echarts、moment等)
    // exports: ['someNpmPackage'],

    // 对象写法:项目内子模块
    exports: {
      xxModuleA: path.resolve(__dirname, './src/components/xxModuleA'),
    },
  },
};

exports 对象中的 key(如 xxModuleA)即为其他组件在 import 时使用的模块名value 为对应源码的入口文件或目录。

2. 在组件 B 中声明远程依赖

在消费方的 neo.config.js 中配置 remoteDepsexternals

  • remoteDeps:字符串数组,列出当前组件运行时所依赖的其他自定义组件在平台上的名称(自定义组件 cmpType,如 'customCmpA')。
  • externals:字符串数组,列出要从打包自定义组件时,要剔除模块名须与 remoteDeps 中某组件在 A 侧 exports 里暴露的 key 一致(如 'xxModuleA')。

externals 仅支持数组写法,且必须与 remoteDeps 同时配置才能正确解析远程共享模块;勿单独使用 externals 而省略 remoteDeps

javascript
// customCmpB 的 neo.config.js
module.exports = {
  neoCommonModule: {
    remoteDeps: ['customCmpA'], // 依赖哪些已发布/可用的自定义组件
    externals: ['xxModuleA'], // 与组件 A 的 exports 中的 key 对应
  },
};

3. 在组件 B 的业务代码中引用

在组件 B 的源码中,像引用普通 npm 包一样按暴露名导入即可(不要再写成本地相对路径):

javascript
import xxModuleA from 'xxModuleA';

remoteDeps 与 externals 的区别

externals:构建阶段(Webpack)需要

打包时将这些模块名视为外部依赖,不打进当前组件的 bundle;运行时再按 commonjs <模块名> 的方式从宿主环境解析,与平台上通过 neoRequire / window.__NeoCommonModules 注入的实现一致。

remoteDeps:运行时依赖声明

声明「当前自定义组件依赖哪些远程组件(按 cmpType)」,运行时(初次加载当前自定义组件)同步加载依赖组件的资源脚本。

externalsremoteDeps 对比

维度externalsremoteDeps
阶段构建(Webpack)运行前注入的全局元数据
解决的问题不把指定模块打进包,与平台共享实现一致标明组件对其它远程组件的依赖关系
典型配置值依赖的第三方依赖 npm 包名、或代码里 require / import 使用的模块标识多为远程自定义组件的 cmpType(如 entityGrid3__c

配合使用:远程依赖既要避免重复打包(externals),又要让平台知道组件级依赖(remoteDeps)。二者职责不同:前者管打包与模块解析,后者管组件依赖声明

示例说明

自定义组件 A(记作 customCmpA)可以在自身的 neoCommonModule.exports导出多个依赖模块(例如 dep1dep2dep3),供其它自定义组件复用。

当其它自定义组件依赖整个 customCmpA 及其导出子模块时,建议区分配置:

  • remoteDeps:填写远程组件的 cmpType,表示「依赖哪一个远程自定义组件包」,例如:

    js
    remoteDeps: ['customCmpA']
  • externals:填写实际在代码中引用的、需要外置的模块标识(与 Webpack 不打进包的 require 名一致),通常对应 customCmpA 暴露的各子模块路径,例如:

    js
    externals: ['dep1', 'dep2', 'dep3']

含义简述:

  • remoteDeps 告诉平台:要先有/要加载 customCmpA 这份远程组件资源。
  • externals 告诉构建工具:对 dep1dep2 等标识不要打包进当前工程,运行时由平台与 customCmpA 的 exports 注册结果对齐。

配置关系小结

配置项作用
组件 AneoCommonModule.exports将本地模块映射为联邦名(key = 对外的 import 名)
组件 BneoCommonModule.remoteDeps声明依赖哪几个自定义组件作为远程
组件 BneoCommonModule.externals声明本工程不打进包、由远程提供的模块名,须与 A 的 key 一致

注意事项

  • 先发布后消费:消费方 B 在页面/设计器中能解析 xxModuleA 的前提是,提供方 A 已按平台流程发布,且运行环境能加载 A 的静态资源;联调时可用 CLI 的 neo linkDebug 等流程配合验证。
  • 命名唯一exports 中的联邦名在依赖链上应清晰、避免多组件间同名冲突;若多源暴露同名,以平台/构建实际约定为准,建议由一方统一维护公共模块。
  • 路径:对象 exports 的 value 请始终使用绝对路径;修改 neo.config.js 后需重新执行本地构建或调试命令使配置生效。