目錄
吐槽:
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
很簡潔的一句話,讓人摸不着頭腦。
而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等等錯誤!
我的目錄結構如下:
config.js(也就是修改chainWebpack的檔案)存在與config目錄下。