服务粉丝

我们一直在努力
当前位置:首页 > 财经 >

新开源项目(solidjs-use)随想录

日期: 来源:三分钟学前端收集编辑:超杰_

前言

如果你是 React 技术栈,就会发现其对新手其实是不太友好的,会导致新人写出很多重复渲染的组件和 BUG,而且排查难度高(当然 React 依然是最优秀的框架,很多理念的提出者和先行者)。

当我看到 SolidJS[1] 后,我感觉这才是真的 react(响应式),它既包含了 React 的语法和天生的 TS 支持,又拥有比 Vue 还彻底的响应式设计,让你不用为 Deps 烦恼。

import { createSignal } from 'solid-js'

const [count, setCount] = useState(0);

createEffect(() => {
console.log('count', count()) // 当 count 变化时,会自动触发
}) // 不需要 deps
复制代码

SolidJS 的优秀之处更多的是在于它的高性能,感兴趣的同学可以去其 官网[2] 了解一下。

综上,我个人很喜欢它的设计,也相信好的事物经过时间的发展最终会展露锋芒。

但现实情况是其生态很缺失,所以经过思考后和调研后,决定写一个工具函数库,一方面希望能参与到开源建设来,另一方面也希望能提高一下自己的能力,毕竟最好的学习技术方式就是马上用起来。

当然做开源也不仅是热爱,也有功利目的,希望能有一个国内外都认可的项目经验。

由于自己能力有限以及社区已经有很多优秀的项目,所以走的是搬运路线,而不是从 0 到 1 的创新。

image.png

在调研了 ahooksreact-useVueUse 等库后,决定采用 VueUse[3] 作为蓝本,后面经过 2 个月的业余时间开发,最终完成并开源了 solidjs-use[4]

本文主要是记录一下在搬运过程中的部分技术实践和思考,希望对你的前端开发和开源有一些启发。

技术实践

Typescript 函数重载和联合类型

虽然 TS 也使用了很久但是有些东西还是傻傻不明白,其中就包含了错误的使用联合类型解决函数重载的问题。

当一个函数出入参数为 A 类型时,返回为 M 类型;输入参数为 B 类型时,返回为 N 类型。如果是以前我会这样写:

function foo(arg: A | B): M | N
复制代码

但这样其实是不准的,因为我们明确知道 A 类型对应的是 M 类型,但是现在 A 类型却对应了 M | N 类型,这样我们在后续只能使用 any 或者 as 大法。

通过在搬砖的过程中,我对 TS 的函数重载有了正确的认知:不同参数个数或者不同参数类型,对应的返回值类型也不同时,需要使用函数重载,而不是联合类型

function foo(arg: A): M;
function foo(arg: B): N;
function foo(arg: A | B) {
  // ...
}
复制代码

多包项目引用管理

在写 monorepo 项目时,a 项目引用 b 项目,当 b 项目发生改变,我们需要重新 build 出 b 产物,这样 A 拿到的才是变化后的 b 项目。

如果仅改一次还好,如果改多次 b 项目就需要启动 watch 模式,但如果 a 同时引入了 b 和 c 两个项目,那么就需要同时 watch 多个项目了,有点麻烦。

看了 VueUse 的源码,发现这个问题也很简单,只需要使用 resolve.alias 到依赖的 src 目录,而不是按照普通 node modules 的解析方式,就可以不用 watch 依赖了。

虽然这个点也很小,但是确确实实能提升开发幸福感。

PS:当然这个方案也有缺点,当依赖的源码过多,启动会变慢。

方法论思考

如何跨技术栈?

想要将 VueUse 转为 SolidJS 框架可能大部分人的想法是直接撸起袖子,对照着搬运就可以了(虽然最后的结果可能是这种方式)。

但当你把第一版拷贝过去,那么 VueUse 后续的更新怎么办?所以这其实并不是一个简单直白的问题,需要综合考虑到实现难度、后期可维护性

如果把这个问题抽象一下,本质上是一个跨技术栈问题,那么如何解决跨技术栈问题,结合社区和自己的思考可以有以下方案供大家思考:

编译路线

编译路线

我们假设需要将 Python 编译为 JS:

  • 两者相同点有很多:例如 if/else、函数、循环等概念都是相通的
  • 当然也有很多不同点,核心体现在:
    • 语法层面:同样是函数,但 JS 中定义函数和 Python 定义函数写法是不同
    • 运行时层面:Python 中的某个内置函数,JS 中没有对应功能的函数

针对不同点,有以下解决方案:

  • 语法层面的不同:我们通过将 Python 代码结构化为 AST[5],然后修改及转化为 JS 的 AST 树,最后再将 JS AST 树转为 JS 代码
  • 运行时层面:注入由 JS 实现的相同功能的函数即可

上面仅是说的 Python 转 JS,但在计算机中,涉及 2 个相似事物的转化,都是可以采用这套转化逻辑,其实就是编译原理的应用

案例

前端最熟悉的 Babel 就是将最新的 JS 规范编译成老版本的 JS 规范,其中:

  • 语法层面:将新语法转为老语法,例如 let 编译成 var
  • 运行时层面:使用 corse-js 完成 polyfill[6],例如 Promise 类
方案优缺点

优点:当写好了转换代码,则无论项目的多少或者大小,都能 cover

缺点:难度大,工作量大

solidjs-use 在最初设计的时候也是考虑过将 VueUse 通过语法转换的方式实现 solidjs-use,但由于部分逻辑实现难度大(太菜),而最终放弃。

抽象层路线

抽象层路线

抽象层是自己先制定一套规范/语法,然后在这套规范进行完成实际代码编写,最后通过编译,编译为其他的语言/框架。

本质上依然是方案1,但是要比方案 1 的难度低很多,因为在设计之初就考虑到不同框架之间的共性以及尽量避免其他框架无做到的事情。

案例
  • mitosis[7]:Write components once, run everywhere. Compiles to Vue, React, Solid, Angular, Svelte, and more.
  • 跨端框架:比如大家比较熟悉的 uniapp 和 taro,就是将小程序的规范编译成各种平台
  • 低代码中的 Schema:《低代码引擎搭建协议规范》 | Low-Code Engine \(lowcode-engine.cn\)[8]
优缺点

优点:整体方案难度中等,成本可控

缺点:需要提前设计,并按照抽象层的规范开发、需要不断维护和对接各个框架特性

因为 VueUse 是针对 Vue 开发的,所以在开发 solidjs-use 时此方案废弃。

分层

分层

这种方式是,实际代码通常写在底层,并在上层进行很薄的一层封装和调用。

案例
  • WebAssembly:支持 WebAssembly 的语言都可以直接调用 WebAssembly 写好的函数,直接实现跨语言
  • Web Components:底层是 Web Components 写的 UI 框架,上层简单进行封装,就可以支持各个前端框架,具体案例如 ionic-ui[9]
优缺点

优点:难度低

缺点:需要提前设计,且基础层方案需要成熟

因为 VueUse 是针对 Vue 开发的,所以在开发 solidjs-use 时此方案废弃。

手动搬砖路线

手动搬砖路线是通过识别不同框架的差异,手动一点一点把代码敲出来。

虽然这种方式是最 low 的,但由于绝大多数框架和库最开始设计都没有考虑到跨技术栈的需求,却是目前最常用的社区解决方案。

当然 solidjs-use 不完全是搬砖,还结合了编译路线中的 运行时层面 进行了一层封装,得到了一个胶水代码包 solid-to-vue[10],其重要作用是使用 solid API 实现的 Vue API,可大大减少 vueuse 转 solidjs-use 过程中代码主体的变更。

优缺点

优点:难度很低

缺点:需要不断跟进项目的变化,进行手动搬砖

solidjs-use 最终采用此方案开发。

开源项目何来?

有人把开源看成很高大上的事情,必须是大佬才能做,其实不然,开源的出发点可以是帮助他人或者是炫技、或者纯粹好玩,和项目大小以及难易无关。

当然很多人苦于没有一个好的想法,本小节就是为了解决此问题,分享一些常见的开源思路。

思路1:工作/生活中的吐槽,我来工具化它/优化它

工作中我们时常吐槽某某工具做的辣鸡,你如果当作者面吐槽,可能就会被怼 “你行你来呀!”。没错,这就是你的开源机会。

案例1:ChatGPT 语音化

ChatGPT 很火,但只能文字交流,能不能做一款语音输入和输出的项目,能不能把这个项目搞到智能音箱里,能不能把她设计为英语口语助手/老师?

案例2:Vite

Webpack 打包和启动很慢

相关阅读

  • 细说 Vue 响应式原理的 10 个细节!

  • 在讲解之前,我们先了解一下数据响应式是什么?所谓数据响应式就是建立响应式数据与依赖(调用了响应式数据的操作)之间的关系,当响应式数据发生变化时,可以通知那些使用了这些响应式
  • 在调用 createApp 时,Vue 为我们做了那些工作?

  • 在使用Vue3时,我们需要使用createApp来创建一个应用实例,然后使用mount方法将应用挂载到某个DOM节点上。那么在调用createApp时,Vue再背后做了些什么事情呢?今天就来扒一扒Vue3
  • 一个企业级的文件上传组件应该是什么样的

  • 前言 大家好这里是阳九,一个中途转行的野路子码农,热衷于研究和手写前端工具.我的宗旨就是 万物皆可手写新手创作不易,有问题欢迎指出和轻喷,谢谢本文适合有一定node后端基
  • 端UI: 切图仔的新技能—PS动图制作

  • 前言真让我有点意外,我今天也只是随手发了一张,自己喜欢的日常生活户型的PS合成图,引来了一波JYM的围观。没想到,这个效果图有这么多掘友们的喜爱,当时我也只是出于打卡的心态,发
  • 老板:你来弄一个团队代码规范!?

  • 点击上方 三分钟学前端,关注公众号面试官也在看的前端面试资料本篇文章讲怎么在前端团队快速制定并落地代码规范!!!干货,拿走这个仓库[1]image.png一、背景9月份换了一个新部
  • 微信 JS-SDK 出发,一起了解JSBridge的神奇功能

  • 前言前段时间由于要实现 H5 移动端拉取微信卡包并同步卡包数据的功能,于是在项目中引入了 **`微信 JS-SDK(jweixin)`**[1] 相关包实现功能,但也由此让我对其产生了好奇心,于是打
  • 研究称做饭可降低四成死亡率?

  • 今天,关于「做饭」还是「外卖」的话题在微博上引发热议。2012年发表于《Public Health Nutrition》期刊上的一项研究引发关注。该研究发现,爱做饭的人寿命似乎更长。研究称,每
  • 世界讨厌香菜日来了

  • 今天是个奇怪的日子世界讨厌香菜日。你喜欢吃香菜吗?有研究发现,爱不爱吃香菜似乎是基因决定的?我们一起来看看。
  • 蔡天凤前夫落网

  • 近日,香港大埔龙尾村发现一宗碎尸案,死者是失踪多日的28岁模特蔡天凤。据媒体报道,此前,其前夫父母及前夫哥哥已被警方拘留。今天下午,其前夫也已被逮捕。

热门文章

  • “复活”半年后 京东拍拍二手杀入公益事业

  • 京东拍拍二手“复活”半年后,杀入公益事业,试图让企业捐的赠品、家庭闲置品变成实实在在的“爱心”。 把“闲置品”变爱心 6月12日,“益心一益·守护梦想每一步”2018年四

最新文章

  • 新开源项目(solidjs-use)随想录

  • 前言如果你是 React 技术栈,就会发现其对新手其实是不太友好的,会导致新人写出很多重复渲染的组件和 BUG,而且排查难度高(当然 React 依然是最优秀的框架,很多理念的提出者和先行
  • 细说 Vue 响应式原理的 10 个细节!

  • 在讲解之前,我们先了解一下数据响应式是什么?所谓数据响应式就是建立响应式数据与依赖(调用了响应式数据的操作)之间的关系,当响应式数据发生变化时,可以通知那些使用了这些响应式
  • 【巨量算数】2022抖音热点数据报告

  • 以上仅为部分展示更多内容详见完整PDF版报告请点击「阅读原文」免责声明:以上报告均系本平台通过公开、合法渠道获得,报告版权归原撰写/发布机构所有。如涉侵权,请联系删除!
  • 在调用 createApp 时,Vue 为我们做了那些工作?

  • 在使用Vue3时,我们需要使用createApp来创建一个应用实例,然后使用mount方法将应用挂载到某个DOM节点上。那么在调用createApp时,Vue再背后做了些什么事情呢?今天就来扒一扒Vue3
  • 一个企业级的文件上传组件应该是什么样的

  • 前言 大家好这里是阳九,一个中途转行的野路子码农,热衷于研究和手写前端工具.我的宗旨就是 万物皆可手写新手创作不易,有问题欢迎指出和轻喷,谢谢本文适合有一定node后端基