EasyDSL:简化 Flutter 开发,类 TailwindCSS 的方案

2024-01-12 13:51:47 +08:00
 gydi

背景

最近在写 Flutter ,感觉一个 padding 都要写一堆,比之前写 web 是要繁琐一点。虽然也有看到一些方案,比如包一层通过属性来设置各种样式。但是好像没有看到类似 TailwindCSS 那样,直接一个 className 字符串就可以写一堆的方案。(如果已经有了话,也可以评论告知一下)

技术方案

一开始想做这个的时候,脑子里只有通过代码生成的方式,后来想想也可以通过运行时的方式。运行时方案暂时没实现,后续可以两种方式都实现,或者 dev 的时候用运行时方式,prod 的时候用代码生成的方式,说到这个脑子里就想到了 vite:)。下面就只说说代码生成的方式。

一个很容易想到的方案就是,对外暴露一个 Div widget ,然后一个 className 属性,build 的时候通过一个 map 去实现,className 到对应 widget 的映射。

基于这个简单的原理,就可以去琢磨 dart 的代码生成了。搞懂 dart 的 build, build_runner, analyzer 之类的包之后,就敲定方案为:先遍历所有 dart 代码找到所有的 className 字符串,然后通过一个注解锚定一个生成文件的位置,然后进行代码生成。

项目进展

仓库地址: https://github.com/zzzgydi/easy_dsl

目前已经发了俩 dart 包:easy_dsl 和 easy_dsl_gen 。

之所以叫 DSL 而不是 Tailwind 之类的,是感觉后续还可以有更多的 DSL 设计来辅助开发。

当前支持的一些 className 大概有:

未来还会逐渐添加更多。

遇到一些问题

首先是热更新的问题,.g.dart文件的变化似乎不会再次引起 hot reload ,所以用户得 ctrl+s 保存两次,样式变更才能展示出来。这个问题目前没想好咋搞。

另外一个是,变更 className 之后就会导致 map 里找不到对应的 widget ,进而导致首次热更新的时候 widget 会闪烁(样式变化嘛)。然后得第二次热更新时候样式才能生效,两次时间差的体感还是很明显的。为了解决这个闪烁的问题,简单的处理是在开发时,用编辑距离去判断两个 className 是否可能匹配,这样虽然不能 fix 两次保存才生效的问题,但是可以部分 fix 大幅度闪烁的问题(不是完全 fix )。

最后

我刚玩 Flutter 不久,希望写 Flutter 的同行路过可以给点意见和建议。感兴趣的可以给仓库点个 star ,来点 issue 反馈和 pr 就更好了。

3040 次点击
所在节点    分享创造
11 条回复
hiscc
2024-01-12 13:53:47 +08:00
不错不错,支持👍
Carlgao
2024-01-12 14:11:51 +08:00
问一下 clash-verge 彻底不搞了吗?
ZGame
2024-01-12 14:41:23 +08:00
不好用 ,你这不就是原子化 css 吗? 嵌套麻烦可以和 react 一样做一个复合组件 ,然后定义 props 传递给用户用啊...
1438010826
2024-01-12 14:42:29 +08:00
有点意思,感觉是个有意思的方向
gydi
2024-01-12 15:01:16 +08:00
@Carlgao 不弄了,换别的玩了
gydi
2024-01-12 15:02:17 +08:00
@ZGame 那就是我说的运行时方案,有很多类似的。我这个的方向就是在 flutter 里搞类似原子 css 那套。
jenhe
2024-01-12 15:26:36 +08:00
你这响应式布局怎么处理?
zuosiruan
2024-01-12 15:29:34 +08:00
@Carlgao #2
@gydi #5 可惜
gydi
2024-01-12 15:33:23 +08:00
@jenhe flex 的话,生成的代码就是 Row 和 Column 这些。还是说响应式是指屏幕宽高变化哪些吗,哪些还没整。
jenhe
2024-01-12 16:00:45 +08:00
@gydi #9 嗯,就是指宽高,一般都用 flutter_screenutil 这种方案
gydi
2024-01-12 16:33:35 +08:00
@jenhe #10 如果要拿屏幕宽高做响应式的话,好像还有点复杂。如果只拿父级做响应式的话,用 LayoutBuilder 应该好搞。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://ex.noerr.eu.org/t/1008093

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX