引子
最近一年里呀,主要写React、PC端、小程序比较多,所以移动端适配啥的就用得少了。以前写Vue的时候,总会用到的postcss-px-to-viewport这个插件也因为在React里用styled-components来写样式然后选择使用其他自动转换方案所以很久没有再用,但是最近想着跟进一下vue3+vite的学习,所以又把demo弄了起来。
遇到问题
说干就干,就按着自己的习惯开始搭demo,vite、vue3、typescript、JSX,这几个之前已经有经验,所以很容易就弄好了。
然后就是UI框架,element-plus试了一下,这次就不说了。
然后来搭移动端,UI框架选用Vant,然后移动端嘛,肯定要搞自适应的,postcss是vite自带了的,postcss-px-to-viewport很自然就用起来了,但是一个之前遇到过的问题现在就出现了:
Vant的设计稿是375的,但是平时我这的设计师一般出的双倍图,用750,所以postcss-px-to-viewport的viewportWidth得可以在不同文件中有不同的值,以前的解决方案是这样的:
// .postcssrc.js
const path = require('path');
module.exports = ({file}) => {
const designWidth = file.dirname.includes(path.join('node_modules', 'vant'))
? 375
: 750;
return {
plugins: {
autoprefixer: {},
'postcss-px-to-viewport': {
viewportWidth: designWidth
}
}
};
};
但是vite里这种方法不会返回file值(推测是webpack和rollup的不同处理),所以这种办法行不通了,我需要一种可以动态配置参数的插件,让我可以像下面这样配置:
// vite.config.ts
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import vueJsx from '@vitejs/plugin-vue-jsx';
import styleImport from 'vite-plugin-style-import';
import px2vp from 'postcss-px2vp';
const vantStyleImport = () => {
const libraryName = 'vant';
return styleImport({
libs: [
{
libraryName,
esModule: true,
resolveStyle(name) {
return `${libraryName}/es/${name}/style`;
}
}
]
});
};
export default defineConfig({
css: {
postcss: {
plugins: [
px2vp({
viewportWidth(rule) {
const file = rule.source?.input.file;
// 根据文件名动态配置viewport width
if (file?.includes('vant')) return 375;
return 750;
}
})
]
}
},
plugins: [vue(), vueJsx(), vantStyleImport()]
});
再者,postcss-px-to-viewport是js编写,没有类型提示,也没有@types类型;
插件编写的方法也是postcss 8版本里不推荐的形式。postcss-8-plugin-migration。
所以,决定自己用typescript重写一下这个插件,顺便把动态传参加了进去。
postcss-px2vp
使用上基本和postcss-px-to-viewport没有差异,主要区别是:
-
像上面提到那样动态处理参数,除了上述参数,其余参数也可以用类似的形式动态处理。
- 处理函数中的入参rule类型为Posscss.Rule
-
有完善的类型提示和参数说明
-
重写为postcss 8插件
最后
其实说这么多,也就是想大伙有需要的时候可以想起这个插件,
当然最大功劳还是原插件postcss-px-to-viewpost,
这里也不多提它的功能用法啥的了,详细可以看看掘金里的相关文章。