Open xinglie opened 5 years ago
magix3缘起
我原本以为以magix1.2版本的稳定性可以支撑好些年,不曾想人在江湖,身不由己:出了一个magix与brix共用事件模块的magix2.0版本。magix2.0是在magix1.2的基础上,把事件模块换成brix提供的事件模块而已。在实际项目开发中,brix提供的事件模块并不能有效的解决dom变化事件需要解绑或绑定的问题。这是因为brix的事件模块是扫描dom节点找到有哪些事件,这样当dom变化时,都要重新扫描,而dom是否变化是在magix的view中由开发者做的,这就导致需要在view中把所有与dom变化的地方都要关注起来,从而可以在dom变化的时候通知到brix的事件模块。如果存在大量的dom变化,事件这块的每次扫描整个dom,性能并不怎么好。
magix1.2
magix
brix
magix2.0
dom
view
分久必合,通过magix2.0与brix整合重复的部分,使我意识到仅仅做事件这块是不够的,模块的加载和实例化也是重复的,view与brix组件间的关系也是分不清楚的,那时候我被问的最多的一些问题:在项目中我应该把这个封装成brix组件么?brix组件里不能包含业务代码么?包含业务代码在我自己的项目里也是没问题啊?在brix组件里我怎么能够使用magix管理的接口?
magix2.0的一些事情没有做好,我们回过头来重新审视,总结经验:这些合并应该更彻底一些。
magix3.0,合并magix与brix,使view与组件归一化,统一模板引擎。brix抱歉了,有些必须割舍,包括brix这个概念。原来的brix组件变成magix的view,现在这些组件对应的view在这里:magix-galllery
magix3.0
模板引擎
许多问题皆源于它,时至今日仍然还在围着模板引擎转,使用合理的模板引擎,生成最优的目标代码,以达到高效的界面更新
合并后第一个挑战就是选择一个合适的模板引擎,统一我们之前在项目中用到的mustache,crox,xtemplate,vue等各式各样的模板。
mustache
crox
xtemplate
vue
underscore.template,最后一版brix用的模板引擎,也没有什么学习成本,magix3就选择了它做为模板引擎。现在来看这个模板引擎的选择并不怎么好,但在当时要整合brix,要升级组件库,许多方案只能先使用旧方案,减少新方案带来的坑和其它问题。统一,在当时显得更重要。就这样我们选择了underscore.template模板写法。
underscore.template
magix3
局部刷新之字符串拆分
如果view数据有变化,我们可以用最新的数据和模板生成最新的HTML,然后通过view根节点的innerHTML属性更新界面。当然目前也可以通过dom diff最细粒度的更新。不过那时候的需求是:找一种可以介于把整个view粗犷的刷掉和最细粒度更新之间的方案。那就是以dom节点与数据进行绑定的局部刷新,感谢波哥在这块的探索与实现,magix3的首次使用的局部刷新就是该方案
HTML
innerHTML
dom diff
当时的局部刷新方案的弊端是:需要在待刷新节点上写上对应的数据key,如果对应key的数据有变化时,则只刷新该节点下的innerHTML,开发过直通车的同学应该有体会。有时候忘记写key了,导致数据变化界面没刷新,如果多写了,则会有不必要的刷新。
key
带着不完善的方案,magix3的使命完成:使用原有的经验,统一割裂的开发方式,减少概念上的认知。
离线处理
处理不好性能的程序猿都是耍流氓。大概2015年底和波哥聊优化的事情,发现很多运行在线上的处理完全可以线下做,这样上线后可以减少计算,提升运行效率。同时因为是线下提前处理好的,可以通过查看结果来发现一些原来线上不能复现的问题。加上magix的本身也需要把html合并到js中,这时候magix-combine就出来了。
html
js
magix-combine
最初magix-combine只是合并文件,并做一些简单替换。
第一个主要的离线处理是前面提到的局部刷新之字符串拆分,为了方便开发人员,不在节点上标记数据变化的key,由程序自动识别完成。magix-combine做这一个功能时,从一个文件到拆分成十几个文件,从简单的正则到复杂的parser方案,前后持续时间最长,难度系数也最大,详细的技术方案可以查看这里 局部刷新与模板 。终于凭一己之力把它做了出来,也正是得益于该方案的实现,后续很多离线处理都在该功能的基础上顺利完成。
parser
第二个主要的离线处理是样式的scoped化,这里有记录在实施scoped之前遇到的问题 关于style的scope。 样式scoped方案线上处理的版本居多,但我们的要求是线下完成。参考过vue给节点增加data-v-hash的方式,私以为样式选择器从原来的标签或类选择器经过scoped后加上了属性选择,浏览器在处理样式匹配上性能会下降。参考过css-modules的做法,需要通过对象+旧选择器来使用变化后的选择器名称,很难和magix这种js与html分离的开发方式结合起来,使用起来也不方便。同时要照顾开发人员,不能因为要使用scoped功能就要做很大的变化。
scoped
data-v-hash
css-modules
“无感使用”是我在做样式scoped时候的感受。我该如何引入新的功能而不用改变现有的开发方式?我该如何平滑稳定的把有问题的方案引导到新的方案上来?虽说不破不立,但同事的感受更重要,我不能太唐突的推进。我要实施新功能,我也要照顾现有的开发流程,如何在二者间平衡,很难。最终在不改变当前开发方式的情况下,实现了想要的功能,新的方案得以顺利实施。难,吾往矣!
其实,一直在跟随着社区的发展,只是像前面所说的,有些功能的实现是无感知的,许多开发者在使用的时候或许并不知道我们早已默默应用了该技术。不过也正是由于我们自己的工具,可以把社区中一些优秀的方案在我们的项目中做的更彻底,能工具化的为什么要开发者参与呢?
第三个主要的离线处理是代码检查,之前我们的开发框架和组件可以快速的搭建出页面,但是如何保证产出的代码质量,如何让开发人员自己快速检查代码,如何避免别人踩过的坑,如何让别人的经验成为自己的经验,是我想解决,并且一定要解决的,尽管很难,If not me , who?
目前代码检测涵盖样式检查(书写要求、使用情况等),js代码循环检查(n层循环嵌套),js接口服务数据检查,模板命令语法检查,模板图片src属性检查,模板不建议使用的标签检查,模板危险属性检查,模板a或area标签检查,模板iframe标签检查,模板mx事件写法检查,模板mx-view检查,模板重复属性检查,模板命令语句中function及for of语句检查,模板标签配对检查等
把常见问题写到代码检测里面去!把别人的经验写到代码检测里面去!把需要掌握的知识点写到代码检测里面去!授鱼不如授渔
所以2016-2017年我的精力都放在magix-combine上,尽管有些事情远远超出离线处理这个愿景。
我回来了
老实说,在我做magix-combine这段时间里,magix除必要的支持外并没有怎么跟进,不过我终于忙完magix-combine回来了。
他们说underscore.template语法写多了比较乱,好的,支持类mustach的模板语法。他们说局部刷新使用字符串模板拆分的方式仍然刷新的范围太大了,而且社区里都是细粒度的刷新,好的,https://github.com/thx/magix/blob/master/src/tmpl/dom.js。真实dom与真实dom的diff,真实dom与虚拟dom的diff,虚拟dom与虚拟dom的diff,满足你的一切好奇心。
diff
我说历史的原因,我们的dom转换是在线上完成的,这显然应该在线下做,jsx的是不错的首选,好的,使用jsx去写magix,感谢竹隐的支持。我说根据同事间的调查,并不是每个人都乐意使用jsx,而且刚熟悉的类mustache写法要丢弃么,好的,支持类quickapp形式的模板。我说这些加载器requirejs,seajs,webpack都是过客,浏览器原生的import才是主场,好的,https://github.com/thx/magix/tree/master/src/module
jsx
requirejs
seajs
webpack
import
你有问题我有解决方案,最美好的事情不过如此吧?
局部刷新之dom diff
magix3提供了比较多的diff,目前线上用的是真实dom之间的diff,这是要照顾一下开发人员还有部分组件,时间久了都会有一些技术债。真实dom diff可以操作dom,而使用虚拟dom是无论如何都不能操作真实dom的,所以目前我们想直接用虚拟dom还需要一段时间的过度
当下
啰嗦了一大堆,有些伤感,回头看了下有用的并不多
magix最新版本3.8.10,magix-combine的最新版本是3.11.0。模板引擎不要再使用unerscore.template,请换用类mustache的模板,当然,不换也没问题,兼容的。局部刷新使用拆分字符串的方案应该不会再使用(旧项目有bug会继续修复),pc端目前使用真实dom diff,移动端没历史包袱可以使用虚拟dom diff,长远看都会切到虚拟dom上,当然,如果浏览器本身提供了增量更新,我们就不用这么费劲了。magix3版本里面的方案切换应该没有什么成本。
unerscore.template
pc
magix-combine看下 https://github.com/thx/magix-combine/blob/master/CHANGELOG.md 吧,想做一下magix-combine的分享,太多也太专了,讲的无聊,听的枯燥。今天看了下magix-combine,好像不是那么容易看懂。
实验中的功能:离线转虚拟dom,这个由magix-combine支持。dom diff按时间片更新,这个是看react的Time Slicing后做的。
react
Time Slicing
我会继续做magix与magix-combine,有些功能因为个人工作上的安排晚了些,但不会缺席。
github.com上的magix-gallery暂无精力维护,我们后台项目开发中使用的组件请使用虞佳维护的zs_gallery,组件使用等相关的问题可以直接联系虞佳
github.com
解决开发、调试、打包、发布工具的magix-cli工具由崇志维护,magix3统一了技术方案,magix-cli则统一了开发方式。这个工具在这里:http://gitlab.alibaba-inc.com/thx/magix-cli
magix-cli
2016年底有感于崇志、浩添去北京支援一淘商家后台项目,虽说当时我们的开发效率很高,我觉得还可以再突飞猛进,所以做了面向开发人员的可视化页面搭建:生成可供编译的代码而非线上页面。2017年集团可视化页面搭建遍地开花,而我们的则由宫卫默默无闻的开发,除了支持业务外,到目前仍然在持续完善中。这个工具在这里:http://gitlab.alibaba-inc.com/thx/magix-desiger ,附一个搭建gif图:https://img.alicdn.com/tfs/TB19JeNrL9TBuNjy0FcXXbeiFXa-1700-880.gif 现在开发一个页面只需要几分钟。重要的是以后普通页面会由运营搭建,彻底解放前端。
移动端的cell由竹隐在负责维护,我们移动端基本上都是由cell支持的,开发移动端页面的同学应该不陌生吧。
cell
还有很多想法,没有落地,一个人的时间和精力是有限的。
后记
以古作镜,可知兴替。技术的发展是飞速的,没有哪一套技术实现可以久远,相对不变的,唯思路尔。想在技术上长足的同学,不要留于使用的表面,走进喜欢的框架里,读懂作者的悲喜。犹记得木头曾聊过微软的htc技术,时至今日,微软自己的浏览器都不支持了吧,但是这种解决问题的思路,不还在react,vue上持续发光么,iframe标签不也在淡化,由新的方案替代么。
htc
iframe
没有什么是不能被淘汰的,要抓住本质。去理解他人的思路,方可一反三,去读懂他人的实现,方可知深坑,去按自己的想法实施,方可胜于蓝。
magix3缘起
我原本以为以
magix1.2
版本的稳定性可以支撑好些年,不曾想人在江湖,身不由己:出了一个magix
与brix
共用事件模块的magix2.0
版本。magix2.0
是在magix1.2
的基础上,把事件模块换成brix
提供的事件模块而已。在实际项目开发中,brix
提供的事件模块并不能有效的解决dom
变化事件需要解绑或绑定的问题。这是因为brix
的事件模块是扫描dom
节点找到有哪些事件,这样当dom
变化时,都要重新扫描,而dom
是否变化是在magix
的view
中由开发者做的,这就导致需要在view
中把所有与dom
变化的地方都要关注起来,从而可以在dom
变化的时候通知到brix
的事件模块。如果存在大量的dom
变化,事件这块的每次扫描整个dom
,性能并不怎么好。分久必合,通过
magix2.0
与brix
整合重复的部分,使我意识到仅仅做事件这块是不够的,模块的加载和实例化也是重复的,view
与brix
组件间的关系也是分不清楚的,那时候我被问的最多的一些问题:在项目中我应该把这个封装成brix
组件么?brix
组件里不能包含业务代码么?包含业务代码在我自己的项目里也是没问题啊?在brix
组件里我怎么能够使用magix
管理的接口?magix2.0
的一些事情没有做好,我们回过头来重新审视,总结经验:这些合并应该更彻底一些。magix3.0
,合并magix与brix,使view
与组件归一化,统一模板引擎。brix
抱歉了,有些必须割舍,包括brix
这个概念。原来的brix
组件变成magix
的view
,现在这些组件对应的view
在这里:magix-galllery模板引擎
许多问题皆源于它,时至今日仍然还在围着模板引擎转,使用合理的模板引擎,生成最优的目标代码,以达到高效的界面更新
合并后第一个挑战就是选择一个合适的模板引擎,统一我们之前在项目中用到的
mustache
,crox
,xtemplate
,vue
等各式各样的模板。underscore.template
,最后一版brix
用的模板引擎,也没有什么学习成本,magix3
就选择了它做为模板引擎。现在来看这个模板引擎的选择并不怎么好,但在当时要整合brix
,要升级组件库,许多方案只能先使用旧方案,减少新方案带来的坑和其它问题。统一,在当时显得更重要。就这样我们选择了underscore.template
模板写法。局部刷新之字符串拆分
如果
view
数据有变化,我们可以用最新的数据和模板生成最新的HTML
,然后通过view
根节点的innerHTML
属性更新界面。当然目前也可以通过dom diff
最细粒度的更新。不过那时候的需求是:找一种可以介于把整个view
粗犷的刷掉和最细粒度更新之间的方案。那就是以dom
节点与数据进行绑定的局部刷新,感谢波哥在这块的探索与实现,magix3
的首次使用的局部刷新就是该方案当时的局部刷新方案的弊端是:需要在待刷新节点上写上对应的数据
key
,如果对应key
的数据有变化时,则只刷新该节点下的innerHTML
,开发过直通车的同学应该有体会。有时候忘记写key
了,导致数据变化界面没刷新,如果多写了,则会有不必要的刷新。带着不完善的方案,
magix3
的使命完成:使用原有的经验,统一割裂的开发方式,减少概念上的认知。离线处理
处理不好性能的程序猿都是耍流氓。大概2015年底和波哥聊优化的事情,发现很多运行在线上的处理完全可以线下做,这样上线后可以减少计算,提升运行效率。同时因为是线下提前处理好的,可以通过查看结果来发现一些原来线上不能复现的问题。加上
magix
的本身也需要把html
合并到js
中,这时候magix-combine
就出来了。最初
magix-combine
只是合并文件,并做一些简单替换。第一个主要的离线处理是前面提到的
局部刷新之字符串拆分
,为了方便开发人员,不在节点上标记数据变化的key
,由程序自动识别完成。magix-combine
做这一个功能时,从一个文件到拆分成十几个文件,从简单的正则到复杂的parser
方案,前后持续时间最长,难度系数也最大,详细的技术方案可以查看这里 局部刷新与模板 。终于凭一己之力把它做了出来,也正是得益于该方案的实现,后续很多离线处理都在该功能的基础上顺利完成。第二个主要的离线处理是样式的
scoped
化,这里有记录在实施scoped
之前遇到的问题 关于style的scope。 样式scoped
方案线上处理的版本居多,但我们的要求是线下完成。参考过vue
给节点增加data-v-hash
的方式,私以为样式选择器从原来的标签或类选择器经过scoped
后加上了属性选择,浏览器在处理样式匹配上性能会下降。参考过css-modules
的做法,需要通过对象+旧选择器来使用变化后的选择器名称,很难和magix
这种js
与html
分离的开发方式结合起来,使用起来也不方便。同时要照顾开发人员,不能因为要使用scoped
功能就要做很大的变化。“无感使用”是我在做样式
scoped
时候的感受。我该如何引入新的功能而不用改变现有的开发方式?我该如何平滑稳定的把有问题的方案引导到新的方案上来?虽说不破不立,但同事的感受更重要,我不能太唐突的推进。我要实施新功能,我也要照顾现有的开发流程,如何在二者间平衡,很难。最终在不改变当前开发方式的情况下,实现了想要的功能,新的方案得以顺利实施。难,吾往矣!其实,一直在跟随着社区的发展,只是像前面所说的,有些功能的实现是无感知的,许多开发者在使用的时候或许并不知道我们早已默默应用了该技术。不过也正是由于我们自己的工具,可以把社区中一些优秀的方案在我们的项目中做的更彻底,能工具化的为什么要开发者参与呢?
第三个主要的离线处理是代码检查,之前我们的开发框架和组件可以快速的搭建出页面,但是如何保证产出的代码质量,如何让开发人员自己快速检查代码,如何避免别人踩过的坑,如何让别人的经验成为自己的经验,是我想解决,并且一定要解决的,尽管很难,If not me , who?
目前代码检测涵盖样式检查(书写要求、使用情况等),js代码循环检查(n层循环嵌套),js接口服务数据检查,模板命令语法检查,模板图片src属性检查,模板不建议使用的标签检查,模板危险属性检查,模板a或area标签检查,模板iframe标签检查,模板mx事件写法检查,模板mx-view检查,模板重复属性检查,模板命令语句中function及for of语句检查,模板标签配对检查等
把常见问题写到代码检测里面去!把别人的经验写到代码检测里面去!把需要掌握的知识点写到代码检测里面去!授鱼不如授渔
所以2016-2017年我的精力都放在
magix-combine
上,尽管有些事情远远超出离线处理
这个愿景。我回来了
老实说,在我做
magix-combine
这段时间里,magix
除必要的支持外并没有怎么跟进,不过我终于忙完magix-combine
回来了。他们说
underscore.template
语法写多了比较乱,好的,支持类mustach的模板语法。他们说局部刷新使用字符串模板拆分的方式仍然刷新的范围太大了,而且社区里都是细粒度的刷新,好的,https://github.com/thx/magix/blob/master/src/tmpl/dom.js。真实dom
与真实dom
的diff
,真实dom
与虚拟dom
的diff
,虚拟dom
与虚拟dom
的diff
,满足你的一切好奇心。我说历史的原因,我们的
dom
转换是在线上完成的,这显然应该在线下做,jsx
的是不错的首选,好的,使用jsx去写magix,感谢竹隐的支持。我说根据同事间的调查,并不是每个人都乐意使用jsx
,而且刚熟悉的类mustache
写法要丢弃么,好的,支持类quickapp形式的模板。我说这些加载器requirejs
,seajs
,webpack
都是过客,浏览器原生的import
才是主场,好的,https://github.com/thx/magix/tree/master/src/module你有问题我有解决方案,最美好的事情不过如此吧?
局部刷新之dom diff
magix3
提供了比较多的diff
,目前线上用的是真实dom
之间的diff
,这是要照顾一下开发人员还有部分组件,时间久了都会有一些技术债。真实dom diff
可以操作dom
,而使用虚拟dom
是无论如何都不能操作真实dom
的,所以目前我们想直接用虚拟dom
还需要一段时间的过度当下
啰嗦了一大堆,有些伤感,回头看了下有用的并不多
magix最新版本3.8.10,magix-combine的最新版本是3.11.0。模板引擎不要再使用
unerscore.template
,请换用类mustache
的模板,当然,不换也没问题,兼容的。局部刷新使用拆分字符串的方案应该不会再使用(旧项目有bug会继续修复),pc
端目前使用真实dom diff
,移动端没历史包袱可以使用虚拟dom diff
,长远看都会切到虚拟dom
上,当然,如果浏览器本身提供了增量更新,我们就不用这么费劲了。magix3
版本里面的方案切换应该没有什么成本。magix-combine
看下 https://github.com/thx/magix-combine/blob/master/CHANGELOG.md 吧,想做一下magix-combine
的分享,太多也太专了,讲的无聊,听的枯燥。今天看了下magix-combine
,好像不是那么容易看懂。实验中的功能:离线转虚拟
dom
,这个由magix-combine
支持。dom diff
按时间片更新,这个是看react
的Time Slicing
后做的。我会继续做
magix
与magix-combine
,有些功能因为个人工作上的安排晚了些,但不会缺席。github.com
上的magix-gallery暂无精力维护,我们后台项目开发中使用的组件请使用虞佳维护的zs_gallery,组件使用等相关的问题可以直接联系虞佳解决开发、调试、打包、发布工具的
magix-cli
工具由崇志维护,magix3
统一了技术方案,magix-cli
则统一了开发方式。这个工具在这里:http://gitlab.alibaba-inc.com/thx/magix-cli2016年底有感于崇志、浩添去北京支援一淘商家后台项目,虽说当时我们的开发效率很高,我觉得还可以再突飞猛进,所以做了面向开发人员的可视化页面搭建:生成可供编译的代码而非线上页面。2017年集团可视化页面搭建遍地开花,而我们的则由宫卫默默无闻的开发,除了支持业务外,到目前仍然在持续完善中。这个工具在这里:http://gitlab.alibaba-inc.com/thx/magix-desiger ,附一个搭建gif图:https://img.alicdn.com/tfs/TB19JeNrL9TBuNjy0FcXXbeiFXa-1700-880.gif 现在开发一个页面只需要几分钟。重要的是以后普通页面会由运营搭建,彻底解放前端。
移动端的cell由竹隐在负责维护,我们移动端基本上都是由
cell
支持的,开发移动端页面的同学应该不陌生吧。还有很多想法,没有落地,一个人的时间和精力是有限的。
后记
以古作镜,可知兴替。技术的发展是飞速的,没有哪一套技术实现可以久远,相对不变的,唯思路尔。想在技术上长足的同学,不要留于使用的表面,走进喜欢的框架里,读懂作者的悲喜。犹记得木头曾聊过微软的
htc
技术,时至今日,微软自己的浏览器都不支持了吧,但是这种解决问题的思路,不还在react
,vue
上持续发光么,iframe
标签不也在淡化,由新的方案替代么。没有什么是不能被淘汰的,要抓住本质。去理解他人的思路,方可一反三,去读懂他人的实现,方可知深坑,去按自己的想法实施,方可胜于蓝。