成都创新互联网站制作重庆分公司

如何让小程序支持JSX语法

今天小编给大家分享一下如何让小程序支持JSX语法的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。

成都创新互联公司是一家集网站建设,双柏企业网站建设,双柏品牌网站建设,网站定制,双柏网站建设报价,网络营销,网络优化,双柏网站推广为一体的创新建站企业,帮助传统企业提升企业形象加强企业竞争力。可充分满足这一群体相比中小企业更为丰富、高端、多元的互联网需求。同时我们时刻保持专业、时尚、前沿,时刻以成就客户成长自我,坚持不断学习、思考、沉淀、净化自己,让我们为更多的企业打造出实用型网站。

现有思路的局限

在介绍新的思路之前,我们先来看下Taro(最新版1.3),nanachi是怎么在小程序端处理JSX语法的。简单来说,主要是通过在编译阶段把JSX转化为等效的小程序wxml来把React代码运行在小程序端的。

举个例子,比如React逻辑表达式:

xx && Hello

将会被转化为等效的小程序wx:if指令:

Hello

这种方式把对JSX的处理,主要放在了编译阶段,他依赖于编译阶段的信息收集,以上面为例,它必须识别出逻辑表达式,然后做对应的wx:if转换处理。

那编译阶段有什么问题和局限呢?我们以下面的例子说明:

class App extends React.Component {

    render () {

        const a = Hello

        const b = a

        return (

           

                {b}

           

        )

    }

}

首先我们声明 const a = Hello,然后把a赋值给了b,我们看下最新版本Taro 1.3的转换,如下图:

这个例子不是特别复杂,却报错了。

要想理解上面的代码为什么报错,我们首先要理解编译阶段。本质上来说在编译阶段,代码其实就是‘字符串’,而编译阶段处理方案,就需要从这个‘字符串’中分析出必要的信息(通过AST,正则等方式)然后做对应的等效转换处理。

而对于上面的例子,需要做什么等效处理呢?需要我们在编译阶段分析出b是JSX片段:b = a = Hello,然后把{b}中的{b}等效替换为Hello。然而在编译阶段要想确定b的值是很困难的,有人说可以往前追溯来确定b的值,也不是不可以,但是考虑一下 由于b = a,那么就先要确定a的值,这个a的值怎么确定呢?需要在b可以访问到的作用域链中确定a,然而a可能又是由其他变量赋值而来,循环往复,期间一旦出现不是简单赋值的情况,比如函数调用,三元判断等运行时信息,追溯就宣告失败,要是a本身就是挂在全局对象上的变量,追溯就更加无从谈起。

所以在编译阶段 是无法简单确定b的值的。

我们再仔细看下上图的报错信息:a is not defined。

为什么说a未定义呢?这是涉及到另外一个问题,我们知道Hello,其实等效于React.createElement(Text, null, 'Hello'),而React.createElement方法的返回值就是一个普通JS对象,形如

// ReactElement对象

{

   tag: Text,

   props: null,

   children: 'Hello'

   ...

}

所以上面那一段代码在JS环境真正运行的时候,大概等效如下:

class App extends React.Component {

    render () {

        const a = {

            tag: Text,

            props: null,

            children: 'Hello'

            ...

        }

        const b = a

        return {

            tag: View,

            props: null,

            children: b

            ...

        }

    }

}

但是,我们刚说了编译阶段需要对JSX做等效处理,需要把JSX转换为wxml,所以Hello这个JSX片段被特殊处理了,a不再是一个普通js对象,这里我们看到a变量甚至丢失了,这里暴露了一个很严重的问题:代码语义被破坏了,也就是说由于编译时方案对JSX的特殊处理,真正运行在小程序上的代码语义并不是你的预期。这个是比较头疼。

新的思路

正因为编译时方案,有如上的限制,在使用的时候常常让你有“我还是在写React吗?”这种感觉。

下面我们介绍一种全新的处理思路,这种思路在小程序运行期间和真正的React几无区别,不会改变任何代码语义,JSX表达式只会被处理为React.createElement方法调用,实际运行的时候就是普通js对象,最终通过其他方式渲染出小程序视图。下面我们仔细说明一下这个思路的具体内容。

第一步:给每个独立的JSX片段打上唯一标识uuid,假定我们有如下代码:

const a = Hello

const y =

   

   

我们给a片段,y片段 添加了uuid属性

第二步:把React代码通过babel转义为小程序可以识别的代码,例如JSX片段用等效的React.createElement替换等

const a = React.createElement(Text, {

  uuid: "000001"

}, "Hello");

第三步:提取每个独立的JSX片段,用小程序template包裹,生成wxml文件