steven026 发表于 2023-7-3 17:17:58

本帖最后由 steven026 于 2023-7-3 17:19 编辑

> (forum.php?mod=redirect&goto=findpost&pid=64197&ptid=4723)
> > 这个我看过了,没有摆脱React依赖,我还是更想要一个原生的,因为创建元素和绑定数据这些都不难,搞一个R ...

摆脱React依赖目前来说实在是有点困难了……
毕竟这样从样式、渲染、响应之类的全要自己去实现,现在用的arco.design UI库,一共有6、70个组件,每个组件还有不同的API方法,UI库的底层用的就是React,如果要摆脱React依赖实现这些功能的代码量估计要爆炸
目前还是打算直接用React+Arco,把框架的API暴露出来,直接调用框架的样式、调用React创建元素、渲染、响应,相当于是把UI框架优化一遍,转换成脚本猫(或者其他脚本管理器)能用的脚本逆向UI框架(利用shadowroot,不与页面原有框架冲突,不会主动污染页面样式,也不会被页面的全局样式污染)
目前打算先这样试试水,说不定后期成熟了可能还可以切换框架(……随便想想)

***

之前哥哥看到的函数式是一之哥哥写的,他是预计将所有组件都自行封装一遍,直接让用0户调用。
优点是
- 组件调用起来方便
-底层实现直接是TSX,不存在兼容问题
-后续可能可以通过`d.ts`实现代码提示补全……

缺点是
- 所有组件(包括组件的子组件)都要手动封装一遍,加大UI库开发难度
- 组件调用起来可能会形成嵌套地狱。

而且我在静态封装的时候越封装越觉得这条路有点歪,因为为了实现一些组件的API,需要把这些API都重新封装一遍,这究竟是框架API还是库API……
因此我尝试了用Object.assign的方法, 想要动态封装减少代码量,不去主动修改API,只将组件暴露出来,所有调用方法都是框架原生的方法

***

然后我就打算换一种形式去实现,把`JSX`文本转成`AST`再转成`React.createElement`,然后通过`eval`或者`new Function`去实现
一开始用的`Babel`,结果发现`Babel`没有ts版本的按需导出,`core`方法只有standalone版本能用,而standalone实在是太大了2.7MB,甚至比这个库还大出将近一倍,实在是下下策。无奈翻了很久github(可能是UI库的这种需求几乎没有,都找不到现成的例子),终于找到一个压缩完只有10KB左右的库`jsxLoader`,虽然作者说有点小瑕疵,但终究是能用,比Babel小了几百倍。
目前JSX文本式方法算是基本实现了,只有偶尔几个API需要额外单独优化一下,其余基本还是直接调用UI框架的原生API。

但是也存在一些问题
- (一开始用的`eval`,但是存在作用域问题,后来发现了哥哥写的传递参数,感觉很好,参考了哥哥的方案,改成了`new Function+解构`,实现了传参),
但是这个方法也存在缺陷`new Function`/`eval`可能会被一些页面的CSP策略所禁止,
- 然后文本的话可能会加大脚本开发难度,参数要手动传递,没法获取上下文,
而且文本难以自动提示(写vscode插件可能太麻烦了,然后脚本猫插件的monaco编辑器里又可能没法用)
- 有些方法不太好封装,需要用到React或者ReactDOM的方法去实现
依赖`jsxLoader`不清楚实际上会不会遇到作者说的瑕疵,至少目前暂时没遇到……

好处可能是
- 开发简单,现在代码只写了1~200行基本大致实现了(后续可能需要单独优化几个特殊API)
- 熟练的人写起来比较方便,直接用JSX方法写成文本形式就行,改动起来也略微方便(如果用vscode之类的编辑器的话)

不知道哥哥对此有啥看法
我的设想是两条路线互不冲突,可以混用
函数式直接`CAT_UI.XXXX`静态调用;
文本式需要new class动态调用`const cat=CAT_UI;cat.createApp(jsx)`


***

最后说一下写这个脚本库的初衷,一是我自己有用的需求,毕竟有需求才有开发动力(一之哥哥是为了吸引更多人用脚本猫😄),二是为了降低门槛,让更多的人也能一起用。
很多脚本(尤其是中小型脚本)都没有自己的UI交互界面,并不是不需要UI交互界面,只是因为开发成本过高,不如不去开发。
脚本的UI开发实在是太麻烦了,样式、渲染、响应都要自己实现,写这个脚本UI库的初衷是降低开发门槛,人人都能用这个库去快速编写UI交互界面,让更多脚本拥有UI交互界面,提高开发体验、用户体验。(目前只完成了基础组件,后续可能会将这些组件封装出一个中级组件模板供微调后直接使用)
主流的UI框架都是为正向开发准备的,我试过好几个框架都不支持shadowroot,差一点的框架根本不考虑样式冲突,好一点的框架会写作用域不主动去污染其他框架,但是在一些技术比较差的网站页面里会被页面的全局样式污染,我找了很多框架都没法满足这个需求。后来萌生出了自己魔改框架的想法,奈何技术太差魔改失败,后来求助一之哥哥,一之哥哥竟然说好【……
然后就是一之哥哥写底层,我在其基础上进行优化。

目前打包出来的库经过最小化处理大概还有2.2MB(React+Acro基础大约1MB,Acro图标组件大约400KB,剩余组件加起来800KB),大小确实是个问题,可能需要后续拆分一些组件、功能,减少体积,按需导出。

函数式主分支(剩余组件有待封装):https://github.com/scriptscat/lib
JSX文本方法分支(大致成型):https://github.com/DreamNya/lib/tree/DOG_UI

(写太多了……有点意识模糊了,写到后面有点语无伦次了,都忘记一开始想写什么了,不知道哥哥有没有理解,希望哥哥见谅)

王一之 发表于 2023-7-3 17:32:04

steven026 发表于 2023-7-3 17:17
> (forum.php?mod=redirect&goto=findpost&pid=64197&ptid=4723)
> ...

> 所有组件(包括组件的子组件)都要手动封装一遍,加大UI库开发难度

一方面是我写的问题,简单的大部分都是直接return,这些可以批量封起来

另外一些是得特殊处理,不管用啥方式,该特殊处理还是要特殊处理

https://github.com/scriptscat/lib/blob/main/src/ui/ui.tsx#L91

---

> 组件调用起来可能会形成嵌套地狱

这个都会有吧

---

关于ast方式我一直是持反对态度的,哥哥都举出这么多缺点了,不过哥哥都实现了,我也不说了,反正哥哥搞

![](https://bbs.tampermonkey.net.cn/data/attachment/forum/202305/12/152207j1nuwncdss0d05ow.jpeg)

cxxjackie 发表于 2023-7-3 23:02:31

steven026 发表于 2023-7-3 17:17
> (forum.php?mod=redirect&goto=findpost&pid=64197&ptid=4723)
> ...

我之所以反对React除了体积问题,还有一个是会模糊UI库的定位,库变成了React的二次封装,有人用着别扭的不如直接去引用React,有人想要轻量级的结果发现比React还大,这让库更多适用于不知道怎么写的新手,对于成熟脚本可能不是一个理想的方案。
函数式我认为可以保留,jsx的做成插件形式就行了,解决体积问题也可以做插件,把库一些占用较大的组件分离出来让用户按需引入,可以一定程度上缓解问题。如果注定要依赖React,那甚至库本身也可以是插件,提供一个打包后的React,引用库需要先引用React,这样做的好处是假如页面本身有React,那可以直接套用以减少体积,还有React也可以单独引入来满足部分人的开发需求。
我写的那个传值其实双向绑定这块有点问题,因为不确定库要怎么实现就没做,要参考的话最好注意一下。还有jsx解析为什么不考虑DOMParser呢?原生的方式效果好体积小,可定制化程度也高,如果是因为一些特殊符号DOMParser报错的话,可以对字符串做一下预处理,参考我用正则加引号的做法。
页: 1 [2]
查看完整版本: 脚本猫UI库初版