最近接了个需求,以前做的pc端的项目要适配,如果适配的话,有两种方案:
媒体查询:麻烦
rem: 更麻烦
**方案:**
所以选择插件 postcss-pxtorem,但是这个插件只能转换css文件中的样式,不能转换行内样式。行内样式要特殊处理,这里的方案就是自定义loader在webpack编译时通过正则拿出px,并通过计算转换。
1.npm install postcss-pxtorem --save
2.配置webapck
在css中配置loader
require('postcss-pxtorem')({ // 把px单位换算成rem单位
rootValue: 19.20, //换算基数,
unitPrecision: 3, //允许REM单位增长到的十进制数字,小数点后保留的位数。
propList: ['*'],
exclude: /(node_module)/, //默认false,可以(reg)利用正则表达式排除某些文件夹的方法,例如/(node_module)/ 。如果想把前端UI框架内的px也转换成rem,请把此属性设为默认值
// selectorBlackList: ['.ant'], //要忽略并保留为px的选择器,本项目我是用的vant ui框架,所以忽略他
mediaQuery: false, //(布尔值)允许在媒体查询中转换px。
minPixelValue: 1 //设置要替换的最小像素值
}),
3.rem.js文件
// 基准大小
const baseSize = 16
// 设置 rem 函数
function setRem () {
// 当前页面宽度相对于 1920 宽的缩放比例,可根据自己需要修改。
const scale = document.documentElement.clientWidth / 1920
// 设置页面根节点字体大小, 字体大小最小为12
let fontSize = (baseSize * Math.min(scale, 2))>12 ? (baseSize * Math.min(scale, 2)): 12;
document.documentElement.style.fontSize = fontSize + 'px'
}
//初始化
setRem()
//改变窗口大小时重新设置 rem,这里最好加上节流
window.onresize = function () {
setRem()
}
4.在入口文件引入rem.js
5. 但是行内样式检测不到,所以接下来要做的事就是将行内样式的px转换为rem
暂定解决方案就是在webpack中自定义一个loader:
实现:
1. 创建一个loader文件,在里面创建一个js文件
module.exports = function(content) {
// let reg = /(\d+(\\.\d+)?)px/g
let reg = /(?<num1>\d+)\.?(?<num2>\d+)?px/g // 匹配所有px 相关的字符
let content1 = content.replace(reg,function(...data){ // px 转换为带小数的rem
var arr = data[data.length-1]
var num1=0, num2=0;
if(arr.num1)num1=parseFloat(arr.num1)
if(arr.num2)num2=parseFloat(arr.num2)
return parseFloat(num1+'.'+num2)/207 + 'rem' // 这里以16px 为pc端转换基数 适配1920分辨率
})
return content1
};
2.拓展webpack配置,test: /\.(js|mjs)$/,是已经有的,这里的webpack是4.x版本
{
test: /\.(js|mjs|jsx|ts|tsx)$/,
include: paths.appSrc,
use: [
{
loader: require.resolve("babel-loader"),
options: {
customize: require.resolve("babel-preset-react-app/webpack-overrides"),
plugins: [
[
require.resolve("babel-plugin-named-asset-import"),
{
loaderMap: {
svg: {
ReactComponent: "@svgr/webpack?-svgo,+titleProp,+ref![path]",
},
},
},
],
],
// This is a feature of `babel-loader` for webpack (not Babel itself).
// It enables caching results in ./node_modules/.cache/babel-loader/
// directory for faster rebuilds.
cacheDirectory: true,
// See #6846 for context on why cacheCompression is disabled
cacheCompression: false,
compact: isEnvProduction,
},
}, {
loader: path.resolve(__dirname, './loader/style-px2rem-loader.js')
}
],
// loader: [require.resolve("babel-loader"), path.resolve(__dirname, './loader/style-px2rem-loader.js')],
},
重点代码块,注意这块代码是在已有的配置中拓展的,是有顺序的:
, {
loader: path.resolve(__dirname, ‘./loader/style-px2rem-loader.js’)
}