哈哈哈,它踏着輕快的步伐來啦。 若是你尚未看過個人《 大聲對webpack4.0說聲你好之webpack的基本使用(一)》,建議您先大體瀏覽,由於我會接着上一節的代碼繼續記筆記。css
本篇你將會對loader有個初步認識,還會對一些經常使用的靜態資源打包,例如圖片、樣式、字體等,若是你想學習更多關於loader的知識點和其餘的,記得關注我,我將會盡快更新。html
思考到你們可能以爲閱讀文章有些許枯燥,而後我決定將代碼放到github-webpack上面,代碼裏面使用webpack的地方,我也寫了詳細的註釋,若是有用請記得✨,有問題能夠及時交流。vue
若是你是webpack的初學者,那麼你跟着個人代碼,手動的敲打一下鍵盤,相信你也能和我同樣快速步入webpack的神聖殿堂。由於我會將全部的筆記都作得很是很是仔細,讓你在運行的過程當中不受任何阻攔。node
爲了完全的搞懂什麼是loader,咱們先來作一個小練習,經過它來認識咱們的loader。webpack
webpack號稱能夠對文件進行打包,咱們第一部分徹底是對js文件進行打包,那麼咱們能不能對圖片進行打包呢?css3
首頁先根目錄下新建文件夾statics做爲個人資源文件夾,git
1. 準備資源
mkdir statics // 新建靜態資源文件夾
// 拷貝一個shu.jpg的圖片
2.圖片資源引入到index.js中
//index.js
var avator = require('../statics/images/shu.jpg')
3.使用webpack打包
npx webpack
複製代碼
很順利的就遇到了問題,打包出現了問題github
ERROR in ./statics/images/shu.jpg 1:0
Module parse failed: Unexpected character '�' (1:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
(Source code omitted for this binary file)
@ ./src/index.js 5:13-49
複製代碼
webpack是默認支持js文件的打包的,可是遇到了圖片文件的打包,他並不知道怎麼辦,因此咱們須要修改配置文件來告訴webpack在模塊打包的時候應該怎麼辦。web
// webpack.config.js
module: { // 模塊打包配置
rules: [ // 新增規則 能夠有不少,數組
{
test: /\.jpg$/, // 檢測文件是jpg結尾的
use: {
loader: 'file-loader'
}
}
]
},
複製代碼
咱們會使用到loader,可是咱們並無安裝這個loader,因此在執行以前咱們還會使用npm進行安裝chrome
npm install file-loader -D
npx webpack
Entrypoint main = main.js
[0] ./src/index.js 198 bytes {0} [built]
[1] ./src/header.js 325 bytes {0} [built]
[2] ./src/slider.js 325 bytes {0} [built]
[3] ./src/footer.js 326 bytes {0} [built]
[4] ./statics/images/shu.jpg 80 bytes {0} [built]
複製代碼
這樣就多了一個圖片文件,咱們打開就是咱們本身的shu.jpg的內容。
在這裏咱們使用了一個loader,名稱叫file-loader,那麼咱們又是怎麼知道 file-loader是能夠打包這個圖片資源的呢?
咱們只有閱讀官方文檔後,才能更好的選取本身所用的loader。如今咱們來看看loader究竟是什麼?
官方定義:webpack 可使用 loader 來預處理文件。
實際上,loader就是咱們打包文件的一種方式。
讓咱們再來看看這個打包圖片的例子,由於我準備把代碼上傳至github,可是每一個人可能看到的文章系列不一樣,因此我從新新建一個js文件。
// src目錄下新建loader-img.js dist目錄下新建loader-img.html
// loader-img.js 使用import...from 方式引入
import avator from '../statics/images/aa.jpeg'
var img = new Image
img.src = avator
var root = document.getElementById('root')
root.append(img)
// loader-img.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>打包圖片文件</title>
</head>
<body>
<div id="root"></div>
</body>
<script src="./main.js"></script>
</html>
// 配置webpack.config.js
module: { // 模塊打包配置
rules: [ // 新增規則 能夠有不少,數組
{
test: /\.(jpg|jpeg)$/, // 檢測文件是jpg或者jpeg結尾的
use: {
loader: 'file-loader'
}
}
]
},
// 打包loader-img.js
npx webpack src/loader-img.js
複製代碼
ok,打包完成,這樣咱們就能夠直接在咱們的loader-img.html預覽圖片,獲得了咱們的效果。
在vue的官網右上角,有個生態系統,咱們能夠看到是給咱們提供了一個生態系統的,裏面就有一個vue loader。 這個時候若是咱們要配置本身的vue打包文件的話,就能夠直接使用vue loader打包。
// 咱們直接在modulues中新加入一條規則便可
module: { // 模塊打包配置
rules: [ // 新增規則 能夠有不少,數組
{
test: /\.(jpg|jpeg)$/, // 檢測文件是jpg/jpeg結尾的
use: {
loader: 'file-loader'
}
},
{
test: /\.vue$/, // 檢測文件是vue結尾的
use: {
loader: 'vue-loader'
}
}
]
},
複製代碼
前提是你須要本身先提早安裝vue loader這個依賴。
經過幾個詳細的例子下來,相信你對webpack中的loader有了必定的瞭解。
像剛纔咱們打包的圖片都是一些靜態資源,可是咱們還能夠更深層次的來看看咱們的loader對靜態資源的處理,好比,我如今想上傳一個圖片,可是我但願他的名字不改變,這個時候應該怎麼作呢?
use: {
loader: 'file-loader',
options: {
name: '[name].[ext]'
}
},
複製代碼
這個操做咱們稱爲placeholder 佔位符 [name]: 文件名 [hash]: 打包文件的hash值(若是不清楚,請看系列一有詳解) [ext]: 文件後綴 [path]: 路徑等等
npx webpack laoder-img.js
複製代碼
就會幫助咱們打包一個aa.jpeg的圖片,咱們還可使用hash值去拼接name
name: '[name]_[hash].[ext]'
複製代碼
這樣就OK了。
若是咱們想打包文件到某個文件夾,咱們直接可使用outputPath屬性,若是你還要其餘打包操做能夠直接去官網查詢。
outputPath: '/images'
複製代碼
其實咱們還可使用url-loader來打包,它會直接幫咱們打包成base64格式。
若是咱們直接打包成base64的話,咱們就會少一個圖片加載,這樣就會節約一次http請求,可是,若是咱們的文件過大,他就會轉成不少的代碼,js文件就會變得相對過大,因此咱們就能夠判斷圖片20k之內咱們就使用url-loader打包,這個具體的實現思路又是怎麼樣的呢?
首先咱們先安裝url-loader
npm install url-loader -D
複製代碼
判斷大小使用limit參數
// options 參數
limit: 1024 * 20
複製代碼
這樣就會判斷圖片是否大於20kb,若是超過就會像file-loader同樣將文件打包到dist的images文件夾下,否則的話就會直接將圖片轉成base64格式打包進咱們的js文件中。
webpack默認只支持js文件的打包,因此不用想咱們先安裝css-loader。
npm install css-loader style-loader -D
複製代碼
而後咱們新增css文件來修飾咱們的img
// index.css
.avatar{
width: 100px;
height: 100px;
}
// index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>css-loader,style-loader,url-loader</title>
</head>
<body>
<div id="root"></div>
</body>
<script src="./main.js"></script>
</html>
// css.js
import avatar from '../statics/images/aa.jpeg'
import '../statics/style/index.css'
var img = new Image
img.src = avatar
img.classList.add('avatar')
var root = document.getElementById('root')
root.append(img)
複製代碼
咱們就能夠直接打包了,咱們還能夠一個css文件經過@import 'xx.css',這種方式來引入另外一個css,這裏我就很少作演示了。
官網提示,若是你想使用scss,那麼就必須安裝sass-loader、node-sass這兩個包
// 安裝loader
npm install sass-loader node-sass -D
// 修改配置
{
test: /\.scss$/, // 檢測文件是scss結尾的
use: ['style-loader','css-loader','sass-loader']
},
// statics/style/index.scss
#root{
.avatar{
width: 100px;
height: 100px;
}
}
// css.js
// import '../statics/style/index.css'
import '../statics/style/index.scss'
// 打包
npx webpack src/css.js
複製代碼
最後打開咱們的laoder-img.html就能夠直觀的看到咱們的樣式生效了。
注意在loader中他是從下到上,從右到左的一個執行過程,因此咱們在打包scss文件的時候,他會先執行sass-loader,將咱們的代碼轉成css後再交到css-loader,最後再給咱們的style-loader掛載到頁面上。
ok,那咱們接下來在來升級一下咱們的打包流程。
咱們在樣式中修改一下咱們的代碼,我想讓個人圖片進行偏移,因此咱們在樣式中加上以下代碼
transform: translate(100px,100px);
複製代碼
而後咱們在進行打包。圖片按照咱們理想的行爲作出了偏移,咱們一塊兒來看看瀏覽器代碼。
如指望,可是在css3中,咱們遇到瀏覽器的兼容問題以後,咱們會手寫不少-webkit-等等諸多的前綴,若是如此寫下去的話,不得不說是一件十分使人頭疼的事情。
其實也有不少的loader爲咱們提供了這樣的自動添加前綴的功能。
1.安裝 postcss-loader
// 下載postcss-loader autoprefixer插件
npm install postcss-loader -D
複製代碼
2.在根目錄下新建postcss.config.js
module.exports = {
plugins: [ // 使用插件
require('autoprefixer')({ overrideBrowserslist: ['last 15 versions'] })
]
}
複製代碼
3.修改webpack.config.js
{
test: /\.scss$/, // 檢測文件是vue結尾的
use: ['style-loader','css-loader','sass-loader','postcss-loader']
},
複製代碼
ok,咱們來進行一次梳理。
這裏有一個新的知識點,pulgin-插件,這個暫時能夠知道這麼使用,由於我會在後面的系列中單獨講到這個核心概念。
({ overrideBrowserslist: ['last 15 versions'] }) 這個是我本身加上去的。
ok,咱們再次打包以後,來看看咱們的頁面中已經爲咱們自動生成了前綴。
首先咱們來假設這樣一個場景
在打包過程當中,他先走postcss-loader,而後走sass-loader,但在遇到@import其餘scss文件的時候可能就不會從新走postcss-loader,sass-loader了,那這個時候咱們又應該怎麼辦呢?
// importLoaders
use: [
'style-loader',
{
loader: 'css-loader',
options: {
importLoaders : 2 // 經過import引入的scss文件,也要走下面兩個loader
}
},
'sass-loader',
'postcss-loader'
]
複製代碼
這樣就能保證不管是在scss中仍是頁面中import的scss文件,都會從新順序執行loader.
咱們在dist目錄下新建m.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>模塊化打包</title>
</head>
<body>
<div id="root"></div>
</body>
<script src="./main.js"></script>
</html>
複製代碼
在src下新建m1.js/m2.js
// m1.js
import avatar from '../statics/images/aa.jpeg'
import createAvatar from './m2'
import '../statics/style/index.scss'
createAvatar()
var img = new Image
img.src = avatar
img.classList.add('avatar')
var root = document.getElementById('root')
root.append(img)
// m2.js
import avatar from '../statics/images/aa.jpeg'
export default function createAvatar(){
var img = new Image
img.src = avatar
img.classList.add('avatar')
var root = document.getElementById('root')
root.append(img)
}
複製代碼
m2中有一個方法建立圖片,那麼咱們每次調用一次就會建立一個圖片,而後在m1中引入了index.scss樣式。這樣的話,m1的樣式文件就會做用於我當前引入的頁面標籤,還會做用於m2我本身封裝的建立函數中,因此這樣引入的方式,樣式至關因而全局的。
若是描述咱們的代碼就會變得很糟糕,因此咱們須要開啓css打包的模塊化概念
在webpack.config.js中開啓css的模塊化打包
modules: true
複製代碼
而後咱們還會在引入方式中作出改變。
// m1.js
import style from '../statics/style/m.scss'
img.classList.add(style.avatar)
// m.scss
.avatar{
width: 100px;
height: 100px;
}
複製代碼
在打包就不會出現剛纔的問題,這個時候就以後m1中圖片的樣式生效了。這樣就只會有一個圖片樣式生效。
若是你想要在建立的文件裏也生效。那麼用一樣的方式處理便可。
字體圖標庫在近幾年的網站中運用的已經愈來愈普遍了。因此在不少項目中都會用到一些圖標來裝飾咱們的網站,其中阿里圖標庫就作的至關不錯。
咱們隨便的選取一些下載至本地。而後運用到咱們的項目當中。而後在statics中新建fonts文件夾,講字體文件所有放進去。
新建font.scss,將下載的iconfont.css內容拷貝進去,需注意文件路徑
@font-face {font-family: "iconfont";
src: url('../fonts/iconfont.eot?t=1590298271844'); /* IE9 */
src: url('../fonts/iconfont.eot?t=1590298271844#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('data:application/x-font-woff2;charset=utf-8;base64,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') format('woff2'),
url('../fonts/iconfont.woff?t=1590298271844') format('woff'),
url('../fonts/iconfont.ttf?t=1590298271844') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */
url('../fonts/iconfont.svg?t=1590298271844#iconfont') format('svg'); /* iOS 4.1- */
}
.iconfont {
font-family: "iconfont" !important;
font-size: 16px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.icon-biaoqing:before {
content: "\e63d";
}
.icon-biaoqing1:before {
content: "\e650";
}
.icon-biaoqing2:before {
content: "\e62d";
}
複製代碼
import '../statics/style/font.scss'
var root = document.getElementById('root')
root.innerHTML = '<div class="iconfont icon-biaoqing"></div>'
複製代碼
這個時候都不用想,引入樣式而後進去會找到字體文件,打包確定失敗,因此咱們會繼續進行配置字體文件的打包。
// 取消scss的模塊化打包
// modules: true
// 利用file-loader將個人字體文件打包,並放在fonts目錄下
{
test: /\.(eot|svg|ttf|woff|woff2)$/, // 檢測文件是vue結尾的
use: {
loader : 'file-loader',
options: {
outputPath: '/fonts/'
}
}
},
複製代碼
ok,這樣就能夠完美的運行了。
loader咱們的入門已經差很少了,回顧一下本節內容。
這裏爲你們推薦官方的打包講解,以及對數據之類的打包方案等。webpack資源管理
若是這篇文章對您有幫助,還請爲個人努力點個贊,下一節咱們將會認識webapck的插件(plugin)。