JModule.define(moduleKey, {
init(jModuleInstance) {}, // jModuleInstance 为JModule 实例
routes: [], // 路由
store: {}, // vuex
imports: [], // 定义模块依赖
exports: {}, // 对外API
});
复制代码
这里作一点解释:javascript
举个例子,开发一个研发流水线(pipeline)的模块:vue
应该会获得两个这样的模块配置:java
// coding 模块配置
JModule.define('coding', {
exports: {
loadHooks() {},
},
});
// pipeline 模块配置
JModule.define('pipeline', {
routes: [{
path: '/list',
name: 'PipelineList',
component: ListView,
}, { ... }],
store: {
currentPipeline: {}, // vuex 里的模块概念
},
imports: ['coding'], // 它依赖coding提供的API,
exports: {
ListView,
},
});
// pipeline 业务代码
JModule.require('coding.loadHooks').then((loadHooks) => {
loadHooks('...');
});
复制代码
把问题具体化,应该有三个问题须要回答vuex
这里总共涉及六个字段:moduleKey、init、routes、store、imports、exports。api
做用跨域
这是模块的标识符,用于识别一个模块。服务器
它不重要函数
若是从“让模块代码顺利运行”这一个目标来说,它其实不须要,我把代码加载了,该注册的路由注册了,代码就能够正确工做了,业务逻辑根本不须要它。不过,让代码运行,只是工程中的一部分工做。工具
它很重要 从管理的角度讲,它真的必不可少。好比:ui
a. 权限管理: 特定的人群只能访问特定的模块,须要它识别模块身份
b. 资源加载管理: 好比因为某些缘由,屡次要求执行加载某个模块的资源,咱们能够经过模块标识进行模块加载状态管理,避免重复从服务器加载资源
c. 调试: 能够跟踪指定模块的资源加载进度以及执行异常,另外,当同一个平台注入了同一个模块的两套资源配置时,好比既有生产环境配置又因开发须要注入了本地资源配置,能够选择本地优先。
做用
声明模块的路由信息和须要全局共享的数据
它不重要
一个模块有哪些页面,有哪些数据须要共享,是业务范畴的事情,业务是复杂多变的,它可能根本没有须要共享的数据,甚至根本不须要注册路由,好比我可能声明一个公共组件做为模块,或者它甚至没有视图,只是负责一些特定数据的加载,它其实能够不须要。因此这是可选字段。
它很重要
routes 很重要,对大多数场景而言,咱们须要根据不一样的地址显示不一样的视图,路由就必不可少。并且业务范畴的事情,也应该在模块内管理,平台不会预测到一个模块有几个页面叫什么名字。store 的存在我却是犹豫过,没有它并不会让业务开发不下去,若是须要共享数据,用 events 和 exports 事实上也能够达到相同的目的,可是从开发者习惯、易用性及历史项目改造难度的角度讲,store能避免一些额外的工做。
做用
模块间的依赖管理,声明模块对外提供服务的api, 以及依赖关系的外部模块的声明。可选
它不重要
没有这两个字段,事实上也确实有其它方式去知足功能开发的需求。没有imports,本身手动加载依赖的模块代码也能够工做;没有exports,往全局变量写点东西,其它模块也照样能访问到。若是只是为了实现功能,说它不重要,其实也没毛病。
它很重要
从代码可维护的角度讲,imports 声明依赖的模块,能够实现自动加载依赖的模块,否则可能会面临脑力记住依赖关系,手动加载依赖模块的尴尬场面。exports 除了对外暴露模块功能之外,能够告知开发者哪些是对外开放的功能,避免不兼容的修改致使其它模块不能正常工做。
做用
模块加载完以后自动执行的一个函数,可选
它不重要
绝大多数场景下,它确实没有存在必要。目前我也没有用到它了。
它很重要
这个字段存在的意义,主要是为了之后扩展功能,它能够拿到模块的实例信息,在早期的跨域解决方案中,模块内的http请求须要知道模块所在的域名,但在代码不容许使用域名硬编码的原则下,这个信息只有从模块实例才能获取到。后来为了研发方便调整了这部分方案,不过考虑到模块运行可能须要其它来源于外部配置的信息,因此保留了这个配置。
可能不必定够用,但我并无遇到更复杂场景。从模块管理的角度讲,提供了moduleKey 做为身份识别;从模块自身功能完备性角度讲,通常业务场景中须要全局挂载使用的只有router和store了;从模块间的关系讲,定义了入口和出口,应该也齐活了。
这里我大概参考了一下angular的模块设计,angular是个自带模块设计的东西,因此借鉴了一下。或许有更好的方式。
或许能够改为这样
export default {
routes: [],
...
};
复制代码
/projectA/src/modules/b
能够自动提取为'projectA.b'做为moduleKey。