引言
在create-react-app項目中配置絕對單位px轉換為相對單位rem,其中使用postcss-plugin-px2rem轉換css/less/sass文件(此插件不支持內聯樣式轉換),使用編寫的loader轉換內聯樣式
1.安裝插件
npm i postcss-plugin-px2rem
2.配置webpack
-
1 找到config/webpack.config.js裏postcss-loader,增加以下代碼
[ 'postcss-plugin-px2rem', { rootValue: 16,//這是基準根元素的大小,用於計算 rem 單位。例如,如果你的 HTML 根元素的 font-size 設置為 16px,那麼設置 rootValue 為 16 將會將 16px 轉換為 1rem unitPrecision: 5,//轉換後的 rem 值的小數點位數。例如,如果設置為 5,那麼轉換後的 rem 值會保留小數點後的五位 propWhiteList: [],//哪些屬性會被轉換,不填則是都轉換 propBlackList: [],//哪些屬性不會被轉換 exclude: ['/node_modules/'],//排除文件 selectorBlackList: ['noRem'], //定義了哪些選擇器不會被轉換。例如,['noRem'] 表示帶有類名為 noRem 的選擇器不會被轉換。 ignoreIdentifier: false,// 是否忽略選擇器中的標識符。設置為 false 將會處理選擇器中的標識符 replace: true,// 是否替換原始的像素值為轉換後的 rem 值。 mediaQuery: false,//是否在媒體查詢中也進行轉換 minPixelValue: 0// 最小的像素值,小於這個值的像素值將不會被轉換。 } ]這樣就完成了對非內聯樣式的轉換
3.編寫自定義loader轉換內聯樣式
-
pxToRemLoader代碼
module.exports = function(content, map, meta) { // 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)/16 + 'rem' // 這裏以16px 為pc端轉換基數 適配1920分辨率 }) return content1 }; -
webpack修改原有配置
{ 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" ), presets: [ [ require.resolve("babel-preset-react-app"), { runtime: hasJsxRuntime ? "automatic" : "classic", }, ], ], plugins: [ isEnvDevelopment && shouldUseReactRefresh && require.resolve("react-refresh/babel"), ].filter(Boolean), // 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('./config/webpack/loader/pxToRemLoader.js') } ] },借鑑:
https://juejin.cn/post/6994702713724338212
https://juejin.cn/post/7068891300740726798