开启unocss的 @apply 转换后,针对style里面的@apply指定的unocss的尺寸类样式不会转viewport单位
unocss.config.ts
import {
defineConfig,
presetAttributify,
presetIcons,
presetMini,
presetUno,
transformerDirectives
} from 'unocss'
import presetRemToPx from '@unocss/preset-rem-to-px'
export default defineConfig({
presets: [
presetUno,
presetAttributify,
presetIcons(),
// 为什么要用到这个插件?
// 模板使用 viewport 作为移动端适配方案,unocss 默认单位为 rem
// 所以需要转成 px,然后由 postcss 把 px 转成 vw/vh,完成适配
presetRemToPx({
// 这里为什么要设置基础字体大小?看下面这篇文章
// https://juejin.cn/post/7262975395620618298
baseFontSize: 4,
}),
presetMini(),
],
shortcuts: [
// shortcuts to multiple utilities
['btn', 'px-6 py-3 rounded-3 border-none inline-block bg-green-400 text-white cursor-pointer !outline-none hover:bg-green-600 disabled:cursor-default disabled:bg-gray-600 disabled:opacity-50'],
],
transformers: [
transformerDirectives({
applyVariable: false,
})
],
})
vite.config.ts
export default {
...,
css: {
postcss: {
plugins: [
autoprefixer(),
// https://github.com/wswmsword/postcss-mobile-forever
viewport({
appSelector: '#app',
viewportWidth: 375,
maxDisplayWidth: 600,
rootContainingBlockSelectorList: [
'van-tabbar',
'van-popup',
],
border: true,
}),
],
},
}
}
然而我在组件中使用@apply写法时
<div class="item">...</div>
<style scoped lang='scss'>
.item {
// 这里text-[14px] 并不会转viewport单位,在浏览器审查样式时,仍然是font-size: 14px;
@apply text-[#333333] text-[14px];
}
.other {
@apply text-[12px];
}
</style>
预期: 这里text-[14px] 会转viewport单位
实际: 这里text-[14px] 并不会转viewport单位,在浏览器审查样式时,仍然是font-size: 14px; 并且.other 类中的 text-[12px] 任意值写法并没有生成对应的class样式类!
"vue": "^3.5.6", "vite": "^5.4.6", "unocss": "0.62.4", "@unocss/preset-rem-to-px": "0.62.4", "postcss-mobile-forever": "^4.1.6",
了解下其它 PostCSS 插件是否也无效?
@wswmsword 其他Postcss有执行的。我的问题是行内unocss原子类使用你的插件确实会把px转viewport单位,但是@apply 指定的就不行了,甚至@apply中的 text-[12px]原子类不会生成对应的样式类, 但是text-[14px]就会生成但是生成的单位是px不是viewport单位
我本地试了一下,UnoCSS 的 at-apply 样式不走 PostCSS 插件,请问你知道原因吗?我不太熟 UnoCSS。这个问题之前也提过 https://github.com/wswmsword/postcss-mobile-forever/issues/47
@wswmsword 我本地写了个postcss插件测试了下,默认情况下交给postcss插件处理时的style中的css规则是未经过unocss 的transformerDirectives转换器转换过的,也就是还是我们源码的@apply这种,你这个插件要匹配这种的话应该要在postcss的AtRule 钩子中处理;但是这也污染了你这个插件的纯粹性吧;解决办法就是配置unocss的transformerDirectives转换器的执行时机,
transformerDirectives({
...,
enforce: "pre"
})
这样就行了;此时posctcss拿到的css样式就是已经经过unocss转换器转换过的样式了
默认情况 at-rule 样式应该也不会处理 unocss 的 @apply,mobile-forever 里实际上也处理了 at-rule。
设置 enforce: "pre" 这个方法怎么样,没啥副作用吧,我本来想是不是要实现个 transformerDirectives 插件的。
@wswmsword 目前我这边是没啥副作用,设置之后就是转换@apply时机提前了而已
import { transformerDirectives } from 'unocss';
export default defineConfig(({ mode }) => {
return {
plugins: [
Unocss({
transformers: [
transformerDirectives({
enforce: 'pre',
}),
],
}),
]
}
});
实测有效,暂未出现异常