项目地址https://github.com/goblin-pitcher/scss-tailwind-trans

背景

公司组件库升级,样式由scss转换为tailwind风格的css写法。tailwind css的好处自不用说,但纯手工转换工作量巨大,因此开发转换工具,重复性工作交由程序执行。

思路

首先分析IO,I为.scss文件,O为tailwind 风格的.css文件。.scss文件我们可以通过scss loader转换为原生css,其实核心工作就是原生css到tailwind css的转换。

tailwind css官网提供了各个css样式所对应的tailwindp css配置,假设将所有配置对照表爬取下来,再逐一对照样式进行转换。

总结下来,大体工作如下:

  1. .scss文件解析为css
  2. 遍历css配置,将其转换为tailwind风格的css
  3. 写入文件

scss转css

这一步可以通过sass+postcss将scss转换为ast树,再通过自定义的插件进行内容转换。

loader部分的使用代码地址为SimpleScssLoader,对应转换插件地址为tailwind-trans-plugin

需要注意的是转换后的css中保留了转换前css配置的注释,便于验证转换的正确性。

css配置转tailwind配置

首先分析,如果将css配置转换成tailwind配置的工作交由人工完成,应如何实现?

假设要转换padding-top: 8px,我们首先能知道padding-top属于padding配置,应在tailwind官网的padding配置列表中查找,但tailwind官方并没有给太多px单位的配置,我们需要将px转换为rem,再进行配置的寻找。同时这带来了一个问题:px转换成rem需要知道根节点的font-size,我们需要让转换过程是一个可配置的过程。

同样以padding-top: 8px为例,假设该属性所在的class同样存在配置padding-bottom: 8px,若根节点font-size16px,那么可以得到pt-2pb-2两天tailwind配置,而这两条配置是可以合并成p-2的,因此我们需要一个合并机制

既然有了合并,那假设有padding: 2px 4px 6px 8px,这在tailwind中同样无法直接转换,需要将其拆分为padding-top|right|bottom|left,分别进行转换,因此我们还需要一个拆分机制

若配置是padding-top: 9px又该如何处理?此时padding-top等于0.5625rem,tailwind中没有对应的配置项。对于这种情况,是否能有一个可配置近似处理机制,能够根据不同的需求对其进行取近似值。

整理以上,我们将转换过程的步骤总结如下:

  1. 爬取并分类tailwind官网上的css配置对照表,用于配置的比对
  2. 拆分复合css配置(如paddingflex等)
  3. 将原子css配置在爬取的对照表中找对应的tailwind配置

    1. 若无法找到,查询用户配置的直接转换表里找是否存在对应项,存在则返回配置结果
    2. 若无法找到,则尝试进行取近似值的处理
    3. 若依旧无法找到,则返回css配置
  4. 对转换后的tailwind配置进行合并,取最优合并结果(配置最少则可认为最优)。

以上步骤对应的代码如下:

  • 步骤1的官网信息爬取对应文件spider,爬取数据用的cheerio
  • 步骤2、3、4对应文件夹translate

    • 转换部分主要是css-translate-to-tailwind,具体配置的分析可以看命名为xxx-analysis的文件或文件夹
    • 转换部分目前取近似值的主要是大小颜色,大小可通过外部传入的remTransFunc方法转换,默认方法是取最近的值。颜色取近似值主要是计算r、g、b三者与对应tailwind颜色r、b、g的方差最小者。
    • 合并原子tailwind属性的思路类似于求数组arr中,和为m的最短组合,这里直接用朴素的动态规划解决了,懒得做优化。。

写入文件

这个没什么好说的,工具做了路径判断,写入的文件夹不存在就创建该文件夹,需要注意的是,file.to配置的路径是相对于file.from的路径,不是绝对路径

用法

npm i git+https://github.com/goblin-pitcher/scss-tailwind-trans.git -D
========
npx scss-to-tailwind init // 自动创建配置文件,各配置用法见注释
npx scss-to-tailwind run // 开始执行转换
// 从官网爬转换表,组件内置了一份转换表,若后续需要更新就执行fetch重新爬取
npx scss-to-tailwind fetch 

默认配置参见配置

效果展示

转换前:

before

转换后:

after

其他

工具是去年做的,主体内容也就花了一个星期,写的比较随意,代码也没啥注释。最近准备刷简历,发现没写啥文章,只能水一篇凑数。

这项目相当于是一次性的工具,基本上不会有后续维护,也懒得打包,没太多特别的语法,node v12+肯定能跑。。目前也只支持.scss文件到tailwind 风格.css文件的转换,后续有需求可以考虑做成webpack loader。


goblin_pitcher
590 声望30 粉丝

道阻且长