webpack多頁(yè)應(yīng)用架構(gòu)系列(六):聽說webpack連圖片和字體也能打包绑嘹?

本文首發(fā)于Array_Huang的技術(shù)博客——實(shí)用至上糠馆,非經(jīng)作者同意,請(qǐng)勿轉(zhuǎn)載除嘹。
原文地址:https://segmentfault.com/a/1190000006907701
如果您對(duì)本系列文章感興趣写半,歡迎關(guān)注訂閱這里:https://segmentfault.com/blog/array_huang

前言

上一篇《聽說webpack連less/css也能打包?》說到使用loader來加載CSS尉咕,這一篇來講講如何籠統(tǒng)地加載其它類型的資源污朽。為什么強(qiáng)調(diào)是“籠統(tǒng)”呢?這是因?yàn)楸疚慕榻B的方法并不針對(duì)任何類型的資源龙考,這意味著蟆肆,什么類型的資源都能用,但效果也都只是有限的晦款。

用的什么loader呢炎功?

本文介紹倆loader:file-loader和url-loader。

file-loader

file-loader的主要功能是:把源文件遷移到指定的目錄(可以簡(jiǎn)單理解為從源文件目錄遷移到build目錄)缓溅,并返回新文件的路徑(簡(jiǎn)單拼接而成)蛇损。

file-loader需要傳入name參數(shù),該參數(shù)接受以下變量(以下討論的前提是:源文件src/public-resource/imgs/login-bg.jpg;在根目錄內(nèi)執(zhí)行webpack命令坛怪,也就是當(dāng)前的上下文環(huán)境與src目錄同級(jí)):

  • [ext]:文件的后綴名淤齐,示例為'jpg'。
  • [name]:文件名本身袜匿,示例為'login-bg'更啄。
  • [path]:相對(duì)于當(dāng)前執(zhí)行webpack命令的目錄的相對(duì)路徑(不含文件名本身),示例為'src/public-resource/imgs/'居灯。這個(gè)參數(shù)我感覺用處不大祭务,除非你想把遷移后的文件放回源文件的目錄或其子目錄里。
  • [hash]:源文件內(nèi)容的hash怪嫌,用于緩存解決方案义锥。

我的做法是,require('!file-loader?name=static/images/[name].[ext]!../imgs/login-bg.jpg')岩灭,這樣login-bg.jpg的路徑就變成static/images/login-bg.jpg了拌倍,注意這還不是完整的路徑,最終還是要拼上webpack配置中的output.publicPath參數(shù)的噪径;比如說我的output.publicPath參數(shù)是../../../../build/柱恤,那么最終從require()里獲得的完整路徑就會(huì)是../../../../build/static/images/login-bg.jpg了。

url-loader

url-loader的主要功能是:將源文件轉(zhuǎn)換成DataUrl(聲明文件mimetype的base64編碼)熄云。據(jù)我所知膨更,在前端范疇里,圖片和字體文件的DataUrl都是可以被瀏覽器所識(shí)別的缴允,因此可以把圖片和字體都轉(zhuǎn)化成DataUrl收納在HTML/CSS/JS文件里荚守,以減少HTTP連接數(shù)。

url-loader主要接受以下參數(shù):

  • limit參數(shù)练般,數(shù)據(jù)類型為整型矗漾,表示目標(biāo)文件的體積大于多少字節(jié)就換用file-loader來處理了,不填則永遠(yuǎn)不會(huì)交給file-loader處理薄料。例如require("url?limit=10000!./file.png");敞贡,表示如果目標(biāo)文件大于10000字節(jié),就交給file-loader處理了摄职。
  • mimetype參數(shù)誊役,前面說了获列,DataUrl是需要聲明文件的mimetype的,因此我們可以通過這個(gè)參數(shù)來強(qiáng)行設(shè)置mimetype蛔垢,不填寫的話則默認(rèn)從目標(biāo)文件的后綴名進(jìn)行判斷击孩。例如require("url?mimetype=image/png!./file.jpg");,強(qiáng)行把jpg當(dāng)png使哈鹏漆。
  • 一切file-loader的參數(shù)巩梢,這些參數(shù)會(huì)在啟用file-loader時(shí)傳參給file-loader,比如最重要的name參數(shù)艺玲。

實(shí)操演示

接下來還是用我的腳手架項(xiàng)目webpack-seed來介紹如何利用url-loader和file-loader來加載各類資源括蝠。

圖片

這一塊我是直接在webpack配置文件里設(shè)置的:

        {
          // 圖片加載器,雷同file-loader饭聚,更適合圖片忌警,可以將較小的圖片轉(zhuǎn)成base64,減少http請(qǐng)求
          // 如下配置若治,將小于8192byte的圖片轉(zhuǎn)成base64碼
          test: /\.(png|jpg|gif)$/,
          loader: 'url-loader?limit=8192&name=./static/img/[hash].[ext]',
        },

由于使用了[hash]慨蓝,因此即便是不同頁(yè)面引用了相同名字但實(shí)際內(nèi)容不同的圖片,也不會(huì)造成“覆蓋”的情況出現(xiàn)端幼;進(jìn)一步講礼烈,如果不同頁(yè)面引用了在不同位置但實(shí)際內(nèi)容相同的圖片,這還可以歸并成一張圖片婆跑,方便瀏覽器緩存呢此熬。

字體文件

這一塊我也還是直接在webpack配置里配置的:

        {
          // 專供iconfont方案使用的,后面會(huì)帶一串時(shí)間戳滑进,需要特別匹配到
          test: /\.(woff|woff2|svg|eot|ttf)\??.*$/,
          loader: 'file?name=./static/fonts/[name].[ext]',
        },

需要聲明的是犀忱,由于我使用的是阿里媽媽的iconfont方案,此方案加載字體文件的方式有一點(diǎn)點(diǎn)特殊扶关,所以正則匹配的時(shí)候要注意一點(diǎn)阴汇,iconfont的CSS是這樣的,你們看看就明白了:

@font-face {font-family: "iconfont";
  src: url('iconfont.eot?t=1473142795'); /* IE9*/
  src: url('iconfont.eot?t=1473142795#iefix') format('embedded-opentype'), /* IE6-IE8 */
  url('iconfont.woff?t=1473142795') format('woff'), /* chrome, firefox */
  url('iconfont.ttf?t=1473142795') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/
  url('iconfont.svg?t=1473142795#iconfont') format('svg'); /* iOS 4.1- */
}

其它資源

也許你會(huì)問节槐,我們?yōu)槭裁催€需要轉(zhuǎn)移其它資源呢搀庶?直接引用不就可以了嗎?

我之前也是這么做的铜异,直接引用源文件目錄src里的資源哥倔,比如說webuploader用到的swf文件,比如說用來兼容IE而又不需要打包的js文件揍庄。但是后來我發(fā)現(xiàn)咆蒿,這樣做的話,就導(dǎo)致部署上線的時(shí)候要把build目錄和src目錄同時(shí)放上去了;而且由于build目錄和src目錄同級(jí)沃测,我就只能用build目錄和src目錄的上一級(jí)目錄作為網(wǎng)站的根目錄了(因?yàn)槿绻?code>build目錄設(shè)為網(wǎng)站缭黔,用戶就讀取不到src目錄了),反正就是各種的不方便蒂破。

那么试浙,我是怎么做的呢?

我建了一個(gè)config文件寞蚌,名為build-file.config.js,內(nèi)容如下:

module.exports = {
  js: {
    xdomain: require('!file-loader?name=static/js/[name].[ext]!../../../vendor/ie-fix/xdomain.all.js'),
    html5shiv: require('!file-loader?name=static/js/[name].[ext]!../../../vendor/ie-fix/html5shiv.min.js'),
    respond: require('!file-loader?name=static/js/[name].[ext]!../../../vendor/ie-fix/respond.min.js'),
  },
  images: {
    'login-bg': require('!file-loader?name=static/images/[name].[ext]!../imgs/login-bg.jpg'),
  },
};

這個(gè)config文件起到兩個(gè)作用:

  1. 每次加載到這個(gè)config文件的時(shí)候钠糊,會(huì)執(zhí)行那些require()語句挟秤,對(duì)目標(biāo)文件進(jìn)行轉(zhuǎn)移(從src目錄到build目錄)。
  2. 調(diào)用目標(biāo)文件的代碼段抄伍,可以從這個(gè)config文件取出目標(biāo)文件轉(zhuǎn)移后的完整路徑艘刚,例如我在src/public-resource/components/header/html.ejs里是這么用的:
<!DOCTYPE html>
<html lang="zh-cmn-Hans">
<head>
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  <title><% if (pageTitle) { %> <%= pageTitle %> - <% } %> XXXX后臺(tái)</title>
  <meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1" /> 
  <meta name="renderer" content="webkit" />

  <!--[if lt IE 10]>
    <script src="<%= BUILD_FILE.js.xdomain %>" slave="<%= SERVER_API_URL %>cors-proxy.html"></script>
    <script src="<%= BUILD_FILE.js.html5shiv %>"></script>
  <![endif]-->
</head>
<body>
  <!--[if lt IE 9]>
    <script src="<%= BUILD_FILE.js.respond %>"></script>
  <![endif]-->

恩,你可能會(huì)好奇這HTML里怎么能直接引用js的值截珍,哈哈哈攀甚,超綱了超綱了,這是我后面要講到的內(nèi)容了岗喉。

示例代碼

諸位看本系列文章秋度,搭配我在Github上的腳手架項(xiàng)目食用更佳哦(笑):Array-Huang/webpack-seed(https://github.com/Array-Huang/webpack-seed)

附系列文章目錄(同步更新)

本文首發(fā)于Array_Huang的技術(shù)博客——實(shí)用至上牵敷,非經(jīng)作者同意,請(qǐng)勿轉(zhuǎn)載法希。
原文地址:https://segmentfault.com/a/1190000006907701
如果您對(duì)本系列文章感興趣枷餐,歡迎關(guān)注訂閱這里:https://segmentfault.com/blog/array_huang

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市苫亦,隨后出現(xiàn)的幾起案子毛肋,更是在濱河造成了極大的恐慌怨咪,老刑警劉巖,帶你破解...
    沈念sama閱讀 207,113評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件润匙,死亡現(xiàn)場(chǎng)離奇詭異诗眨,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)孕讳,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門匠楚,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人厂财,你說我怎么就攤上這事芋簿。” “怎么了璃饱?”我有些...
    開封第一講書人閱讀 153,340評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵与斤,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我荚恶,道長(zhǎng)撩穿,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,449評(píng)論 1 279
  • 正文 為了忘掉前任谒撼,我火速辦了婚禮食寡,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘嗤栓。我一直安慰自己冻河,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評(píng)論 5 374
  • 文/花漫 我一把揭開白布茉帅。 她就那樣靜靜地躺著叨叙,像睡著了一般。 火紅的嫁衣襯著肌膚如雪堪澎。 梳的紋絲不亂的頭發(fā)上擂错,一...
    開封第一講書人閱讀 49,166評(píng)論 1 284
  • 那天,我揣著相機(jī)與錄音樱蛤,去河邊找鬼钮呀。 笑死,一個(gè)胖子當(dāng)著我的面吹牛昨凡,可吹牛的內(nèi)容都是我干的爽醋。 我是一名探鬼主播,決...
    沈念sama閱讀 38,442評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼便脊,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼蚂四!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,105評(píng)論 0 261
  • 序言:老撾萬榮一對(duì)情侶失蹤遂赠,失蹤者是張志新(化名)和其女友劉穎久妆,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體跷睦,經(jīng)...
    沈念sama閱讀 43,601評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡筷弦,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了抑诸。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片烂琴。...
    茶點(diǎn)故事閱讀 38,161評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖蜕乡,靈堂內(nèi)的尸體忽然破棺而出监右,到底是詐尸還是另有隱情,我是刑警寧澤异希,帶...
    沈念sama閱讀 33,792評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站绒瘦,受9級(jí)特大地震影響称簿,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜惰帽,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評(píng)論 3 307
  • 文/蒙蒙 一憨降、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧该酗,春花似錦授药、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至爵嗅,卻和暖如春娇澎,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背睹晒。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評(píng)論 1 261
  • 我被黑心中介騙來泰國(guó)打工趟庄, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人伪很。 一個(gè)月前我還...
    沈念sama閱讀 45,618評(píng)論 2 355
  • 正文 我出身青樓戚啥,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親锉试。 傳聞我的和親對(duì)象是個(gè)殘疾皇子猫十,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評(píng)論 2 344

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