構(gòu)建多頁面應(yīng)用——靜態(tài)資源的處理

在之前的系列文章中,我已經(jīng)介紹了如何用webpack實(shí)現(xiàn)多頁面應(yīng)用的js牙丽,html,css的處理兔魂。今天就主要介紹如何處理靜態(tài)資源烤芦,在web開發(fā)中最常見的靜態(tài)資源就是圖片。

圖片的引用方式

而因?yàn)樵趙eb中析校,圖片有兩種主要的引入方式构罗,第一種是<img src="...">铜涉,第二種是backgorund-image: url(...)。前者在html中使用绰播,后者在css中使用骄噪。

web開發(fā)中的圖片處理

圖片常見的類型有jp(e)g,png蠢箩,gif链蕊,包括現(xiàn)在普遍使用的svg以及webp。svg作為矢量圖形谬泌,有一定的使用場(chǎng)景滔韵,而webp作為未來web開發(fā)的趨勢(shì),有一定的使用場(chǎng)景掌实,比如:愛奇藝中的輪播圖(carousel)中就是用webp陪蜻,但其他的見到的不多。

現(xiàn)在贱鼻,web開發(fā)中使用最多的還是jpg和png宴卖,處理他們,在構(gòu)建工具中使用url-loaderfile-loader就好了邻悬,其中file-loader負(fù)責(zé)圖片的拷貝和輸出症昏,并會(huì)給圖片名添加一個(gè)hash值。

說到這里父丰,很多人會(huì)想到字體圖標(biāo)肝谭。以前處理web頁面中的圖標(biāo)(icon),使用圖片來處理蛾扇,這樣會(huì)帶來一個(gè)性能問題就是http請(qǐng)求的增多攘烛,這樣會(huì)造成服務(wù)器的負(fù)載壓力,同時(shí)會(huì)帶來用戶體驗(yàn)的問題镀首,因?yàn)闀?huì)出現(xiàn)頁面的局部空白和頁面重繪的問題坟漱,當(dāng)然一種解決方案使雪碧圖(sprite),但是如果圖片過大怎么解決更哄,如何對(duì)圖片進(jìn)行分解(大變小的問題)靖秩,圖片的拼接比較困難,最要命的是在引用雪碧圖時(shí)要進(jìn)行計(jì)算竖瘾,除此之外就是如何對(duì)雪碧圖的組成圖片進(jìn)行自定義的刪減沟突,而使用字體圖標(biāo)這些問題,都會(huì)得到一定程度的解決捕传,當(dāng)然在構(gòu)建工具中可以使用webpack-spritesmith這個(gè)插件來處理組成雪碧圖的圖片惠拭。

當(dāng)然,有些特殊的情況,需要使用base64职辅,這里使用url-loader即可棒呛。

將圖片處理為base64有使用場(chǎng)景,將圖片轉(zhuǎn)換為雪碧圖亦有使用場(chǎng)景域携,單獨(dú)的圖片處理也有使用場(chǎng)景(這些使用場(chǎng)景的圖片大小從左到右依次增大)簇秒。

這些場(chǎng)景在一個(gè)web項(xiàng)目中都會(huì)涉及到。

雖然使用字體圖標(biāo)可以替代雪碧圖秀鞭,因?yàn)樽煮w圖標(biāo)有更小的尺寸趋观,更自由的操作手法(如:圖標(biāo)顏色的自定義),但是一個(gè)DIY的web項(xiàng)目還是有些圖標(biāo)還是需要雪碧圖锋边。

但是皱坛,這里有一個(gè)問題,如何在一個(gè)項(xiàng)目中同時(shí)使用base64豆巨,雪碧圖剩辟,字體圖標(biāo),單獨(dú)的圖片往扔。

在構(gòu)建中如何使用多種圖片處理方式

在構(gòu)建多頁面應(yīng)用中贩猎,如何解決呢?

字體圖標(biāo)

處理字體圖標(biāo)很簡(jiǎn)單萍膛,如:iconfont(阿里巴巴字體圖標(biāo)庫)吭服,就像引用css那么簡(jiǎn)單。

base64

base64的處理卦羡,使用url-loader噪馏。

雪碧圖

雪碧圖的處理麦到,可使用webpack-spritesmith這個(gè)插件

單獨(dú)的圖片

使用file-loader绿饵,它負(fù)責(zé)拷貝url-loader的處理結(jié)果,并輸出瓶颠。

上面就是我們常見的圖片處理拟赊,如果要處理svg可以參考svg-url-loader,如果要處理webp可以參考webp-loader

如何對(duì)圖片進(jìn)行優(yōu)化

對(duì)圖片進(jìn)行優(yōu)化粹淋,會(huì)帶來良好的用戶體驗(yàn)吸祟。

熟悉圖片優(yōu)化的都知道漸進(jìn)式(progressive),可參考nuwen.net

jp(e)g可以進(jìn)行連續(xù)性處理桃移,這樣可保證圖片數(shù)據(jù)請(qǐng)求回來多少屋匕,就渲染多少,是自上而下的渲染借杰,也是有模糊到清晰的狀態(tài)过吻。

png可以進(jìn)行交叉處理,這樣也可保證圖片數(shù)據(jù)請(qǐng)求回來多少,就渲染多少纤虽,它是整體的顯示乳绕,而且是又模糊狀態(tài)到清晰的狀態(tài)。

gif圖片一般使用小圖逼纸,如果是大圖會(huì)記號(hào)瀏覽器性能洋措,還不如使用視頻,或者用css動(dòng)畫來代替杰刽。我個(gè)人整理了一個(gè)css 動(dòng)畫集菠发,有需要的可以看一下。

在構(gòu)建多頁面應(yīng)用中专缠,會(huì)使用到image-webpack-loader來做優(yōu)化處理雷酪。

其中,配置項(xiàng)options中的mozjpeg 處理jp(e)g圖片涝婉,pngquant處理png圖片哥力,gifsicle處理gif圖片,webp處理webp圖片墩弯。

多頁面應(yīng)用中的圖片處理

首先吩跋,看一下多頁面應(yīng)用中的目錄結(jié)構(gòu)圖:

./src
│  aboutUs.js
│  contactUs.js
│  css.js
│  index.js
│  recruitment.js
│  
├─assets
│  │  favicon.jpg
│  │  
│  ├─css
│  │  │  index.scss
│  │  │  
│  │  ├─commons
│  │  │  ├─container
│  │  │  │      index.scss
│  │  │  │      
│  │  │  ├─footer
│  │  │  │      index.scss
│  │  │  │      
│  │  │  └─header
│  │  │          index.scss
│  │  │          
│  │  ├─productus
│  │  │      index.scss
│  │  │      productus-sprite.scss
│  │  │      
│  │  └─utils
│  │          btn.scss
│  │          form.scss
│  │          inital.scss
│  │          list.scss
│  │          modeal.scss
│  │          normalize.scss
│  │          pagination.scss
│  │          popover.scss
│  │          table.scss
│  │          text.scss
│  │          tooltip.scss
│  │          
│  └─imgs
│      ├─base64
│      │      fe.jpg
│      │      
│      ├─other
│      │      float.jpg
│      │      productus-sprite.png
│      │      
│      └─sprites
│          └─productus
│                  product-us_01.png
│                  product-us_02.png
│                  product-us_03.png
│                  product-us_04.png
│                  product-us_05.png
│                  product-us_06.png
│                  product-us_07.png
│                  product-us_08.png
│                  product-us_09.png
│                  product-us_10.png
│                  product-us_11.png
│                  product-us_12.png
│                  
├─pages
│  │  recruitment.pug
│  │  template.pug
│  │  
│  └─components
│      ├─commons
│      │  ├─container
│      │  │      index.pug
│      │  │      
│      │  ├─footer
│      │  │      index.pug
│      │  │      
│      │  └─header
│      │          index.pug
│      │          
│      └─productus
│              index.pug
│              
└─utils
        load.js

跟以前的實(shí)例代碼相比,這次的文件目錄結(jié)構(gòu)變化較大渔工,這里將要處理的所有文件模塊都放在了src目錄下锌钮。

可能有人會(huì)問,為什么要要將目錄分的這么細(xì)引矩,下面我就說一下為什么這么分梁丘。

  • aboutUs.js, contactUs.js, index.js, recruitment.js是四個(gè)路由頁面,要用到的js代碼旺韭,css.js處理各個(gè)路由頁面公用的css代碼氛谜;
  • 靜態(tài)資源目錄(assets)下,存放web項(xiàng)目常用的靜態(tài)資源区端;
  • 靜態(tài)資源目錄下的css目錄統(tǒng)一存放整個(gè)web項(xiàng)目所用到的css樣式值漫。其中commons存放公用的css模塊,每個(gè)公用模塊有創(chuàng)建一個(gè)目錄存放該公用模塊可以使用到的css模塊(提醒织盼,不要分的過于細(xì))杨何,而其他的如productus存放產(chǎn)品模塊代碼,根據(jù)開發(fā)的需要可以創(chuàng)建其他的模塊目錄沥邻,目錄結(jié)構(gòu)類似于commons中的header模塊危虱,其中utils放置自己總結(jié)的工具模塊代碼,如table唐全,form等埃跷。然后,指定style-loader,css-loader等樣式相關(guān)的loader處理css樣式文件,這樣可以減少遍歷捌蚊,縮短構(gòu)建時(shí)間集畅。
  • 靜態(tài)資源目錄下的imgs目錄,用來存放整個(gè)項(xiàng)目中缅糟,用到的圖片挺智。在這里,分為base64窗宦,sprite赦颇,ohter等,為什么要這樣分赴涵?如果分的話file-loader這個(gè)webapck的loader會(huì)復(fù)制并導(dǎo)出imgs目下所有的圖片媒怯,者在構(gòu)建中并不是我們需要的,這樣會(huì)增加構(gòu)建的時(shí)間髓窜。如果讓url-loader處理base64目錄下的圖片扇苞,file-loader處理ohter目錄下的圖片,webpack-spritesmith處理sprite目錄下的圖片寄纵,并將生成的圖片放到ohter目錄下鳖敷,用file-loader進(jìn)行二次處理。這樣做程拭,webpack處理更精確定踱,可以減少不必要的遍歷,極大地減少構(gòu)建的時(shí)間恃鞋,同樣方便對(duì)圖片的管理崖媚,特別是對(duì)于需要改變sprite的圖片的管理。
  • imgs目錄下創(chuàng)建base64目錄恤浪,sprite目錄畅哑,使用file-loader指定處理ohter目錄,是為了避免file-loader將所有的圖片都拷貝一份并導(dǎo)出到dist輸出目錄中资锰,因?yàn)榕cbase64相關(guān)的文件已經(jīng)在css樣式文件中了敢课,再拷貝一份阶祭,已經(jīng)沒有意義绷杜,而sprite相關(guān)的文件會(huì)被webpack-spritesmith插件先處理生成一個(gè)文件,所以再拷貝它們也沒有意義濒募,還會(huì)讓構(gòu)建速度更慢鞭盟。
  • page目錄下,放置所有的html代碼塊(這里使用pug編譯器生成相應(yīng)的html代碼塊)瑰剃,它的目錄分類和css相類似齿诉,它們是一一對(duì)應(yīng)的關(guān)系。

注意:iamge-webpack-loader,要先對(duì)所有的圖片進(jìn)行優(yōu)化處理粤剧,然后再用其他loader處理歇竟。loader的執(zhí)行順序,如果你是style-loader!css-loader!sass-loader"使用抵恋,它是從右到左方向先后執(zhí)行焕议,如果你是在配置文件中的rules: [...]數(shù)組中,它也是從右到左的方向執(zhí)行弧关,如果你將所有的loader規(guī)則有回車符號(hào)隔開盅安,那么它就是自下而上的執(zhí)行。

一類特殊的圖片引用

針對(duì)<img src="...">的圖片使用世囊,ul-loader是不會(huì)處理html中的img引用别瞭,現(xiàn)在處理這樣情況的loader或插件,也并沒有一個(gè)比較出名的≈旰叮現(xiàn)在通用的做法就是將圖片拷貝一份到生成目錄中蝙寨,copy-webpack-plugin。參考配置代碼如下:

new CopyWebpackPlugin([
  {
  from: path.resolve(__dirname, 'assets/imgs/other/'),
  to: path.resolve(__dirname, 'dist/assets/imgs/other/'),
  ignore: ['.*']
  }
]),

但這樣嗤瞎,會(huì)帶來另一個(gè)問題就是圖片的優(yōu)化問題籽慢,如何使用 image-webpack-loader?本來的目的是對(duì)項(xiàng)目中使用到的所有的圖片進(jìn)行優(yōu)化猫胁,而現(xiàn)在只能對(duì)base64sprite目錄下的圖片進(jìn)行優(yōu)化處理箱亿。不過,不要慌弃秆,可以通過創(chuàng)建一個(gè)新的npm腳本命令(本是里使用的是npm run img)來對(duì)圖片進(jìn)行壓縮處理届惋,新建了一個(gè)目錄static用來保存優(yōu)化前的圖片,ohter用來保存優(yōu)化后的圖片菠赚。

首先脑豹,需要安裝imagemin, imagemin-mozjpeg, imagemin-optipng, imagemin-gifsicle :

yarn add imagemin imagemin-mozjpeg imagemin-optipng imagemin-gifsicle --dev

然后,在項(xiàng)目的根目錄添加一個(gè)優(yōu)化圖片的文件optzing-img.js衡查,代碼如下:

const path = require('path')
const imagemin = require('imagemin');
const imageminMozjpeg = require('imagemin-mozjpeg');
const imageminOptipng = require('imagemin-optipng');
const imageminGifsicle = require('imagemin-gifsicle');

(async () => {
    await imagemin(
    [
      path.resolve(__dirname, 'src/assets/imgs/static/*.jpg'),
      path.resolve(__dirname, 'src/assets/imgs/static/*.png'),
      path.resolve(__dirname, 'src/assets/imgs/static/*.gif')
    ],
    path.resolve(__dirname, 'src/assets/imgs/other/'),
    {
      use: [
        imageminMozjpeg(),
        imageminOptipng(),
        imageminGifsicle()
      ]
    }
  );

    console.log('圖片優(yōu)化完成瘩欺!');
})();

最后,在package.json文件中添加如下的npm命令:

...
"scripts": {
    ...
    "img": "node optzing-img.js"
  },
...

在控制輸入npm run img拌牲,然后按下回車鍵就可以得到你所需要的俱饿。

注:既然重新定義了圖片優(yōu)化的npm腳本命令,那么塌忽,是否需要去掉之前在webpack.config.js中的image-webpakc-loader拍埠,當(dāng)然不需要。主要有兩個(gè)原因土居,一個(gè)是sprite雪碧圖它是用幾張小圖片合成了一張大圖片枣购,這張合成的圖片還需要優(yōu)化嬉探;另一個(gè)是因?yàn)楸卷?xiàng)目對(duì)于存放圖片的目錄進(jìn)行了細(xì)化。

字體

在web開發(fā)中棉圈,自定義的字體也是比較常見的涩堤,在webpack中它的處理和圖片類似,都是使用的 url-loaderfile-loader分瘾。參考代碼如下:

...
{
  include: path.resolve(__dirname, 'assets/fonts/'),
  test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
  use: [{
    loader: 'url-loader',
    options: {
      limit: 10000,
      name:  isDev ? '[name].[ext]' : '[name].[hash].[ext]',
      outputPath: 'assets/fonts/'
    }
  }]
},
...

新創(chuàng)建了一個(gè)fonts目錄又來存放項(xiàng)目開發(fā)過程中使用的字體定躏。

源代碼

webpack4.x multi-page

此后,webpack構(gòu)建多頁面應(yīng)用系列文章的源代碼芹敌,都在這個(gè)github項(xiàng)目中痊远,webpack3.x multi-page不再維護(hù)。

構(gòu)建多頁面應(yīng)用系列文章

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末氏捞,一起剝皮案震驚了整個(gè)濱河市碧聪,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌液茎,老刑警劉巖逞姿,帶你破解...
    沈念sama閱讀 216,544評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異捆等,居然都是意外死亡滞造,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門栋烤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來谒养,“玉大人,你說我怎么就攤上這事明郭÷蚩撸” “怎么了?”我有些...
    開封第一講書人閱讀 162,764評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵薯定,是天一觀的道長(zhǎng)始绍。 經(jīng)常有香客問我,道長(zhǎng)话侄,這世上最難降的妖魔是什么亏推? 我笑而不...
    開封第一講書人閱讀 58,193評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮年堆,結(jié)果婚禮上吞杭,老公的妹妹穿的比我還像新娘。我一直安慰自己嘀韧,他們只是感情好篇亭,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,216評(píng)論 6 388
  • 文/花漫 我一把揭開白布缠捌。 她就那樣靜靜地躺著锄贷,像睡著了一般译蒂。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上谊却,一...
    開封第一講書人閱讀 51,182評(píng)論 1 299
  • 那天柔昼,我揣著相機(jī)與錄音,去河邊找鬼炎辨。 笑死捕透,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的碴萧。 我是一名探鬼主播乙嘀,決...
    沈念sama閱讀 40,063評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼破喻!你這毒婦竟也來了虎谢?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,917評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤曹质,失蹤者是張志新(化名)和其女友劉穎婴噩,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體羽德,經(jīng)...
    沈念sama閱讀 45,329評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡几莽,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,543評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了宅静。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片章蚣。...
    茶點(diǎn)故事閱讀 39,722評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖姨夹,靈堂內(nèi)的尸體忽然破棺而出究驴,到底是詐尸還是另有隱情,我是刑警寧澤匀伏,帶...
    沈念sama閱讀 35,425評(píng)論 5 343
  • 正文 年R本政府宣布洒忧,位于F島的核電站,受9級(jí)特大地震影響够颠,放射性物質(zhì)發(fā)生泄漏熙侍。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,019評(píng)論 3 326
  • 文/蒙蒙 一履磨、第九天 我趴在偏房一處隱蔽的房頂上張望蛉抓。 院中可真熱鬧,春花似錦剃诅、人聲如沸巷送。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽笑跛。三九已至付魔,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間飞蹂,已是汗流浹背几苍。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留陈哑,地道東北人妻坝。 一個(gè)月前我還...
    沈念sama閱讀 47,729評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像惊窖,于是被迫代替她去往敵國(guó)和親刽宪。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,614評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容