What is Module Monkey
For the built-in modules of CabloyJS and the modules provided by the third party, if we want to modify some pages, functions and logic provided by these modules, there are generally two methods:
- Fork Branch: If the module provides the source code, we can fork a branch and modify it on this branch
- Module Monkey: Using the
module monkey
mechanism provided by CabloyJS, it’s easy to replace some functionalities of modules just like a monkey🐒
Next, we use the module test-partymonkey-monkey
to monkey another module test-party
Create a Module Monkey
The module test-partymonkey-monkey
is provided by the suite test-party
, so just install the suite test-party
as well:
- 1$ npm run cli :store:sync test-party
To demonstrate, when a new project is created, the module test-partymonkey-monkey
will be automatically added to the project. If you want to create a new module monkey, you can do the following:
Now take the module test-mymonkey-monkey
as an example to demonstrate how to create a new module monkey
:
- 1$ npm run cli :create:module test-mymonkey-monkey -- --template=module
Module Suffix:
-monkey
- The module must be suffixed with
-monkey
to inform the system that this module is a monkey
Monkey at Frontend
Through the monkey mechanism, you can replace the Page Routes
, Vuex Store
, Config
and Components
at frontend, etc.
Injection of Monkey
src/suite-vendor/test-party/modules/test-partymonkey-monkey/front/src/main.js
- 1 return cb({
- 2 ...
- 3 monkey: require('./monkey.js').default(Vue),
- 4 });
Definition of Monkey
src/suite-vendor/test-party/modules/test-partymonkey-monkey/front/src/monkey.js
- 1import monkeyerPage from './pages/monkeyer.vue';
- 2import monkeyerComponent from './components/monkeyerComponent.vue';
- 3
- 4// eslint-disable-next-line
- 5export default function(Vue) {
- 6
- 7 function monkeyRoute(moduleSelf, module, routePath, routeComponent) {
- 8 const route = module.options.routes.find(item => item.path === routePath);
- 9 if (route) {
- 10 route.module = moduleSelf;
- 11 route.component = routeComponent;
- 12 }
- 13 }
- 14
- 15 function monkeyStore(moduleSelf, module) {
- 16 const store = module.options.store;
- 17 // monkey getters: message2
- 18 const _message2 = store.getters.message2;
- 19 store.getters.message2 = function(state) {
- 20 const res = _message2(state);
- 21 console.log('monkey-store message2:', res);
- 22 return res;
- 23 };
- 24 // monkey mutations: setMessage
- 25 const _setMessage = store.mutations.setMessage;
- 26 store.mutations.setMessage = function(state, message) {
- 27 _setMessage(state, message);
- 28 console.log('monkey-store setMessage:', state.message);
- 29 };
- 30 }
- 31
- 32 function monkeyConfig(moduleSelf, module) {
- 33 const config = module.options.config;
- 34 config.monkeyed = true;
- 35 }
- 36
- 37 function monkeyComponent(moduleSelf, module, componentName, component) {
- 38 component.module = moduleSelf;
- 39 module.options.components[componentName] = component;
- 40 }
- 41
- 42 return {
- 43 moduleLoaded({ module }) {
- 44 if (module.name !== 'test-party') return;
- 45 const moduleSelf = Vue.prototype.$meta.module.get('test-partymonkey');
- 46 // route
- 47 monkeyRoute(moduleSelf, module, 'kitchen-sink/monkey/monkeyee', monkeyerPage);
- 48 // store
- 49 monkeyStore(moduleSelf, module);
- 50 // config
- 51 monkeyConfig(moduleSelf, module);
- 52 // component
- 53 monkeyComponent(moduleSelf, module, 'monkeyeeComponent', monkeyerComponent);
- 54 },
- 55 };
- 56
- 57}
Monkey at Backend
Through the monkey mechanism, you can replace the API Routes
, and Config
at backend, etc.
Injection of Monkey
src/suite-vendor/test-party/modules/test-partymonkey-monkey/backend/src/main.js
- 1 ...
- 2 // monkey
- 3 const monkey = require('./monkey.js')(app);
- 4
- 5 return {
- 6 ...
- 7 monkey,
- 8 };
Definition of Monkey
src/suite-vendor/test-party/modules/test-partymonkey-monkey/backend/src/monkey.js
- 1const controllerMonkeyer = require('./controller/monkeyer.js');
- 2
- 3module.exports = app => {
- 4 // eslint-disable-next-line
- 5 const moduleInfo = app.meta.mockUtil.parseInfoFromPackage(__dirname);
- 6
- 7 function monkeyRoute(module, routePath, routeController) {
- 8 const route = module.main.routes.find(item => item.path === routePath);
- 9 if (route) {
- 10 route.controller = routeController;
- 11 }
- 12 }
- 13
- 14 function monkeyConfig(module, config) {
- 15 config.monkeyed = true;
- 16 }
- 17
- 18 const monkey = {
- 19 moduleLoaded({ module }) {
- 20 if (module.info.relativeName !== 'test-party') return;
- 21 // route
- 22 monkeyRoute(module, 'test/monkey/monkeyee/test', controllerMonkeyer);
- 23 },
- 24 configLoaded({ module, config }) {
- 25 if (module.info.relativeName !== 'test-party') return;
- 26 // config
- 27 monkeyConfig(module, config);
- 28 },
- 29 };
- 30 return monkey;
- 31};
Comments: