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:

  1. Fork Branch: If the module provides the source code, we can fork a branch and modify it on this branch
  2. 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. 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. 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/module-vendor/test-partymonkey-monkey/front/src/main.js

  1. 1 return cb({
  2. 2 ...
  3. 3 monkey: require('./monkey.js').default(Vue),
  4. 4 });

Definition of Monkey

src/module-vendor/test-partymonkey-monkey/front/src/monkey.js

  1. 1import monkeyerPage from './pages/monkeyer.vue';
  2. 2import monkeyerComponent from './components/monkeyerComponent.vue';
  3. 3
  4. 4// eslint-disable-next-line
  5. 5export default function(Vue) {
  6. 6
  7. 7 function monkeyRoute(moduleSelf, module, routePath, routeComponent) {
  8. 8 const route = module.options.routes.find(item => item.path === routePath);
  9. 9 if (route) {
  10. 10 route.module = moduleSelf;
  11. 11 route.component = routeComponent;
  12. 12 }
  13. 13 }
  14. 14
  15. 15 function monkeyStore(moduleSelf, module) {
  16. 16 const store = module.options.store;
  17. 17 // monkey getters: message2
  18. 18 const _message2 = store.getters.message2;
  19. 19 store.getters.message2 = function(state) {
  20. 20 const res = _message2(state);
  21. 21 console.log('monkey-store message2:', res);
  22. 22 return res;
  23. 23 };
  24. 24 // monkey mutations: setMessage
  25. 25 const _setMessage = store.mutations.setMessage;
  26. 26 store.mutations.setMessage = function(state, message) {
  27. 27 _setMessage(state, message);
  28. 28 console.log('monkey-store setMessage:', state.message);
  29. 29 };
  30. 30 }
  31. 31
  32. 32 function monkeyConfig(moduleSelf, module) {
  33. 33 const config = module.options.config;
  34. 34 config.monkeyed = true;
  35. 35 }
  36. 36
  37. 37 function monkeyComponent(moduleSelf, module, componentName, component) {
  38. 38 component.module = moduleSelf;
  39. 39 module.options.components[componentName] = component;
  40. 40 }
  41. 41
  42. 42 return {
  43. 43 moduleLoaded({ module }) {
  44. 44 if (module.name !== 'test-party') return;
  45. 45 const moduleSelf = Vue.prototype.$meta.module.get('test-partymonkey');
  46. 46 // route
  47. 47 monkeyRoute(moduleSelf, module, 'kitchen-sink/monkey/monkeyee', monkeyerPage);
  48. 48 // store
  49. 49 monkeyStore(moduleSelf, module);
  50. 50 // config
  51. 51 monkeyConfig(moduleSelf, module);
  52. 52 // component
  53. 53 monkeyComponent(moduleSelf, module, 'monkeyeeComponent', monkeyerComponent);
  54. 54 },
  55. 55 };
  56. 56
  57. 57}

Monkey at Backend

Through the monkey mechanism, you can replace the API Routes, and Config at backend, etc.

Injection of Monkey

src/module-vendor/test-partymonkey-monkey/backend/src/main.js

  1. 1 ...
  2. 2 // monkey
  3. 3 const monkey = require('./monkey.js')(app);
  4. 4
  5. 5 return {
  6. 6 ...
  7. 7 monkey,
  8. 8 };

Definition of Monkey

src/module-vendor/test-partymonkey-monkey/backend/src/monkey.js

  1. 1const controllerMonkeyer = require('./controller/monkeyer.js');
  2. 2
  3. 3module.exports = app => {
  4. 4 // eslint-disable-next-line
  5. 5 const moduleInfo = app.meta.mockUtil.parseInfoFromPackage(__dirname);
  6. 6
  7. 7 function monkeyRoute(module, routePath, routeController) {
  8. 8 const route = module.main.routes.find(item => item.path === routePath);
  9. 9 if (route) {
  10. 10 route.controller = routeController;
  11. 11 }
  12. 12 }
  13. 13
  14. 14 function monkeyConfig(module, config) {
  15. 15 config.monkeyed = true;
  16. 16 }
  17. 17
  18. 18 const monkey = {
  19. 19 moduleLoaded({ module }) {
  20. 20 if (module.info.relativeName !== 'test-party') return;
  21. 21 // route
  22. 22 monkeyRoute(module, 'test/monkey/monkeyee/test', controllerMonkeyer);
  23. 23 },
  24. 24 configLoaded({ module, config }) {
  25. 25 if (module.info.relativeName !== 'test-party') return;
  26. 26 // config
  27. 27 monkeyConfig(module, config);
  28. 28 },
  29. 29 };
  30. 30 return monkey;
  31. 31};