小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
TIP 👉 东边日出西边雨,道是无晴却有晴。唐·刘禹锡《竹枝词》
前言
我们如何在style标签中样式,通过属性px2rem可以强制转换或者强制不转换
实现一个这样的postcss插件
将px转换为rem的postcss插件
-
1、 当 options 的选项 defaultEffect 值未设置或者为true时,表示默认将px转换为rem;
-
当 options 的选项 defaultEffect 为false时,表示默认不进行转换。
-
2、 引用样式文件时,通过参数px2rem可以强制转换或者强制不转换,例:
-
require('./assets/style/reset.css?px2rem=true')
-
require('./assets/style/reset.css?px2rem=false')
-
3、 style标签中样式,通过属性px2rem可以强制转换或者强制不转换,例:
<style lang="scss" scoped px2rem>
<style lang="scss" scoped px2rem="true">
<style lang="scss" scoped px2rem="false">
首先
const postcss = require('postcss') // 转换样式
const Px2rem = require('px2rem-dpr') // 根据一个样式表,生成rem版本和@1x、@2x和@3x样式表
const querString = require('query-string') // 用来把对象转成查询字符串或者把查询字符串转成对象用的
导出
module.exports = postcss.plugin(
'postcss-px2rem',
/**
* px转化为rem
* @param options 插件选项
{
defaultEffect: true, // px2rem 是否默认生效
baseDpr: 2, // base device pixel ratio (default: 2)
remUnit: 75, // rem unit value (default: 75)
remPrecision: 6, // rem value precision (default: 6)
forcePxComment: 'px', // force px comment (default: `px`)
keepComment: 'no', // no transform value comment (default: `no`)
shouldUseDprRule: function(rule){
let list = ['font', 'font-size'];
return list.some(function(item) {
return item === rule.property;
})
},
shouldIgnoreRule: function(rule) {
return /border/.test(rule.property);
}
}
* @returns {Function}
*/
function (options) {
// px转化为rem是否默认生效
let effect = options.defaultEffect !== false
// 排除规则
var excludeReg = options.exclude || /node_modules/
return function (css, result) {
var resourcePath = result.opts.webpack.resourcePath
if (excludeReg.test(resourcePath)) {// 符合不包含规则的样式不转换
return
}
var styleOptions = queryString.parse(result.opts.webpack.resourceQuery)
if ((effect && styleOptions.px2rem !== 'false') || (!effect && styleOptions.px2rem === 'true')) {
var px2remIns = new Px2rem(options);
var oldCssText = css.toString();
var newCssText = px2remIns.generateRem(oldCssText);
var newCssObj = postcss.parse(newCssText);
result.root = newCssObj;
}
};
}
)
.postcssrc.js
const config = require('./config')
// px2rem-dpr 的配置
const px2remOption = {
defaultEffect: true, // px2rem 是否默认生效
exclude: /(node_modules)|(element-theme)/, // 不包含规则,默认为 /node_modules/
baseDpr: 2, // base device pixel ratio (default: 2)
remUnit: 75, // rem unit value (default: 75)
remPrecision: 6, // rem value precision (default: 6)
forcePxComment: 'px', // force px comment (default: `px`)
keepComment: 'no', // no transform value comment (default: `no`)
shouldUseDprRule: function(rule){
let list = ['font', 'font-size'];
return list.some(function(item) {
return item === rule.property;
})
},
shouldIgnoreRule: function(rule) {
return /border/.test(rule.property);
}
}
const plugins = [
require('postcss-import')(),
require('postcss-url')(),
// to edit target browsers: use "browserslist" field in package.json
require('autoprefixer')(),
config.meshProp('isMobile') ? require('./build/plugin/postcss-px2rem-plugin')(px2remOption) : false
]
module.exports = {
plugins
}