近两年,shadcn/ui 异军突起。让我开始反思,在现今的前端界,做 UI 组件这件事仍不可画上句点。
什么是现今的前端界对 UI 组件的看法呢:
正因如此,shadcn/ui
的出现显得有些出人意料。在这个已经被“做烂”了的领域,shadcn/ui
仍然有其价值的原因,我认为在于两点:对最佳实践的开放探讨,自由度和掌控感的建立。
大家都要有一套组件库,甚至细分业务的组件库在继承基础组件库时,也要进行一定的创新改造。大家需要把时间花在重新造轮之中,好像只有这样才好证明自己是有价值的。每个人都会说自己的业务有差别,因此重复造轮的意义也“很容易被证明”。
—— 我认为这是一个“自我证明”的怪圈。
shadcn/ui
却不陷入这个怪圈。它的标题是 Build your component library
,它至多说自己是 Beautifully designed components
。
首先,技术选型上,它推荐了一种基础的基于 Radix UI
和 Tailwind CSS
及其相关工具(clsx
tailwind-merge
等)的开发方式。
其次,它不拘泥于仅用一个开源方案,而是集思广益,选择各种开源组件实现:
Calendar
组件选用 React DayPicker
;Chart
组件选用 Recharts
;Table
组件选用 @tanstack/react-table
;Form
组件选用 react-hook-form
和 zod
。它也选用了一些有特色的开源组件:
input-otp
;Sonner
;Vaul
。当然有人说,shadcn/ui
本来就不是一个完整的设计语言。然而它的价值也在于此。正如它的名字,作者 shadcn 通过这个项目向大家推荐了一些自己选型过的 ui。如果你认为这些选型不适合你,你可以不安装这一个组件。在其他人都忙于“自我证明”时,shadcn/ui
选择了对最佳实践的开放探讨。
它大大方方地告诉你,这些组件都不是我写的,而且我也不是一个完整的设计语言。好像它在说,它不看重你们口中说的那些价值。这种剑走偏锋的态度让我觉得有趣。也让我重新思考:做 UI 这件事的目的,不是为了证明自己造轮的开发能力,而是为了做出更优秀的 UI 其本身。
许多开发者对 UI 组件的价值思考聚焦且仅聚焦于 效率,才会有我开篇提到的那两种看法。当然,我的重点并不是说做优秀的 UI 等同于多用开源组件,而是说如今的组件开发者们并不以此为本。
以上更多是从组件开发者的角度的思考。现在,我想从组件使用者的角度来看 shadcn/ui
。
首先,可能作者从一开始就没有考虑为纯粹的组件使用者们提供服务,而是为组件开发者提供了维护的便利。因此,如果我们站在组件使用者的角度来看,确实容易得出和自己不适配的结论。
这非常正常。当我们不想要在 UI 这件事上花费太多时间时、当我们开发时间非常紧迫时,我们当然是选择 Ant Design
一把梭。然而渐渐地,我们无法跳出框架内的世界观。我们不喜欢 Tailwind CSS
、不喜欢 shadcn/ui
对表单的浅封装。我们总是希望拿来主义。
如果你只想拿来,如果你只想高效率地完成功能,那么 shadcn/ui
确实不适合你。这很正常,这篇文章到此结束。
但如果你还是关注 UI 的,或者你的需求还是需要一些设计上的自定义,那么我想推荐你尝试在你的项目中执行一下 npx shadcn init
,这真是一种新奇的体验。从前所有安装的东西,都放在 node_modules
这个无底黑洞之中,然而 shadcn/ui
直接注入到了你的项目。在那一刻,你多了一种对组件和整个项目的掌控感。
这种感觉可能会有点奇怪,因为这个项目本来就是你的,而且你可能本身就抱着拿来主义的态度。但就是因为它成为了你的源代码,你就生出了对 UI 的掌控与关注。
因此它和安装 Ant Design
真的不同。如果我要修改 ant 的组件样式,我只能阅读 Props 文档,或者想办法用 CSS 魔法覆盖 —— 你一直在接受。但 shadcn/ui
不是黑盒,它的源码就是你的源码,它的样式就是你的样式。这是自由度和掌控感的建立。
shadcn 自己说:
The design of your components should be separate from their implementation.
这可能才是 shadcn/ui
之所以存在的核心价值观,而不是我以上所说的。然而我却不认同,设计和实现当然没有办法分离。组件负责制定交互,设计制定不同的样式?这当然是不够的,交互当然是设计的一部分,而不只是实现的一部分。
不仅是 shadcn/ui
,最近有一些有特色的 UI 组件库出现,比如 Magic UI。虽然它们大多面向 SAAS 产品,而非后台表单类。但同样地让我意识到,做 UI 组件这件事,真的还没有完。