组件模块共享
什么是组件模块共享?
在实际项目中,多个自定义组件经常需要复用同一段代码——比如一套工具函数、一个业务子模块、或一个 UI 功能组件。如果每个组件都各自打包一份,不仅增大了资源体积,后续维护也容易出现版本不一致的问题。
组件模块共享 解决的就是这个问题:让组件 A 把公共代码「导出」,组件 B 在运行时直接「引用」组件 A 导出的模块,而不是自己再打包一份。只需要在 neo.config.js 中做简单配置,即可解决多自定义组件之间的模块共享问题。
下文用 组件 A(提供方)与 组件 B(消费方)代称;工程内的目录名、以及 package.json 中的组件名,请替换为你的实际自定义组件标识(与 Neo 平台中注册的名称一致,下文示例记为 customCmpA / customCmpB)。
1. 在组件 A 中导出模块
在提供方的 neo.config.js 中配置 neoCommonModule.exports:
- 数组写法:按模块名列表导出 第三方依赖 等(例如 echarts、moment等)。
- 对象写法:用于导出 自定义组件内的子模块;值为绝对路径(建议用
path.resolve(__dirname, '...')),避免相对路径在解析时出错。
// 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 中配置 remoteDeps 与 externals:
remoteDeps:字符串数组,列出当前组件运行时所依赖的其他自定义组件在平台上的名称(自定义组件cmpType,如'customCmpA')。externals:字符串数组,列出要从打包自定义组件时,要剔除的模块名;须与remoteDeps中某组件在 A 侧exports里暴露的 key 一致(如'xxModuleA')。
重要约束
externals 仅支持数组写法,且必须与 remoteDeps 同时配置才能正确解析远程共享模块。如果只配置了 externals 而省略 remoteDeps,运行时将无法找到对应的远程模块,导致加载失败。
// customCmpB 的 neo.config.js
module.exports = {
neoCommonModule: {
remoteDeps: ['customCmpA'], // 依赖哪些已发布/可用的自定义组件
externals: ['xxModuleA'], // 与组件 A 的 exports 中的 key 对应
},
};3. 在组件 B 的业务代码中引用
在组件 B 的源码中,像引用普通 npm 包一样按暴露名导入即可(不要再写成本地相对路径):
import xxModuleA from 'xxModuleA';remoteDeps 与 externals 的区别
externals:构建阶段(Webpack)需要
打包时将这些模块名视为外部依赖,不打进当前组件的 bundle;运行时再按 commonjs <模块名> 的方式从宿主环境解析,与平台上通过 neoRequire / window.__NeoCommonModules 注入的实现一致。
remoteDeps:运行时依赖声明
声明「当前自定义组件依赖哪些远程组件(按 cmpType)」,运行时(初次加载当前自定义组件)同步加载依赖组件的资源脚本。
externals 和 remoteDeps 对比
| 维度 | externals | remoteDeps |
|---|---|---|
| 阶段 | 构建(Webpack) | 运行前注入的全局元数据 |
| 解决的问题 | 不把指定模块打进包,与平台共享实现一致 | 标明组件对其它远程组件的依赖关系 |
| 典型配置值 | 依赖的第三方依赖 npm 包名、或代码里 require / import 使用的模块标识 | 多为远程自定义组件的 cmpType(如 entityGrid3__c) |
配合使用:远程依赖既要避免重复打包(externals),又要让平台知道组件级依赖(remoteDeps)。二者职责不同:前者管打包与模块解析,后者管组件依赖声明。
示例说明
自定义组件 A(记作 customCmpA)可以在自身的 neoCommonModule.exports 中导出多个依赖模块(例如 dep1、dep2、dep3),供其它自定义组件复用。
当其它自定义组件依赖整个 customCmpA 及其导出子模块时,建议区分配置:
remoteDeps:填写远程组件的 cmpType,表示「依赖哪一个远程自定义组件包」,例如:jsremoteDeps: ['customCmpA']externals:填写实际在代码中引用的、需要外置的模块标识(与 Webpack 不打进包的require名一致),通常对应 customCmpA 暴露的各子模块路径,例如:jsexternals: ['dep1', 'dep2', 'dep3']
含义简述:
remoteDeps告诉平台:要先有/要加载customCmpA这份远程组件资源。externals告诉构建工具:对dep1、dep2等标识不要打包进当前工程,运行时由平台与 customCmpA 的exports注册结果对齐。
配置关系小结
| 侧 | 配置项 | 作用 |
|---|---|---|
| 组件 A | neoCommonModule.exports | 将本地模块映射为联邦名(key = 对外的 import 名) |
| 组件 B | neoCommonModule.remoteDeps | 声明依赖哪几个自定义组件作为远程 |
| 组件 B | neoCommonModule.externals | 声明本工程不打进包、由远程提供的模块名,须与 A 的 key 一致 |
注意事项
- 先发布后消费:消费方 B 在页面/设计器中能解析
xxModuleA的前提是,提供方 A 已按平台流程发布,且运行环境能加载 A 的静态资源;联调时可用 CLI 的neo linkDebug等流程配合验证。 - 命名唯一:
exports中的联邦名在依赖链上应清晰、避免多组件间同名冲突;若多源暴露同名,以平台/构建实际约定为准,建议由一方统一维护公共模块。 - 路径:对象
exports的 value 请始终使用绝对路径;修改neo.config.js后需重新执行本地构建或调试命令使配置生效。
