騰訊DeepOcean原創文章:dopro.io/webpack-spr…css
一、須要合成的雪碧圖icon統一放在src / assets / sprite文件夾下html
二、在src / img 會生成一份以上級目錄名稱命名的雪碧圖,如icon文件夾中用到的圖標拼合成icon.png前端
三、雪碧圖從上到下的方式排列,而且每一個圖標間隔20px,如圖所示webpack
四、在sass中編寫,按需合併。git
五、編譯後獲得的樣式以下,包括width、height也一同輸出github
一種是以webpack-spritesmith、postcss-sprites爲表明的插件,webpack-spritesmith主要的運行方式是會預先把sprite目錄中的圖標拼合好,頁面主要依賴生成後的雪碧圖。而postcss-sprites則是經過對已經生成的 CSS 文件進行分析,將其中的 background 或 background-image 做爲依賴收集,合併成雪碧圖後再將相關參數替換。web
第二種是loader處理方式,不過網上基本上沒有很好的方案,好比說這種前端工程化
這種經過註釋的方式來識別並非很好。sass
目前市面上的方案都不能知足咱們的個性化要求,相對於插件針對某一文件夾/文件處理方式,咱們更但願採用loader鏈式處理的方式來實現。微信
這裏主要利用spritesmith開源項目來進行開發,spritesmith很強大,它能夠比較靈活的合成雪碧圖,經過相應的API能夠得到圖標的相關信息。
其中sprites是須要被合成的圖片路徑,裏面包含了圖標的絕對路徑
Spritesmith.run({src: sprites,algorithm:'top-down',padding: 20}, function handleResult (err, result) {
if(err) {
throw err;
}
});
Spritesmith.run({src: sprites,algorithm:'top-down',padding: 20}, function handleResult (err, result) {
if(err) {
throw err;
}
});
利用這些信息咱們能夠對返回的樣式進行從新處理,知足前面第5點的樣式要求
let imageW = image.width;
let imageH = image.height;
if(mobile){
imageW = imageW/2;
imageH = imageH/2;
}
let imgWidth = 'width:' + imageW + 'px;';
let imgHeight = 'height:' + imageH + 'px;';
if(i < afterContent.length) {
if(afterContent[i] == ';') {
end = i + 1;
afterContent = afterContent.substring(0, end) + backgroundSize+ imgWidth+ '\n' + imgHeight + afterContent.substring(end);
} else {
end = i;
afterContent = afterContent.substring(0, end) + ';\n' + backgroundSize +imgWidth+ '\n' + imgHeight+ afterContent.substring(end);
}
}
let imagePosX = image.x;
let imagePosY = image.y;
if(mobile){
imagePosX = imagePosX/2;
imagePosY = imagePosY/2;
}
let imageX = image.x == 0 ? ' 0' : ' -' + imagePosX + 'px';
let imageY = image.y == 0 ? ' 0' : ' -' + imagePosY + 'px';
let imagePosition = '';
if(image.x || image.y){
imagePosition = imageX + imageY;
}
let cssVal = 'url("' + spriteRelativePath + '")' + imagePosition;
module:{
rules:[
{
test:/\.(scss|css)$/,
use: ExtractTextPlugin.extract({
fallback: "style-loader",
publicPath: '../../',
use: [{
loader:'css-loader'
},{
loader:'isprite-loader',
options:{
outputPath:'./src/assets/img/',
mobile:true
}
},{
loader:'sass-loader'
}],
})
},
]
}
每個業務都有不一樣的需求場景,這種方式可能不必定適用於其餘項目,但願對你們有所幫助。
附上demo