本文首發(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è)作用:
- 每次加載到這個(gè)config文件的時(shí)候钠糊,會(huì)執(zhí)行那些
require()
語句挟秤,對(duì)目標(biāo)文件進(jìn)行轉(zhuǎn)移(從src
目錄到build
目錄)。 - 調(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
)。
附系列文章目錄(同步更新)
- webpack多頁(yè)應(yīng)用架構(gòu)系列(一):一步一步解決架構(gòu)痛點(diǎn)
- webpack多頁(yè)應(yīng)用架構(gòu)系列(二):webpack配置常用部分有哪些钱床?
- webpack多頁(yè)應(yīng)用架構(gòu)系列(三):怎么打包公共代碼才能避免重復(fù)荚斯?
- webpack多頁(yè)應(yīng)用架構(gòu)系列(四):老式j(luò)Query插件還不能丟,怎么兼容查牌?
- webpack多頁(yè)應(yīng)用架構(gòu)系列(五):聽說webpack連less/css也能打包事期?
- webpack多頁(yè)應(yīng)用架構(gòu)系列(六):聽說webpack連圖片和字體也能打包?
- webpack多頁(yè)應(yīng)用架構(gòu)系列(七):開發(fā)環(huán)境纸颜、生產(chǎn)環(huán)境傻傻分不清楚兽泣?
- webpack多頁(yè)應(yīng)用架構(gòu)系列(八):教練我要寫ES6!webpack怎么整合Babel胁孙?
- webpack多頁(yè)應(yīng)用架構(gòu)系列(九):總有刁民想害朕唠倦!ESLint為你阻擊垃圾代碼
- webpack多頁(yè)應(yīng)用架構(gòu)系列(十):如何打造一個(gè)自定義的bootstrap
- webpack多頁(yè)應(yīng)用架構(gòu)系列(十一):預(yù)打包Dll,實(shí)現(xiàn)webpack音速編譯
- webpack多頁(yè)應(yīng)用架構(gòu)系列(十二):利用webpack生成HTML普通網(wǎng)頁(yè)&頁(yè)面模板
- webpack多頁(yè)應(yīng)用架構(gòu)系列(十三):構(gòu)建一個(gè)簡(jiǎn)單的模板布局系統(tǒng)
- webpack多頁(yè)應(yīng)用架構(gòu)系列(十四):No復(fù)制粘貼浊洞!多項(xiàng)目共用基礎(chǔ)設(shè)施
- webpack多頁(yè)應(yīng)用架構(gòu)系列(十五):論前端如何在后端渲染開發(fā)模式下夾縫生存
本文首發(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