手写px2rem

100 阅读1分钟

px2rem是一种将像素单位转换为rem单位的工具,它可以兼容不同屏幕分辨率下的布局。在使用过程中,需要设置转换的比例、最大和最小的转换数值以及允许转换的属性列表。

  1. 引用loader
// webpack.config.js
    const px2rem2LoaderPath = Path.resolve(__dirname,'loaders/pa2rem2-loader.js')
    ...
    resolveLoaders:{
        alias: {
            px2rem2-loader: px2rem2LoaderPath
        }
        // 或者配置解析顺序
        modules: ['Loaders','node_modules']
    }
    module: {
        reules: [
            {
                test: /\.css$/,
                use: [
                    'style-loader',
                    'css-loader',
                    {
                        Loader: 'px2rem2-loader'
                        options: {
                            remUnit: 75,
                            remPrecision: 8
                        }
                    }
                ]
            }
        ]
    }
    // loaders/pa2rem2-loader.js
    let px2rem = require('./px2rem.js')
    let loaderUtils = require('loader-utils')
    function loader(source){
        let options = loaderUtils.getOptions(this)
        if(options.exclude && options.exclude.test(this.resource)){
            return resource
        }
        let px2rem = new Px2rem(options)
        let targetSource = px2rem.generateRem(source)
        return targetSource
    }
    module.exports = loader
 // px2rem.js
 const css = require('css')
 const pxRegExp = /\b(\d+(\.\d+)?)px\b/;
 class px2rem {
     constructor(config){
         this.config = config
     }
     generateRem(cssText){
         let self = this
         function processRules(rules){
             for(let i = 0;i<rules.length;i++){
                 let rule = rules[i]
                 let declaration = rule.declarations
                 for(let j = 0; j<declarations.length;j++){
                     let declaration = declarations[j]
                     if(declaration.type === 'declaration' && pxRegExp.test(declaration.value)){
                         declaration.value = self._getCalcValue('rem',declaration.value)
                     }
                 }
             }
         }
         var astObj = css.parse(cssText)
         procssRules(astObj.stylesheet.rules)
         return css.stringify(astObj)
     }
     _getCalcValue(type,value){
         let {remUnit,remPrecision} = this.config
         return value.replace(pxRegExp,(_,$1)=>{
             let val = (parseFloat($1)/remUnit).toFixed(remPrecision)
             return val+type
         })
     }
 }
 module.exports = px2rem

同时需要配合amfe-flexible设置body的字体大小,同时改变rem的值

image.png