#背景
目前接触到一个项目,它是由@efox/emp(opens new window)搭建的,最近在开发的项目中考虑引入原子化CSS。
#选型
我之前接触过两种原子化框架,tailwindcss(opens new window)和windicss(opens new window),这次考虑到windicss
原作者已经不再维护相关库了同时我又想尝试新的框架,因此选了unocss(opens new window)
#unocss 配置
根据@efox/emp
相关介绍来说是基于webpack5
,因此我安装的时候采用了Webpack Plugin(opens new window)安装的相关步骤,但是最终启动的时候出现了内部依赖的各项报错,然后找issue
、stackoverflow
等都没有找到相应的解决方案,所以不知道是我配置的问题还是框架依赖存在问题,总而言之,最后无奈放弃了这种解决方案
PS:如果有人可以提供一个简单解决的demo
感激不尽
我又找了一下是否有其他方式,本来想使用Postcss Plugin(opens new window),但看到其中写着一个告警
WARNING
This package is in an experimental state right now. It doesn't follow semver, and may introduce breaking changes in patch versions.
因此为了稳定性,放弃了引入unocss
,转向tailwind
#tailwind
#配置
我认为tailwind
的配置还是比较简单的,直接按照官网的安装步骤走就可以
#多余样式
打完包后其实想看是否按需加载的,通过代码搜索看到确实进行了按需加载,但是也生成了一些没有用到过的样式,搜了一下发现在vue
中的style
内其实有position: absolute
,打包出来存在没用到的.absolute { position: absolute }
,因此怀疑是vue
中的style
影响到读取并生成了多余样式,我于是初始化一个最简单的模板进行了测试,使用的是Vite
生成的模板
打包前存在的样式:
打包后生成的样式:
#解决方案一
发现果然如我所想,因此我自然而然的想到在读取的时候有没有一种措施能够忽略掉 style 内的样式,于是找了一下tailwind
是使用哪个工具来扫描文件的,最终发现是@fullhuman/postcss-purgecss(opens new window),然后找了官网发现了一个解决措施
于是兴冲冲地去找了tailwind
配置项,这里说一个小技巧,如果不知道如何配置那么可以找这个工具仓库的tests
文件,这些文件是用于自测使用,但可以通过这些测试案例很好的了解到如何配置
这个通过defaultExtractor
这个配置项找到了如何配置
于是写下来如下解决方案,在tailwind.config.js
中配置:
/** @type {import('tailwindcss').Config} */
const customExtractor = (content) => {
const contentWithoutStyleBlocks = content.replace(/<style[^]+?<\/style>/gi, '')
return contentWithoutStyleBlocks.match(/[A-Za-z0-9-_/:]*[A-Za-z0-9-_/]+/g) || []
}
module.exports = {
corePlugins: {
preflight: false,
},
content: {
relative: true,
files: ["./src/**/*.{html,js,vue,ts}"],
options: {
defaultExtractor: customExtractor,
}
},
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
结果发现并没有生效,然后通过测试发现传参进来的content
是文件内的单行,并不是整个文件,因此并不能解决这个问题,因此该方法失败
然后思考是否有配置项可以整个文件进行读取,找了api
发现有一个 transform 选项可以做到,于是我又在tailwind.config.js
进行如下配置:
/** @type {import('tailwindcss').Config} */
const customTransformer = (content) => {
const contentWithoutStyleBlocks = content.replace(/<style[^]+?<\/style>/gi, '')
return contentWithoutStyleBlocks
}
module.exports = {
corePlugins: {
preflight: false,
},
content: {
relative: true,
files: ["./src/**/*.{html,js,vue,ts}"],
transform: {
vue: customTransformer,
}
},
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
经过测试发现确实可以忽略style
内的样式,但是又发现还是存在多余的样式,然后经过测试发现原来vue
中定义的变量也会被读取,例如:
const visible = ref(false)
const changeVisible = () => {
visible.value = !visible.value
}
2
3
4
5
那么在最终生成打包出来的样式就会存在冗余,如下图所示:
在js
、ts
文件中如果出现变量值或者函数名存在与tailwind
一致,并且这种情况很难用规避,那么打包后不可避免的就会产生多余的样式,但这种情况应该也不会很多,个人认为在可接受范围内
#解决方案二
方案一虽然可接受,但没能很好的解决多余样式问题,于是我又想到是否还有其他的解决方案,思考后想到可以通过添加前缀的方式来解决,这样基本可以避免重复问题,于是有了如下配置:
/** @type {import('tailwindcss').Config} */
module.exports = {
prefix: 'tw-',
corePlugins: {
preflight: false,
},
content: ["./src/**/*.{html,js,vue,ts}"],
}
2
3
4
5
6
7
8
这样在书写的时候虽然多了前缀,但这样基本可以避免其他命名的冲突,很好地解决生成多余样式问题
#总结
在以往的开发过程中都是能使用就行,并没有关注过打包后是否会存在问题,这一次原先是想看是否按需加载,却意外发现生成多余样式,然后根据这个问题去解决的心路历程。