VUE 组件转换为微信小程序组件的方法

发布日期:2025-01-03 18:20    点击次数:75

简介: 首先我们介绍一下本文的关键点:抽象语法树,它是以树状的形式表现编程语言的语法结构,树上的每个节点都表示源代码中的一种结构。 通过操作这棵树,可以精确的定位到声明、赋值、运算语句,从而实现对代码的优化、变更等操作。 本文通过对 VUE 组件的 JavaScript 、CSS模块进行转换,比如 JavaScript模块,包括外层对象,生命周期钩子函数,赋值语句,组件的内部数据,组件的对外属性等等来实现把一个 VUE 组件转换为 一个小程序组件。 AST 抽象语法树,似乎我们平时并不会接触到。实际上在我们的项目当中,CSS 预处理,JSX 亦或是 TypeScript 的处理,代码格式化美化工具,Eslint, Javascript 转译,代码压缩,Webpack, Vue-Cli,ES6 转 ES5,当中都离不开 AST 抽象语法树这个绿巨人。先卖个关子,让我们看一下 AST 到的官方解释: It is a hierarchical program representation that presents source code structure according to the grammar of a programming language, each AST node corresponds to an item of a source code. 中文的解释有: 抽象语法树(abstract syntax tree或者缩写为 AST ),或者语法树(syntax tree),是源代码的抽象语法结构的树状表现形式,这里特指编程语言的源代码。和抽象语法树相对的是具体语法树(concrete syntaxtree),通常称作分析树(parse tree)。一般的,在源代码的翻译和编译过程中,语法分析器创建出分析树。一旦 AST 被创建出来,在后续的处理过程中,比如语义分析阶段,会添加一些信息。 抽象语法树,它以树状的形式表现编程语言的语法结构,树上的每个节点都表示源代码中的一种结构。 通过操作这棵树,可以精确的定位到声明、赋值、运算语句,从而实现对代码的优化、变更等操作。这些并不是我们想要看到的。 对于 AST 面纱的神秘感,似乎已经将要揭开。不错,在我刚接触到他的时候,同样感觉确实是难。但是当你开始了解了它以后,你就会越来越喜欢它。 因为他实在太强大了。AST 本身并不难,难点在于转换的目标对象与源对象的语法差异,当中水深毋庸置疑。但是,这才能更加激起我们探索他的欲望。在开始之前,我们先看一下 抽象语法树到底长什么样子。 一、 一探究竟 AST 通过 astexplorer [1] (AST树查看网站),通过他你可以方便的查看代码的语法树,挑你喜欢的库。你可以在线把玩 AST,而且除了 JavaScript,HTML, CSS 还有很多其它语言的 AST 库,让我们对他有一个感性而直观的认识。 请看下图,看看AST语法树长什么样子: 此图看到的是一个 ExportDefaultDeclaration 也就是export default {},还有他的位置信息,注释失信,tokens等等。 国际惯例,先来一个小demo 输入数据 处理数据 输出数据 我们看一下我们得到的 AST 树 接下来我们插入一段 把 VUE 组件转换为微信小程序组件正则版本的处理 二、 简单粗暴的版本(VUE 组件转换为微信小程序组件) 没有使用 AST 将 VUE 组件转换成小程序组件的简易版本介绍 下方是两段代码,简单的逻辑,实现思路,匹配目标字符串,替换字符,然后生成文件。 上方是正则版本的一些模板匹配规则,经过后续的一系列处理把一个 VUE组件处理得到对应的小程序的 WXML ,WXSS,JSON,JS,4个文件。 上方是处理得到的 WXML ,WXSS,JSON,JS,4个文件,并且生成到对应的目录下。代码实现用时较短,后续更改方案,并没有做优化,这里就不做详细展开讨论这个实现方案了。 回到正题 介绍一下,AST 抽象语法树的核心部分: 三、 抽象语法树三大法宝 Babel 是 JavaScript 编译器,更确切地说是源码到源码的编译器,通常也叫做“ 转换编译器(transpiler)”。 意思是说你为 Babel 提供一些 JavaScript 代码,Babel 更改这些代码,然后返回给你新生成的代码。 babel-core:Babel 的编译器;它暴露了 babel.transform 方法。 [1] babylon:Babylon 是 Babel 的解析器。用于生成 AST 语法树。 [2] babel-traverse:Babel 的遍历器,所有的transformers都使用该工具遍历所有的 AST (抽象语法树),维护了整棵树的状态,并且负责替换、移除和添加节点。我们可以和 Babylon 一起使用来遍历和更新节点。 [3] babel-generator:Babel 的代码生成器。它读取AST并将其转换为代码。 整个编译器就被分成了三部分:分析器、转换器、生成器,大致的流程是: 输入字符串 -> babylon分析器 parse -> 得到 AST -> 转换器 -> 得到 AST -> babel-generator -> 输出 总结核心三步: AST 三大法宝 babylon.parse => traverse 转换 AST => generate(ast, {}, code).code) 生成 感兴趣的童鞋,可以在网上或者看参考资料都有介绍。该铺垫的都铺垫的差不多了,进入正题。 我们到底是如何通过 AST 将 VUE 组件转换为微信小程序组件的呢? 四、 VUE 组件转换为微信小程序组件中 组件的对外属性、赋值语句的转换处理 转换之前的 VUE 组件代码 Demo 处理后我们得到的微信小程序组件 JavaScript 部分代码 我们对js动了什么手脚(亦可封装成babel插件): 转换之前的js代码的部分 AST 树: 具体的 API 使用,童鞋们看一下 babel 相关的文档了解一下。 五, VUE 组件转换为微信小程序组件中 Export Default 到 Component 构造器的转换 与 生命周期钩子函数,事件函数的处理 首先我们看一下要转换前后的语法树与代码如下(明确转换目标): 转换之前的 AST 树与代码 转换之后的 AST 树与代码 通过以上转换之前和转换之后代码和 AST 的对比我们明确了转换目标就是 ExportDefault 到 Component构造器的转换,下面看一下我们是如何处理的: 我们做了什么(在转换中进入到 ExportDefault 中做对应的处理): 对于 ExportDefault => Component 构造器转换还有一种转换思路 下面我们看一下: [1] 第一种思路是先提取 ExportDefault 内部所有节点的 AST ,并做处理,然后创建Component构造器,插入提取处理后的 AST,得到最终的 AST [2] 第二种思路呢,就是我们上面展示的这种,不过有一个关键的地方要注意一下: 如果你想在 AST 开始处与结尾处插入,可使用 path 操作: 注:关于微信小程序不支持 computed , 与 watch,我们具体的初期采用的方案是挂载 computed 和 watch 方法到每一个微信小程序组件,让小程序组件也支持这两个功能。 六,VUE 组件转换为微信小程序组件中 的 Data 部分的处理: 关于 Data 部分的处理实际上就是:函数表达式转换为对象表达式 (FunctionExpression 转换为 ObjectExpression) 转换之前的 JavaScript 代码 处理后我们得到的 通过如上的代码对比,我们看到了我们的转换前后代码的变化: 转换前后 AST 树对比图明确转换目标: 我们对 JavaScript 动了什么手脚(亦可封装成babel插件): 我们的转换部分都尽量在一个 Traverse 中处理,减少 AST 树遍历的性能消耗 七,VUE 组件转换为微信小程序组件中 CSS 部分的处理: 那 CSS 我们也是必须要处理的一部分,let try 以下是我们要处理的css样本 处理后我们得到的 通过前后代码的对比,我们看到了单位尺寸的转换(比如:top: 50px; 转换为 top: 117rpx;)。 单位的转换( px 转为了 rpx ) CSS 又做了哪些处理呢? 同样也有不少的 CSS Code Parsers 供我们选择 Cssom ,CssTree等等, 我们拿 Cssom 来实现上方css代码的一个简单的转换。 当然这只是一个 demo,实际项目中使用还的根据项目的实际情况出发,SCSS,LESS等等的转换与考虑不同的处理场景哦! 注:本文有些模块的转换实现还未在小程序开发工具中测试。 插播一个通过 AST 实现的好东东: 将 JavaScript 代码转化生成 SVG 流程图 js2flowchart( 4.5 k stars 在 GitHub ) 当你拥有 AST 时,可以做任何你想要做的事。把AST转回成字符串代码并不是必要的,你可以通过它画一个流程图,或者其它你想要的东西。 js2flowchart使用场景是什么呢?通过流程图,你可以解释你的代码,或者给你代码写文档;通过可视化的解释学习其他人的代码;通过简单的js语法,为每个处理过程简单的描述创建流程图。 马上用最简单的方式尝试一下吧,去线上编辑看看 js-code-to-svg-flowchart [8]。 此处有必要附上截图一张。 八、总结: 通过以上我们的介绍,我们大概对抽象语法树有了初步的了解。总体思路是:我们用Babel的解析器 把 JavaScript 源码转化为抽象语法树, 再通过 Babel 的遍历器遍历 AST (抽象语法树),替换、移除和添加节点,得到一个新的 AST 树。最后, 使用,Babel 的代码生成器 Babel Generator 模块 读取 处理后的 AST 并将其转换为代码。任务就完成了! 本文通过对 VUE 组件转换为微信小程序组件的转换部分包括如下内容: VUE 组件 JavaScript模块 对外属性转换为小程序对外属性的处理 VUE 组件 JavaScript模块 内部数据的转换为小程序内部数据的处理 VUE 组件 JavaScript模块 methods 中的赋值语句转换为小程序赋值语句的处理 VUE 组件 JavaScript模块 外层对象,生命周期钩子函数的处理与 CSS 模块的简易处理 总结 以上所述是小编给大家介绍的VUE 组件转换为微信小程序组件的方法,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持! 如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!