背景
我們在進(jìn)行h5開發(fā)時,通常使用的設(shè)計稿是750px(考慮retina),我們會直接根據(jù)設(shè)計稿的尺寸去開發(fā),然后進(jìn)行適配(常用的有淘寶的flexible方案以及近期流行的vw適配方案)。但有時,我們又想直接使用現(xiàn)有移動端框架的一些組件(如簡潔大方的weui)。weui作為基礎(chǔ)組件,大多數(shù)是使用px為單位的,比如直接在自己的項目中用upload組件,看起來就小了一號。

這是由于<meta>中的 viewport已經(jīng)被相關(guān)js改成 640 或 750 之類的值,WeUI中的 13px 等字號或尺寸就顯得捉襟見肘了。
解決方案
1. 最笨的
要解決這個問題,最直接的方式就是把框架里相關(guān)代碼拷貝過來,自己默默地覆蓋樣式,這樣做的好處是可以精確控制像素,缺點自然是浪費生命~~
2. 與適配方案相關(guān)的
如果你使用rem的適配方案,有現(xiàn)成的工具可以將px轉(zhuǎn)化成rem(如,px2rem),或者在webpack工程中使用postcss-px2rem插件,并在處理css的相關(guān)rules中添加
{
loader: 'postcss-loader',
options: {
plugins: [
px2rem({
remUnit: 375 / 20,
remPrecision: 5
})
]
}
}
需要注意的是
- remPrecision指的是生成的rem數(shù)值精度,避免過長
- 而 remUnit 中用 375,是基于 iphone6 的尺寸做一個基準(zhǔn),計算出來的尺寸基本在各自手機(jī)型號中都可以接受
- 20 則參考了小程序中的標(biāo)準(zhǔn),這個值其實也可以自定義,和相關(guān)rem輔助工具中的設(shè)置一致即可
該方案參考自《WeUI在rem項目中的一種適配方法》 一文,該文還提出“使用 webpack2-replace-loader 插件”的方式,但本人測試后無法編譯通過,如果有同學(xué)成功了,請多多指教~
3. 字符串替換方式,修改原來的px(大概2倍大小比較合適)
這個方式的思路是找出框架中所有以px為單位的數(shù)字,乘以2。借用node文件處理,按行讀取文件,對每行文件進(jìn)行正則匹配,并替換所有以px結(jié)尾的數(shù)值。代碼如下:
let output = ''; // 最終輸出的結(jié)果
const readline = require('readline');
const path = require('path');
const fs = require('fs');
let filepath = path.join(__dirname, "weui.css"); // 需要轉(zhuǎn)化的css文件
let input = fs.createReadStream(filepath);
const rl = readline.createInterface({
input: input
});
rl.on('line', (line) => {
var exp = new RegExp(/\b(\d+(\.\d+)?)px\b/g); // 獲取所有以px結(jié)尾的數(shù)值
var out = line.replace(exp, function ($0, $1) {
return $1 * 2 + 'px';
}); // 將匹配到的數(shù)值進(jìn)行計算
output += `${out}\n`;
});
rl.on('close', (line) => {
fs.writeFile(__dirname + '/output.css', output, function (err) {
if (err) {
throw err;
}
console.log('已保存!');
});
console.log("讀取完畢!");
});
將輸出的文件引入項目,可以看到剛才的上傳組件變成正常大小啦

踩過的幾個坑:
- 一開始沒想到replace函數(shù)可以直接用替換函數(shù),還在那里自己拼字符串,如下:
var result = exp.exec(line);
var out = line;
if (result !== null) {
out = line.substring(0, result.index) + parseInt(result[1])*2 + line.substring(result.index+result[1].length);
}
但這也只能解決一行只出現(xiàn)一次px的情況,如果有多個匹配串,拼起來太痛苦了,就想著px轉(zhuǎn)rem的工具肯定已經(jīng)解決了這個問題,所以屁顛屁顛跑去參考了px2rem的源碼(思路!!!),發(fā)現(xiàn)replace可以這么用,馬上解決了我的痛點,開心!
- 本來想每行處理的時候順便寫入到文件,但寫入文件的過程是異步的,所以生成出來的文件會錯位。一般css文件都不會很大,因此我直接把結(jié)果緩存起來,最后一起寫入文件。畢竟讀寫文件的開銷比較大。
本人初入移動端,希望各位多多吐槽,一起討論解決問題的思路。