您好,欢迎来到花图问答。
搜索
您的当前位置:首页深入Weex中的transformer实现原理(上篇)

深入Weex中的transformer实现原理(上篇)

来源:花图问答

0x1 读完后希望你会

  • 了解Weex中,we脚本的各个标签<template><script><style>解析实现方式,如何生成可以运行的js脚本文件。
  • 基于标签tag,自己实现一套你喜欢的类似we或者微信小程序的脚本语言。
    • 可以包含表达式计算
    • 流程控制

0x2 背景

目前线上App接入的weex版本为0.8.X,距目前最新的0.10.X系列跨度相差较大,但是在保证目前业务稳定的前提下,不能直接升级Weex SDK到最新版。

在升级前期,不得不面对的几个问题:

  • 目前已开发的大量.we页面是否可以在新版Weex运行。
  • 继续使用已被废弃的we脚本开发新需求(Weex已经推荐用vue来写页面)
    • Vue与Weex两大生态的联手,Weex官方也在推进vue来编写界面.
    • we脚本将来很有可能面临不再被扩展维护,也就是weex很多的新特性在we中不一定会被支持,除非we与vue的feature更新节奏保持一致。
    • 据说手淘与猫客已不再使用we编写weex,而是全部采用vue(求证)。
    • Vue自身生态庞大,对vue更好的支持,反而更利于weex的推广。

所以在升级之前,以weex的transform流程原理为开端,展开一些前期的调研工作,顺便学习一下weex的toolkit实现原理。
据weex的同学说新版的weex是可以跑老we的,不过要保证we脚本代码的严谨性,因为新版的jsf runtime校验机制,更加严格,某些页面可能白屏(What?!!)。
老话常谈,“Talk is cheap,Show me the code”。

0x3 验证思路

一个we页面被渲染执行,可以大致拆分为两部分。
【.we脚本的打包与编译】(weex/vue loader,生成标准的js脚本)

    [.we] -> [build] -> output [*.js]

【Weex JS 运行时环境(JSF)】(负责解析运行编译好的js脚本)

    [*.js] -> [weex runtime] -> render [view:page]
Weex模块构成.png

从图中可以看出 Weex 整体的工作流程。
首先开发者编写 .we 文件。
通过 weex-toolkit 提供的工具将 .we 文件转为js。

JS Framework 接收并执行 js 的代码,执行数据绑定、模板编译等操作,然后输出 json 格式的 Virtual DOM 传递给移动端。

这篇文章主要分析第一层的transformer的实现原理。

0x4 we/vue 脚本是如何被解析的

weex-loader首先通过parse5 得到we文本的json 结构的树结构,
然后Weex-loader的处理流程中,针对不同标签(<template/> <script/><style/>),分别有对应的解析处理模块,

Paste_Image.png

大致流程如上图,从左向右依次为:
1.输入为原始we脚本文件。
2.通过parse5组件解析出对应的jsonobject
3.根据json object中描述的各部分tag交给对应的处理模块。

例如一个template标签的json对象,在loader中是这样被处理的,

Paste_Image.png

源码地址: weex-loader/lib/loader.js

不同的标签类型文本会分配给专门的parse组件.

Paste_Image.png

源码地址:weex-loader/lib/parser.js

标签对应的处理模块如下:
<script> 标签 ————> weex-templater
<style > 标签 ————> weex-styler
<script> 标签 ————> weex-scripter

0x5 weex-styler 简介以及CSS预备知识

一张图看懂CSS构成.

A CSS rule-set consists of a selector and a declaration block:

Paste_Image.png

rule-set:包含一个selector 以及多个declaration。
selector:样式选择器,主要用来定位元素
declaration:定义样式属性以及值。

了解这三个基本概念之后,看scripter也是轻车熟路了,快上车。
scripter当中,通过css parser得到AST json object,读取ast.stylesheet.rules获得到当前样式的rule-set,然后遍历所有的declaration,校验样式是否被weex所支持的(因为weex中支持css的样式有限),以及简单的value字段合法性校验。

![Uploading Paste_Image_374004.png . . .]

源码:/weex-styler/index.js

weex-styler新老版之差异。

对Pseudo class样式进行了支持。

Paste_Image.png

新版weex中,支持shorthand writing写法的transition样式。

// shorthand writing 
div {
    transition: width 2s linear 1s;
}

div {
    transition-property: width;
    transition-duration: 2s;
    transition-timing-function: linear;
    transition-delay: 1s;
}

0x6 weex-templater 简介

解析we脚本中的<template/>标签内容,其核心节点数据结构也是基于parse5解析出的json object,同时也会做数据绑定,标签验证,自动修复common错误的处理。

<template>
  <div if={{x}}>
    <text onclick="toggle">Toggle: {{result}}</text>
  </div>
</template>
  • 数据绑定:
    <text>标签内的value,”Toggle: {{result}}”,
    <div>标签内的attribute if 中的 “{{x}}”,
    也就这种用户可以编辑的文本段,需要对包含的表达式以及变量进行处理,这里的实现就在var exp = require('./exp’)这个模块当中,

该exp函数有2个参数,需要转换的字符串文本,以及是否需要转换成function对象。

![Uploading Paste_Image_402398.png . . .]

/weex-templater/lib/exp.js

将双引号“替换为单引号’,去除所有\n换行控制字符。
判断文本中是否包含表达式,如果不包含,直接返回原始文本。
根据生成的token列表,
文本会在两端加入单引号’
表达式在两端(),显式的加入运算优先级。
比如Toggle: {{result}} => [‘\’Toggle:\’’,’(result)’]
这样在最后,只需要把结果列表中的所有元素做一次’+’.join操作,就可以构成了一个合法的js语句。

  • 事件绑定:
    text中的onclick属性的值,templater会自动生成可以调用toggle函数的js代码。当标签的属性名包含on前缀时,将进行事件绑定。
Paste_Image.png

weex-templater/index.js

在checkEvent方法中,通过把封装好的function描述字符串eval对象赋值给value,达到事件发生时触发函数的机制。


Paste_Image.png
  1. 【else】 validation:当遍历到一个节点中包含else时,就会验证前一个节点中是否包含了if。
  2. Tag(标签)validation:
    Tag的验证相对多一点,因为不同的tag会有其特殊的规则,
    例如最外层的<template/>只能包含一个root子节点。
    container类型的标签可以嵌套标签,非container则不可。
    <cell>标签可以自动补全tree属性。
  3. <text>标签比较特殊,因为text里面可以包含任意的字符串,变量,表达式,
    例如下面的脚本。
  • 修复一些简单的common问题。
    举个例子,比如图像内容,既可以写成<img>也可以写成<Image>,在templater中是有处理的。

源码地址:weex-templater/lib/validator.js

Copyright © 2019- huatuowenda.com 版权所有 湘ICP备2023022495号-1

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务