flutter语法
swiftUI语法
为什么想要尝试oop开发ui界面
由于同一种语法之间的互操作,比两种语法之间的互操作要容易和灵活的多,所以web前端能不能也像flutter和swiftUI那样使用oop语法那样更灵活的开发ui呢,于是我开始了尝试
OVS(object view js)
我为他命名为ovs(object view js),一种面向对象的视图ts扩展语法,目前还仅仅是一个最简示例demo,但接下来我会持续完善这个语法
语法
div{
'hello world',
button({style: { color: 'red' }}){ 'click me' }
}
经过编译会转换为
h('div', [
'123',
h('button',{style: { color: 'red' }},'click me')
])
目前对这个语法的支持是在vue渲染函数的基础上实现的
实现思路
ovs语法只是一种语法糖,他完全等同于vue的渲染函数,所以我要做的仅仅是在编译阶段,将ovs语法转为vue的渲染函数即可
扩展后的typescript语法,不能再是.ts文件,因为他不是标准的ts语法,所以需要新建一种文件类型为.ovs
开发环境和三方依赖
开发环境是 vite + vue, 代码转换使用 chevrotain + typescript 实现,
具体实现
开发一个vite插件(vite-plugin-ovs),让vite可以识别.ovs后缀的文件
使用此插件,并配置vue处理ovs,因为是基于vue的渲染函数实现的,所以需要vue处理编译后的逻辑
将读取到的ovs中的代码,转换为原生ts代码
寻找支持ovs语法的编译器
- 我们需要识别ovs语法的代码,由于这是我们自创的语法,所以是没有其他编译器支持这种结构的,所以我们必须自己创建支持这个语法的编译器,
放弃编译器babel,babel不支持扩展js语法
经历了一天多的了解,我首先尝试了babel,发现babel并不支持自定义语法,babel对于ts的扩展语法都是内置插件,所有插件对语法的支持也都是因为已经内置了对语法的支持,只是通过配置项开启和关闭而已
放弃编译器acorn,仅支持js,不支持ts
放弃编译器typescript、typescript-eslint 等
不支持语法扩展插件,需要修改源码,太重了,后续维护问题,还有需要对源码的高度理解,都劝退了我
支持任意自定义语法的编译器,chevrotain
经过不断地了解,pegjs、antrl4等等各种支持自定义语法的js编译器,我找到了一个最简单易用的编译器,chevrotain,
大部分自定义编译器都需要使用ebnf语法定义语法,需要使用一种js之外的语言定义语法,然后将定义好的语法经过编译成为代码,在使用这个经过编译生成的代码来处理你需要处理的代码,这就有点麻烦了,antrl4就是这样
chevrotain却简单了很多,他完全使用js,不涉及ebnf语法,这是我选择他的原因,他还有很多好处,比如性能更快等等,大家可以去官网了解
使用chevrotain处理ovs语法,生成cst
但是chevrotain的解决方案也不是那么完美,chevrotain官方仅仅提供了ecma5语法的语法文件,这代表着要支持typescript还需要扩展ecma5的语法,幸运的是chevrotain支持语法扩展,使得这个难度没那么大,但依旧不小
目前我还没有做到这个阶段,目前还是只将ovs转为es5,没有转为ts
- 扩展chevrotain的es5语法支持ovs,继承ECMAScript5Parser,定义一个名为OvsDomRender的新语法,
语法定义
// (参数) 可选,元素数组可选 标识符(){ 元素数组 }
这样chevrotain就可以支持ovs语法了,经过chevrotain处理,我们就可以得到chevrotain处理后的cst了
将chevrotain处理后得到的cst转换为typescript的ast
- 这部分就是自己手撸代码了,没找到什么方便取巧的办法,总之就是将 chevrotain 处理
div{
'hello world',
button({style: { color: 'red' }}){ 'click me' }
}
得到的cst,转为
h('div', [
'123',
h('button',{style: { color: 'red' }},'click me')
])
对应的typescript的ast,两种数据结构的转换,自己想办法对应上就行了
将typescript的ast转为vue渲染函数代码
这部分比较简单,直接调用typescript的api就行了,通过printer对象实现,printer对象为typescript编译器的内置对象,得到渲染函数代码
将渲染函数代码放到vue的render函数中,返回
放到vue的render函数中,然后将这个vue文件交给vue处理
页面正确渲染了
灵感来源
- 灵感来自于很久以前,但以前只是想了想
前端能否参考swiftui和flutter开发一个不使用html的面向对象的UI框架?
- 最近开发,而且又被模板和jsx语法搞得头痛,我的业务需要开发一个基础界面模板,同时又需要使用者可以对基础模板进行各种插槽,对已有界面部分内容进行重写,使用vue插槽来实现,需要定义各种插槽,很麻烦
于是最近又提了一系列相关问题
- 最终还是自己决定尝试试一试
专栏
相关推荐
【编译原理创新尝试(一)】parser代码解析篇:不再写代码生成器generator,用类ebnf语法实现不同编程语言的自动转换,200行js示例入门编译原理
【编译原理创新尝试(二)】generator代码生成篇:不再写代码生成器generator,用类ebnf语法实现不同编程语言的自动转换
结尾
本人菜鸡,文中的不足之处,请谅解
如果本文的思路存在问题,或者有更便捷的实现方式,希望您能告知,不足之处也请您指出,非常感谢
本文只是尝试一种新思路,仅为一个简单demo,细节处理中存在漏洞,请谅解
特别鸣谢 chatGPT,chevrotain,vue
-
如果在没有chatGPT之前,完全无法想象这是我这个菜鸡可以做的事情,chatGPT扩展了我的能力边界,使我可以去尝试那些原本能力之外的事
-
chevrotain,可以通过js的语法扩展js的语法,让自定义语法变的很简单,部分初始灵感来自于chevrotain
-
感谢vue的render函数,没有render函数,ovs做起来也没这么简单