铺垫
随着大前端蓬勃发展, 冒出越来越多的端, 最火的当数最近出现的微信小程序. 但是无论是 微信小程序 , 还是 支付宝小程序, 或者 快应用 都有一个明显的缺点, 虽然他们还是按照一定的 js html css 标准作为开发方式, 但是他们都与当前所有主流技术有相当大的壕沟.
虽然小程序使用类似Vue, angular的模板渲染, 实现了类MVVM的开发方式.但是小程序的开发方式相当蛋疼. 以下是一个简单小程序的目录结构:
上述目录只包含页面内容, 开发过程中需要不断在不同文件中切换. 相比React的Component+css 和 Vue的单文件来看, 开发体验不太好. 并且很多小程序开发者都是vue、React、angular等等前端框架的使用者, 使用熟悉的开发栈对他们来说更容易上手.
小程序的本质
在开发一个工具前要理解运行载体的原理. 正如我们希望用React去开发小程序, 那么我们必须要了解小程序的原理.
因为小程序是闭源的, 我只能在自己的猜想上分析. 但是小程序的底层是Native 这是前提. 那么我猜想小程序的实现原理应该跟ReactNative类似, 通过js bridge搭建js和原生通信的桥梁, 由js及模板, 实现对页面的渲染描述.
但是小程序与ReactNative的不同点是, ReactNative对js层开放renderer api. 而小程序则对这层进行了封装. 这让我们无法通过重新实现React的renderer来使用React的一些特性(如vdom).
所以我的思路是通过语法转换, 把React文件转换成小程序工程文件. 并实现小程序的框架, 来对接小程序与react的生命周期方法.
期望
我希望能把React文件, 经过编译后, 变成可执行的微信小程序
import Page from '../wechat'import './page.css'class P extends Page { onClick(){ } render() { return (威武) }}复制代码
开始我们的旅程
有了开发小程序的思路, 那我们就来动手. 我使用了babel作为语法转换的工具, 我们先开个头. 下面是转换的核心代码
function transform(code, sourcePath) { let output = { wxml:'', wxss:'', js:'', json:'', type:''//App||page||component } sharedState.sourcePath = sourcePath; const result = babel.transform(code, { babelrc: false, plugins: [ '@babel/plugin-syntax-jsx', transformPlugin, '@babel/plugin-proposal-object-rest-spread', ['@babel/plugin-proposal-decorators',{ "legacy": true}] ] }) // tranform后, 结果都会写入sharedState.output output = sharedState.output; const obj = t.objectExpression(sharedState.methods); output.js = generate(obj).code; sharedState.reset(); switch(output.type){ case 'App': output.js = CodeWrapper('App', output.js); break; default: //Page output.js = CodeWrapper('Page', output.js); break; } return output;}复制代码
该部分代码实际上就是通过babel 对React代码文件进行处理, 处理后把结果写入到output. 重点在于, 我们通过babel.transform这个方法, 把代码拆分成四块, 分别写入到sharedState.output中.
最终通过一些简单处理后, 返回output, 不难看出output中的wxss, js, json, wxml就是一个小程序页面/组件的代码文件.
其中 transformPlugin
是自定义的编译插件. 今天有点晚先到这里, 下期继续讨论插件开发思路.
项目代码: https://github.com/PepperYan/react-miniapp)
喜欢这篇文章的大佬, 点个赞和star, ٩(๑´0`๑)۶
该项目参考了mpvue, taro, weact等. babel-traverse和babylon
还有感谢 @方正 提点
原文链接: https://zhuanlan.zhihu.com/p/38102065