博客 / 詳情

返回

react自適應佈局 px轉rem

引言

在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,增加以下代碼
    image.png

     [
                                      '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轉換內聯樣式

    image.png

  • 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

user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.