├── .babelrc ├── .gitignore ├── .npmignore ├── LICENSE ├── README.md ├── dist ├── mk-meta-engine.js ├── mk-meta-engine.js.map └── mk-meta-engine.min.js ├── example ├── .babelrc ├── .npmignore ├── apps │ └── demo │ │ ├── action.js │ │ ├── component.js │ │ ├── config.js │ │ ├── data.js │ │ ├── index.js │ │ ├── mock.js │ │ ├── reducer.js │ │ ├── style.less │ │ └── webapi.js ├── assets │ ├── styles │ │ ├── apps.less │ │ └── index.less │ └── theme │ │ └── index.less ├── config.js ├── index.html ├── index.js ├── mock.js ├── package.json └── webpack.config.js ├── package.json ├── src ├── action.js ├── common.js ├── componentFactory.js ├── config.js ├── context.js ├── defaultComponent.js ├── index.js ├── monkeyKing.js ├── reactTryCatchBatchingStrategy.js ├── reducer.js ├── templateFactory.js └── wrapper.js ├── webpack.config.js └── yarn.lock /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["env"], 4 | ["stage-0"], 5 | ["react"], 6 | ], 7 | "plugins": [ 8 | ["transform-runtime"], 9 | ["transform-decorators-legacy"], 10 | ["add-module-exports"], 11 | ] 12 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | logs 2 | *.log 3 | npm-debug.log* 4 | .grunt 5 | .lock-wscript 6 | lib 7 | node_modules 8 | .npm 9 | .vscode 10 | jsconfig.json 11 | package-lock.json 12 | .lock 13 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | examples 3 | node_modules 4 | logs 5 | *.log 6 | npm-debug.log* 7 | test 8 | .npm -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # mk-meta-engine 2 | 3 | 元数据化引擎,在mk-app-loader实现的应用隔离基础上,实现可以用json元数据描述界面模型,并提供了action、reducer的基础函数和monkeyKing组件. 4 | 5 | 目的是让开发者能按照一个固定的套路创建应用 6 | 7 | ## run example 8 | 9 | ``` 10 | $ cd example 11 | $ npm init 12 | $ npm start 13 | ``` 14 | 15 | ## 基于当前元数据引擎实现的一些模板app,请点击链接查看 16 | 17 | - [mk-app-root](https://github.com/ziaochina/mk-app-root) 18 | - [mk-app-login](https://github.com/ziaochina/mk-app-login) 19 | - [mk-app-portal](https://github.com/ziaochina/mk-app-portal) 20 | - [mk-app-person-list](https://github.com/ziaochina/mk-app-person-list) 21 | - [mk-app-person-card](https://github.com/ziaochina/mk-app-person-card) 22 | 23 | ## demo网站 24 | 25 | - [mk-demo](https://github.com/ziaochina/mk-demo) 26 | 27 | ## API 28 | 29 | ### index 30 | 31 | | 成员 | 说明 | 类型 | 32 | |-------------|----------------|--------------------| 33 | | start | 启动, 使用mk命令创建网站已经调用,不用手动再掉 | function | 34 | | config | 配置,配置元数据引擎以及app-loader需要apps,components等,不用手动调用 | function | 35 | | action | 元数据引擎基类action,提供了一些action基础方法 | class | 36 | | reducer | 元数据引擎基类reducer,提供了一些reducer基础方法 | class | 37 | | wrapper | 元数据引擎组件装饰器 | function | 38 | | componentFactory | 元数据引擎组件仓库,可以注册自己开发的组件 | function | 39 | | AppLoader | AppLoader组件,可以加载app,来源于mk-app-loader | ReactElement | 40 | 41 | 42 | ### action 43 | 44 | | 成员 | 说明 | 类型 | 45 | |-------------|----------------|--------------------| 46 | | config | 配置函数,使用mk命令初始化的应该默认已经调用 | function | 47 | | getField | 获取state中某个字段值,参数为(fieldPath),如data.form.user | function | 48 | | gf | gf === getField, 简写 | function | 49 | | setField | 设置state中某个字段值,参数为(fieldPath,value) | function | 50 | | sf | sf === setField, 简写 | function | 51 | | getMeta | 获取元数据,参数为(path,propertys), path:如root.form.user, propertys:如['style'] | function | 52 | | gm | gm === getMeta, 简写 | function | 53 | | context | 上下文object,设置后所有app可以获取context中的信息 | object | 54 | | toast | 轻提示 | function | 55 | | notification | 通知提示 | function | 56 | | modal | 显示模式窗口 | function | 57 | 58 | ### reducer 59 | | 成员 | 说明 | 类型 | 60 | |-------------|----------------|--------------------| 61 | | init | 初始化,使用mk命令初始化的应该默认已经调用 | function | 62 | | getMeta | 获取元数据, 参数(state, path,propertys) | function | 63 | | gm | gm === getMeta | function | 64 | | getField | 获取字段值,参数为(state, fieldPath) | function | 65 | | gf | gf === getField | function | 66 | | setField | 设置字段值, 参数为(state, field, value) | function| 67 | | sf | sf === setField | function | 68 | | context | 上下文Object | object | 69 | 70 | ### meta 71 | Json化定义界面数据,如下 72 | ``` 73 | { 74 | name: 'root', 75 | component: '::div', 76 | children: [{ 77 | name: 'about', 78 | component: '::a', 79 | children: 'about', 80 | style: { fontSize: 16, margin: 30 }, 81 | onClick: '{{$handleAboutClick}}' 82 | }, { 83 | name: 'hello', 84 | component: '::a', 85 | children: 'hello world', 86 | style: { fontSize: 16, margin: 30 }, 87 | onClick: '{{$handleHelloClick}}' 88 | }, { 89 | name: 'content', 90 | component: '::div', 91 | style: { fontSize: 16, margin: 30 }, 92 | children: 'hello world' 93 | }] 94 | } 95 | ``` 96 | | 固定属性 | 说明 | 类型 | 97 | |-------------|----------------|--------------------| 98 | | name | 名称,同级不能为重复 | string | 99 | | component | 组件名,componentFactory中注册的,使用注册时候的名字,默认包含了mk-component所有组件;使用原生组件时,前面加:: | string | 100 | | _visibile | 引擎级属性,设置为false,这个节点将不render | bool | 101 | | _power | 超能力,目前支持函数返回组件和循环输出组件 | string | 102 | | ... | ...属性将属性值解构赋值给组件 | 103 | | 组件自身可用属性 | 只要是组件可用的属性就可以设置 | | 104 | 105 | 106 | 注:组件自身可用属性,属性值可以使用表达式,格式为"{{}}" 107 | 108 | "{{data.form.user}}" => 取state中路径为data.form.user的值 109 | 110 | "{{$handleClick}}" => 返回action中定义的handleClick方法 111 | 112 | "{{(e)=>$setField('data.form.user', e.target.value)}}" => 用户输入框修改,直接调用Action基类中setField方法赋值 113 | 114 | "{{$getVisible()}}" => 调用action中getVisible方法执行结果 115 | 116 | 117 | 118 | 119 | -------------------------------------------------------------------------------- /dist/mk-meta-engine.min.js: -------------------------------------------------------------------------------- 1 | !function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e(require("MKAppLoader"),require("React"),require("MKUtils"),require("Immutable"),require("ReactDom")):"function"==typeof define&&define.amd?define(["MKAppLoader","React","MKUtils","Immutable","ReactDom"],e):"object"==typeof exports?exports.MKComponent=e(require("MKAppLoader"),require("React"),require("MKUtils"),require("Immutable"),require("ReactDom")):t.MKComponent=e(t.MKAppLoader,t.React,t.MKUtils,t.Immutable,t.ReactDom)}(window,function(t,e,n,r,o){return function(t){var e={};function n(r){if(e[r])return e[r].exports;var o=e[r]={i:r,l:!1,exports:{}};return t[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=t,n.c=e,n.d=function(t,e,r){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:r})},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var o in t)n.d(r,o,function(e){return t[e]}.bind(null,o));return r},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="",n(n.s=64)}([function(t,e){var n=t.exports={version:"2.5.7"};"number"==typeof __e&&(__e=n)},function(t,e,n){var r=n(32)("wks"),o=n(24),i=n(2).Symbol,u="function"==typeof i;(t.exports=function(t){return r[t]||(r[t]=u&&i[t]||(u?i:o)("Symbol."+t))}).store=r},function(t,e){var n=t.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=n)},function(t,e,n){var r=n(2),o=n(0),i=n(34),u=n(10),a=n(5),s=function(t,e,n){var f,c,p,l=t&s.F,d=t&s.G,m=t&s.S,h=t&s.P,v=t&s.B,y=t&s.W,g=d?o:o[e]||(o[e]={}),_=g.prototype,b=d?r:m?r[e]:(r[e]||{}).prototype;for(f in d&&(n=e),n)(c=!l&&b&&void 0!==b[f])&&a(g,f)||(p=c?b[f]:n[f],g[f]=d&&"function"!=typeof b[f]?n[f]:v&&c?i(p,r):y&&b[f]==p?function(t){var e=function(e,n,r){if(this instanceof t){switch(arguments.length){case 0:return new t;case 1:return new t(e);case 2:return new t(e,n)}return new t(e,n,r)}return t.apply(this,arguments)};return e.prototype=t.prototype,e}(p):h&&"function"==typeof p?i(Function.call,p):p,h&&((g.virtual||(g.virtual={}))[f]=p,t&s.R&&_&&!_[f]&&u(_,f,p)))};s.F=1,s.G=2,s.S=4,s.P=8,s.B=16,s.W=32,s.U=64,s.R=128,t.exports=s},function(t,e,n){var r=n(6),o=n(48),i=n(35),u=Object.defineProperty;e.f=n(7)?Object.defineProperty:function(t,e,n){if(r(t),e=i(e,!0),r(n),o)try{return u(t,e,n)}catch(t){}if("get"in n||"set"in n)throw TypeError("Accessors not supported!");return"value"in n&&(t[e]=n.value),t}},function(t,e){var n={}.hasOwnProperty;t.exports=function(t,e){return n.call(t,e)}},function(t,e,n){var r=n(11);t.exports=function(t){if(!r(t))throw TypeError(t+" is not an object!");return t}},function(t,e,n){t.exports=!n(12)(function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a})},function(t,e,n){"use strict";e.__esModule=!0,e.default=function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}},function(t,e,n){var r=n(45),o=n(28);t.exports=function(t){return r(o(t))}},function(t,e,n){var r=n(4),o=n(15);t.exports=n(7)?function(t,e,n){return r.f(t,e,o(1,n))}:function(t,e,n){return t[e]=n,t}},function(t,e){t.exports=function(t){return"object"==typeof t?null!==t:"function"==typeof t}},function(t,e){t.exports=function(t){try{return!!t()}catch(t){return!0}}},function(t,e,n){var r=n(28);t.exports=function(t){return Object(r(t))}},function(t,e,n){var r=n(44),o=n(33);t.exports=Object.keys||function(t){return r(t,o)}},function(t,e){t.exports=function(t,e){return{enumerable:!(1&t),configurable:!(2&t),writable:!(4&t),value:e}}},function(t,e){t.exports={}},function(t,e,n){"use strict";e.__esModule=!0;var r=function(t){return t&&t.__esModule?t:{default:t}}(n(82));e.default=function(){function t(t,e){for(var n=0;n0&&e.forEach(function(t){t.appName?f.default.registerAppComponent(t.appName,t.name,t.component):f.default.registerComponent(t.name,t.component)}),u&&(0,a.default)(u).forEach(function(t){var e=u[t];e.components&&e.components.length>0&&e.components.forEach(function(t){f.default.registerAppComponent(e.name,t.name,t.component)})})}p.getToast=function(){return r},p.getNotification=function(){return o},p.getModal=function(){return i},p.getApps=function(){return u},e.default=p,t.exports=e.default},function(t,e,n){t.exports={default:n(66),__esModule:!0}},function(t,e){t.exports=!0},function(t,e){var n=0,r=Math.random();t.exports=function(t){return"Symbol(".concat(void 0===t?"":t,")_",(++n+r).toString(36))}},function(t,e){e.f={}.propertyIsEnumerable},function(t,n){t.exports=e},function(t,e){t.exports=n},function(t,e){t.exports=function(t){if(void 0==t)throw TypeError("Can't call method on "+t);return t}},function(t,e){var n={}.toString;t.exports=function(t){return n.call(t).slice(8,-1)}},function(t,e){var n=Math.ceil,r=Math.floor;t.exports=function(t){return isNaN(t=+t)?0:(t>0?r:n)(t)}},function(t,e,n){var r=n(32)("keys"),o=n(24);t.exports=function(t){return r[t]||(r[t]=o(t))}},function(t,e,n){var r=n(0),o=n(2),i=o["__core-js_shared__"]||(o["__core-js_shared__"]={});(t.exports=function(t,e){return i[t]||(i[t]=void 0!==e?e:{})})("versions",[]).push({version:r.version,mode:n(23)?"pure":"global",copyright:"© 2018 Denis Pushkarev (zloirock.ru)"})},function(t,e){t.exports="constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf".split(",")},function(t,e,n){var r=n(70);t.exports=function(t,e,n){if(r(t),void 0===e)return t;switch(n){case 1:return function(n){return t.call(e,n)};case 2:return function(n,r){return t.call(e,n,r)};case 3:return function(n,r,o){return t.call(e,n,r,o)}}return function(){return t.apply(e,arguments)}}},function(t,e,n){var r=n(11);t.exports=function(t,e){if(!r(t))return t;var n,o;if(e&&"function"==typeof(n=t.toString)&&!r(o=n.call(t)))return o;if("function"==typeof(n=t.valueOf)&&!r(o=n.call(t)))return o;if(!e&&"function"==typeof(n=t.toString)&&!r(o=n.call(t)))return o;throw TypeError("Can't convert object to primitive value")}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=u(n(71)),o=u(n(8)),i=u(n(17));function u(t){return t&&t.__esModule?t:{default:t}}var a=new(function(){function t(){(0,o.default)(this,t),this.components={},this.appComponents={}}return(0,i.default)(t,[{key:"registerComponent",value:function(t,e,n){if(this.components[t]){if(n)return;throw"组件existed. name: "+t}this.components[t]=e}},{key:"registerAppComponent",value:function(t,e,n){if(this.appComponents[t]=this.appComponents[t]||{},this.appComponents[t].components=this.appComponents[t].components||{},this.appComponents[t].components[e])throw"组件existed. app:"+t+", name: "+e;this.appComponents[t].components[e]=n}},{key:"registerComponents",value:function(t){var e=this;t&&0!=t.length&&t.forEach(function(t){return e.registerComponent(t.name,t.component)})}},{key:"getComponent",value:function(t,e){if(!e)throw"component name can not null";if("::"==e.substring(0,2)){if(e.substr(2))return e.substr(2);throw"没有组件. name: ::"}var n=e.split("."),r=n[0];if(this.appComponents&&this.appComponents[t]&&this.appComponents[t].components&&this.appComponents[t].components[r]){var o=this.appComponents[t].components[e];if(o&&n.length>1&&(o=this.findChild(o,n)),o)return o}var i=this.components[r];if(i&&n.length>1&&(i=this.findChild(i,n)),!i)throw"没有组件. name: "+e;return i}},{key:"findChild",value:function(t,e){var n=!0,o=!1,i=void 0;try{for(var u,a=(0,r.default)(e.slice(1));!(n=(u=a.next()).done);n=!0){var s=u.value;if(!t[s])return void(t=void 0);t=t[s]}}catch(t){o=!0,i=t}finally{try{!n&&a.return&&a.return()}finally{if(o)throw i}}return t}}]),t}());e.default=a,t.exports=e.default},function(t,e,n){var r=n(6),o=n(77),i=n(33),u=n(31)("IE_PROTO"),a=function(){},s=function(){var t,e=n(49)("iframe"),r=i.length;for(e.style.display="none",n(78).appendChild(e),e.src="javascript:",(t=e.contentWindow.document).open(),t.write("