天天看點

umi配置chainWebpack,使用自定義loader----jsx-px2rem

目錄

吐槽:

loader:

修改chainWebpack配置

完結

吐槽:

最初追随潮流,老大看到了umi這個國人開發标簽的架構,覺得可以嘗試,并且相信阿裡。從此開始了填坑之路。。。

雖然雲謙大佬在github上說了,umi本身的配置已經很完善了,但是肯定滿足不了所有人各種各樣的奇葩需求。。。

比如今天說的将jsx中的style裡,将px轉換為rem。

umi本身提供了postcss、cssloader等,但是要想将jsx中的px轉換成rem,并未找到相關的插件。就隻有手寫一個loader,然後再修改umi的webpack配置了。

loader:

jsx-px2rem-loader.js:

import regRules from './reg';
import _ from 'lodash';    // lodash是一個js工具庫,特别友善建議各位去了解一下

module.exports = function(source) {
  if (this.cacheable) {
    this.cacheable();
  }
  let backUp = source;

  // style={{marginRight: '1px'}} => style={{marginRight: '0.01rem'}}
  if (regRules.pxReg.test(backUp)) {
    backUp = backUp.replace(regRules.pxReg, px => {
      let val = px.replace(regRules.numReg, num => {
        return num / 100;
      });
      val = val.replace(/px$/, 'rem');
      return val;
    });
  }


  // marginRight: 1 => marginRight: '0.01rem'
  _.each(regRules.styleReg, (reg, styleName) => {
    if (reg.test(backUp)) {
      backUp = backUp.replace(reg, val => {
        return val.replace(regRules.numReg, num => {
          return `"${num / 100}rem"`;
        });
      });
    }
  });


  // img标簽 width: 1 => style={{width: '0.01rem'}}
  _.each(regRules.imgReg, (reg, styleName) => {
    if (reg.test(backUp)) {
      backUp = backUp.replace(reg, val => {
        let style = '';
        val.replace(regRules.numReg, num => {
          style = `${num / 100}rem`;
        });
        return `style={{${styleName}:"${style}"}}`;
      });
    }
  });
  
  return backUp;
}
           

reg.js:

// 比對jsx中的px 如 1px
const pxReg = /\b(\d+(\.\d+)?)px\b/g;    
 
// 比對jsx中 縮寫形式的style 如:marginRight: 1
const styleReg = {    
  marginTop: /\bmarginTop(?:\s+):(?:\s+)?(\d+)/g,
  marginRight: /\bmarginRight(?:\s+)?:(?:\s+)?(\d+)/g,
  marginBottom: /\bmarginBottom(?:\s+)?:(?:\s+)?(\d+)/g,
  marginLeft: /\bmarginLeft(?:\s+)?:(?:\s+)?(\d+)/g,
  fontSize: /\bfontSize(?:\s+)?:(?:\s+)?(\d+)/g,
  paddingTop: /\bpaddingTop(?:\s+)?:(?:\s+)?(\d+)/g,
  paddingRight: /\bpaddingRight(?:\s+)?:(?:\s+)?(\d+)/g,
  paddingBottom: /\bpaddingBottom(?:\s+)?:(?:\s+)?(\d+)/g,
  paddingLeft: /\bpaddingLeft(?:\s+)?:(?:\s+)?(\d+)/g,
}

// 比對img 中的行内樣式 width: '20'
const imgReg = {    
  height: /\bheight(?:\s+)?=(?:\s+)?(\'||\")?(\d+)?=(\'||\")?/g,
  width: /\bwidth(?:\s+)?=(?:\s+)?(\'||\")?(\d+)?=(\'||\")?/g,
}

// 比對數字
const numReg = /(\d+)/g;

export default {
  pxReg,
  styleReg,
  imgReg,
  numReg,
}
           

修改chainWebpack配置

之後便是修改umi的webpack配置。

這是官方的說明:

https://umijs.org/zh/config/#chainwebpack

umi配置chainWebpack,使用自定義loader----jsx-px2rem

很簡潔的一句話,讓人摸不着頭腦。

而github上webpackChain的issue回複速度也是讓人無語,文檔也是不清不楚。

求助umi官方人員得到的回複卻是參照webpackChain。

沒有辦法,隻能一個一個去嘗試。

終于,在快要放棄的時候成功了。

config.js

import path from 'path'

...

chainWebpack(config){
    config.module
      .rule('jsx-px2rem-loader')
      .test(/\.js$/)
        .exclude
        .add([path.resolve('../src/pages/.umi'), path.resolve('node_modules')])
        .end()
      .use('../loader/jsx-px2rem-loader')
        .loader(path.join(__dirname, '../loader/jsx-px2rem-loader'));
  }
           

注意:在配置config的時候,.use() 與 .loader()的路徑事關重要!根據項目實際路徑自行更換!

配置錯誤會出現諸如: /.umi not found或者未報錯但是并未執行loader等等錯誤!

我的目錄結構如下:

umi配置chainWebpack,使用自定義loader----jsx-px2rem

config.js(也就是修改chainWebpack的檔案)存在與config目錄下。

完結

繼續閱讀