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

346 天前
 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 就更好了。

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

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

https://www.v2ex.com/t/1008093

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

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

© 2021 V2EX