Module Monkey是什么
对于CabloyJS内置的模块,以及第三方提供的模块,如果我们想对这些模块提供的某些页面、功能、逻辑进行改造,一般有两种方法:
- Fork分支:If the module provides the source code, we can fork a branch and modify it on this branch
- Module Monkey:使用CabloyJS提供的
Module Monkey
机制,使我们可以像猴子🐒一样,很轻易的对模块的某些组件进行替换
下面,我们使用模块test-partymonkey-monkey
来Monkey另一个模块test-party
创建Module Monkey
为了演示的需要,当创建一个新项目时,会自动在项目中添加模块test-partymonkey-monkey
。如果要新建一个Module Monkey,可以如下所示:
$ npm init cabloy src/module/test-partymonkey-monkey --type=module
模块后缀:
-monkey
- 模块必须添加后缀
-monkey
,从而告知系统这个模块是一个Monkey
前端Monkey
通过Monkey机制,可以替换前端的页面路由
、Vuex Store
、Config
和组件
,等等
注入monkey
在模块前端注入一个monkey对象
src/module/test-partymonkey-monkey/front/src/main.js
return cb({
...
monkey: require('./monkey.js').default(Vue),
});
定义monkey
src/module/test-partymonkey-monkey/front/src/monkey.js
import monkeyerPage from './pages/monkeyer.vue';
import monkeyerComponent from './components/monkeyerComponent.vue';
// eslint-disable-next-line
export default function(Vue) {
function monkeyRoute(moduleSelf, module, routePath, routeComponent) {
const route = module.options.routes.find(item => item.path === routePath);
if (route) {
route.module = moduleSelf;
route.component = routeComponent;
}
}
function monkeyStore(moduleSelf, module) {
const store = module.options.store;
// monkey getters: message2
const _message2 = store.getters.message2;
store.getters.message2 = function(state) {
const res = _message2(state);
console.log('monkey-store message2:', res);
return res;
};
// monkey mutations: setMessage
const _setMessage = store.mutations.setMessage;
store.mutations.setMessage = function(state, message) {
_setMessage(state, message);
console.log('monkey-store setMessage:', state.message);
};
}
function monkeyConfig(moduleSelf, module) {
const config = module.options.config;
config.monkeyed = true;
}
function monkeyComponent(moduleSelf, module, componentName, component) {
component.module = moduleSelf;
module.options.components[componentName] = component;
}
return {
moduleLoaded({ module }) {
if (module.name !== 'test-party') return;
const moduleSelf = Vue.prototype.$meta.module.get('test-partymonkey');
// route
monkeyRoute(moduleSelf, module, 'kitchen-sink/monkey/monkeyee', monkeyerPage);
// store
monkeyStore(moduleSelf, module);
// config
monkeyConfig(moduleSelf, module);
// component
monkeyComponent(moduleSelf, module, 'monkeyeeComponent', monkeyerComponent);
},
};
}
后端Monkey
通过Monkey机制,可以替换后端的API路由
和Config
,等等
注入monkey
在模块后端注入一个monkey对象
src/module/test-partymonkey-monkey/backend/src/main.js
...
// monkey
const monkey = require('./monkey.js')(app);
return {
...
monkey,
};
定义monkey
src/module/test-partymonkey-monkey/backend/src/monkey.js
module.exports = app => {
// eslint-disable-next-line
const moduleInfo = app.meta.mockUtil.parseInfoFromPackage(__dirname);
function monkeyRoute(module, routePath, routeController) {
const route = module.main.routes.find(item => item.path === routePath);
if (route) {
route.controller = routeController;
}
}
function monkeyConfig(module, config) {
config.monkeyed = true;
}
const monkey = {
moduleLoaded({ module }) {
if (module.info.relativeName !== 'test-party') return;
// route
monkeyRoute(module, 'test/monkey/monkeyee/test', {
module: moduleInfo.relativeName,
name: 'monkeyer',
});
},
configLoaded({ module, config }) {
if (module.info.relativeName !== 'test-party') return;
// config
monkeyConfig(module, config);
},
};
return monkey;
};
评论: