最近看了hera,一款17年微店出的小程序sdk,正好可以加深对小程序架构的理解,这篇权当总结一下。
我们都知道小程序是双线程架构,渲染和脚本是分开执行的,具体术语是view层和service层,view 和 service通过bridge进行通信,在hera的h5模式中,可以抽象地理解成事件的发布订阅。view的渲染数据依赖于service传过来的数据,当然大家都知道肯定需要这样,不然怎么算双线程模式呢。接下来简单讲讲hera h5模式中的打包编译过程。
hera的打包编译过程,简单的来说,分为以下几步,首先扫描目录,把非js的文件等直接拷贝过去,第二,读取项目配置,把其他非路由js文件合并成一个文件,类似common文件把,然后我们pages的js文件babel编译过去到原来的目录下面,第三,把hera framework也拷贝过去,这个后面会找着重讲,三步完成之后,我们就启动一个web服务器,我们访问的时候,会根据app.json生成的路由去寻找对应的页面,这里需要注意的是,前面第二部生成page对应文件的时候,把这个page的wxml、wxss、js都合并成一个文件了,里面有分割界定符,在我们初次访问的时候,会从这个文件中分割出来,创建一个container容器塞到我们的body,然后把wxss塞到这个容器里面,把编译我们的wxml,生成渲染函数,这里不着急执行,因为渲染函数依赖js传递过来的数据,所以就是wxml生成渲染函数之后,view层准备就绪,servie层也在完成page路由注册之后,把page需要的数据传递过去,但是如果page在view还没ready的时候,多次的setdata会合并,当service也准备好的时候,就通过bridge把数据传递给view层完成初次的渲染,view层也会受到数据后,生成virtual dom,最后渲染出页面,当再次数据发生变化的时候,进行virtual dom diff,这个没什么好讲的。
这里有几个点,挑出来讲下。首先,我们不是说,每个page路由都被打包成一个文件了吗,但是我们在打开控制台的时候,能够发现page路由wxml、wxss、js好好地一一对应着,这就是source-map的功劳了,new Function 执行的之后,会在尾部加上sourcemap地址,这样浏览器就能识别出来了,同时也会对每次分割的结果进行一个cache缓存。第二,wxml、wxss的解析,可以使用微信自动的二进制编译,也可以使用npm第三方的complier,但是有个很有趣暴力的一点,内部组件template文本节点就是通过{{和}}进行split分割,然后拼凑生成html,依赖的收集也是很简单有趣。还有对全局变量的屏蔽,其实就是page模块会被包在amd 里面,里面的立即生成函数后面几个参数就是全局变量名,相当于直接被undefined了。
大致小程序 h5版原理就是这样的双线程模式,虽然也许别人一问小程序原来是什么,可能会不经思考地说双线程模式,但是仔细研究hera的运行原理之后,真的是绝知此事要躬行,工程远不止字面那么简单。