前几天发布了我的框架,EasyGameFramework ,也发了几篇文章来分享我的心得和想法。之后在跟一些小伙伴的交流中收获很多。初次写文章,有些地方可能没表达清楚,大家可能一些疑惑。所以想了一下,写了下这篇文章,主要讲一下关于这个框架的定位。
什么是定位?
定位是一个汉语词汇,读音dìng wèi,意思是指确定方位,确定或指出的地方,确定场所或界限(如通过勘察)给这个地产的界限定位。出自《韩非子·扬权》。
第一篇文章 : 框架的诞生-零:为什么写框架?中有讲到,框架是解决特定领域问题的。
所以在这里我想要讲的定位是,如何划定框架解决问题的领域,以及方向。
为什么要定位呢?
这里不得不提Vue这个框架,以及其作者尤雨溪尤大。我相信有很多人都认识。CocosCreator的编辑器所用的前端框架就是vue+Eletron。
这里有一篇对尤雨溪大佬的采访文章:比较详细的采访 Vue 作者尤雨溪,这篇采访中尤雨溪谈到了对vue的定位
在所有框架中,我自己创造了一个概念叫渐进的框架。
因为 Vue 的核心组成只是数据绑定和组件,和 React 差不多。它只是解决了一小部分很重要的痛点。
与 React 相比,Vue 可能更简单易用,只知道一些 HTML,JavaScript 和 CSS 知识的人都可以很快入门 Vue。在框架层面上,我是用一个非常精简和尽可能小的的内核来构建的。
但是当构建更复杂的应用的时候,有很多其他的问题需要解决。比如说路由,或者说怎么处理跨组件通信,怎么样在大型应用程序中共享状态,这样的话我们就还需要更多的构建工具来模块化我们的代码库。怎么样来组织样式和各种各样的静态资源?像 Ember 或 Angular 这些非常完整的框架,它们就想解决所有可能遇到的这些问题,并把这些功能全都集成到框架中。
这就叫有得必有失吧。对用户使用情况的假设越多,框架最终的灵活性就越低。或者像 React 这样把很多问题都留给社区。React 社区是非常非常活跃的,经常有很多牛 X 的想法跳出来,当然也有不少不完美的想法。
Vue 就是比较折中,仍然保持一个很小的核心,只提供一些最重要的功能。但是我们还是在逐渐提供一些更多的独立解决方案,比如说路由,状态管理,构建工具链和 CLI。
它们都是官方维护的,有很好的文档,设计的也非常好,可以各种搭配使用,但重点是不需要的时候就可以不用。我认为这可能是 Vue 作为一个框架最大的特色。
就在今年Vue3.0也发布了,它在这条道路上更加极致了。有兴趣的小伙伴可以了解一下,掘金上也有很多分析的文章。
我对此的理解:
渐进的框架,提供一个非常精简,尽可能小的内核。来满足基本需求。然后逐渐提供一些官方维护的帮助构建复杂应用的独立解决方案,可以各种组合搭配使用,不需要时可以不用。同时也可以自己开发定制自己的库。
一个框架需要有自己的定位,要么精简无比,就像react一样,就做个渲染库。或者像Angular一样,大而全。亦或者像vue一样折中,渐进。
一开始,我在慢慢搭建自己的框架时,心潮澎湃,激情满满。想要有很多很多功能,也实现了很多功能模块。但是,有时候想用一部分功能时,不好拆分,用了之后同步和维护也会变得麻烦。(ps.当时用Laya3d在开发rpg挂机项目,框架已经具备大部分功能模块了,也想开源出来,但想了想只是芸芸众轮中一个大同小异的轮子,没啥好分享的,也不好维护。)
大而全的路子不适合我,因为时间精力没那么多,而且价值和意义不大。
所以我选择了渐进。
这一个转变,让我更多地关注手中的业务,关注多人协作,以及对需求、问题的思考。去学习不同框架的设计思路,以及了解它们如何去解决它们界定的领域的问题。
我将我认为最重要最核心的模块分离出来,进行研究,实践和迭代,尽量打磨到更好的状态。
虽然我选择的方向和Vue相似,但不能比的。
框架核心的定位
-
极致轻量级
这样它就可以轻易融入任意阶段的项目,比如你想要一个舒服的全局调用不同模块的接口的体验,那它的添加几乎无感,就130多行的源码,未压缩就10kb。
-
引擎无关性
不受限于任意引擎,只要是能用js/ts开发的程序,都可以用。如果你希望获得在不同项目中拥有一致的编码和模块管理体验的话。
-
可插拔可扩展的模块化机制
核心库提供的机制,可以让你可以创造多种方式去管理你的业务和基础模块,你可以在里面套pureMvc那套规范,也可以简单的横向扩展。
使用面向接口编程,你可以动态地根据平台,环境,替换具体模块实现。 -
灵活可扩展的模块生命周期
模块生命周期可以方便管理模块之间的依赖,以及可以扩展自己业务环境所需的生命周期。
比如登陆,登陆之后,断线,重连,屏幕尺寸变化,进入后台,要做引导了…等等
论坛上有个小伙伴@zzzz.leung问到我
模块之间的依赖怎么处理呢?
一个框架应该需要提供模块裁剪能力以减少代码包大小吧?
因为迭代的功能越多,框架会越庞大复杂。其实这个模块生命周期的用法在框架的诞生-一:我想要的框架就有说到,不知道是不是你想要的。
start, afterStart 这些生命周期 接口跟 cocos 和 Unity 的组件式接口很像。
主要是方便处理不同模块之间的依赖引用。比如:A 依赖了 B,但 B 还未初始化。
各自的初始化,都在 start 里处理,然后在 afterStart 里进行依赖调用。
可能对于不同的业务,这些生命周期可能不够用,可以根据具体业务进行扩展,满足自定义需求。
比如登录业务相关的:
C 模块依赖 A 和 B 登录后的数据状态,那么增加两个接口 onLoginInit,onAfterLoginInit。
那么 A 和 B 实现 onLoginInit 接口进行登录初始化,C 在 onAfterLoginInit 接口进行依赖调用。
模块自动裁剪这种功能,太高级了。这个是在编译层做的处理,比如摇树Treeshake优化,将没有调用过的函数代码剪掉。
随着功能迭代开发,框架的确会越来越庞大,这个时候就需要开发者自己去整理了,这个可能任何框架都没办法帮你自动处理。
有人可能说:人家CocosCreator可以啊。这个是官方提供的对引擎的模块进行剔除。你自己扩展一堆模块,可能需要你自己去决定剔除哪些了。
同样,我所提供的模块,你可以按需使用。可以参照这两张图▼
我提供的一些模块有我个人从业务开发中实践然后沉淀比如显示管理模块display-ctrl,也有我基于兴趣写的,比如imgui编辑器开发库。
框架库构建工具的定位
-
用于导出多模块规范的typescript库
-
可以做nodejs工具开发,通用库开发,引擎扩展库开发、、、
其实这个平时的业务开发不推荐使用这个工具将模块,独立起来开发。只有当这个模块需要多项目内共用,开源分享,抽离沉淀时使用。因为会增加维护成本。平时开发怎么方便就怎么来。
EasyGameFramework仓库的定位
开源和持续维护
这个项目主要是开源和持续维护框架提供的一些重要的基础模块。
包括不仅限于
-
前端基础模块(显示,资源,消息状态,网络等)
-
引擎扩展模块
-
基础模块的引擎实现
抛砖引玉
给大家提供一个开发框架的实践参考,也方便大家交流框架开发,业务开发等
也鼓励更多的人参与和交流,游戏开发路上不孤单。
H5游戏技术中台实践参考
这个说的有点夸张,但意思是那个意思,就是沉淀技术进行多项目共享的实践
游戏引擎,属于游戏程序里的渲染层级,如果能将业务和渲染很好的分离,将业务和渲染扩展分别沉淀,不仅有益于提高现有项目的开发效率。
而且将来如果做下一个项目,甚至切换引擎做项目,那么这个沉淀就可以让我节省很多时间,花更多的时间来专注业务和游戏性逻辑的研发,提高项目开发效率。
如果用了fairygui这种第三方UI解决方案,连UI资产也可跨项目跨引擎,那也可以节省很多时间。
当然也可以参照这个项目去打造公司的技术中台。
如果想做一个免费私有的npm源,可以借助coding免费打造私有的制品库。感兴趣的可以了解一下CODING 制品库 | 版本化的制品管理
这个项目是基于monorepo,主要是为了方便多模块项目开发和共享。
了解一下monorepo资料
白鹭的egret pro 就是使用了monorepo的方式进行开发。 【PPT】白鹭引擎首席架构师@王泽:框架开发中的基础设施搭建 ▼
当然这个好不好用,看个人和团队。
我自己使用的感觉就是,多个独立模块同时开发,一个包写完代码,另一个包就可以像npm install 之后那样用,反馈非常快,非常舒服。
就是指令稍微有点复杂这个不太舒服,开发久了就习惯了
如果是分开仓库,本地开发还好,可以使用npm link,但如果多人协作,就麻烦了。
而且本地开发需要npm link 这个和install不太一样,就是和具体的使用环境不同。
谢谢大家阅读我的文章,希望大家能有所收获。
框架开发系列文章
-
不只是 UI 管理:通用显示管理
-
让 fairygui 更好用的插件
-
满足多种需求的通用对象池
-
构建游戏/应用的神器:broadcast
-
满足所有自定义需求的通用 socket 网络模块
-
业务开发总结之状态管理
-
待续。。。
最后
欢迎关注我的公众号,更多内容持续更新
公众号搜索:玩转游戏开发
或扫码:
QQ 群: 1103157878
博客主页: https://ailhc.github.io/
掘金: https://juejin.cn/user/3069492195769469
github: https://github.com/AILHC