前面三節,我主要給大家分享了有關webpack的一些配置的知識點,如何打包js文件,而如果我們遇到其他類型的資源如圖片、css、字體font等等,我們該如何處理呢?今天會介紹預處理器(loader),它賦予了Webpack可處理不同資源類型的能力,極大豐富了其可擴展性。
如果想了解Webpack的基礎配置可以參考以下地址:
Webpack實戰(一):Webpack打包工具安裝及參數配置
Webpack實戰(二):webpack-dev-server的介紹與用法
Webpack實戰(三):作爲前端你不得不懂的Webpack資源入口和出口的配置
在一個項目中,我們要面臨着各種各樣的資源,如何讓Webpack很好的處理這些資源呢?這個時候我們需要藉助於預處理器(loader),loader的字面意思是裝載器,在Webpack中它的實際功能則更像是預處理器。Webpack本身只認識JavaScript,對於其他類型的資源必須預先定義一個或多個loader對其進行轉譯,輸出爲Webpack能夠接收的形式再繼續進行,因此loader做的實際上是一個預處理的工作。
loader配置
- loader引入
如果我們要引入css文件,webpack是沒法處理的,如
// common.css
body {
font-size: 20px;
background: #0fc;
}
//index.js
import './common.css'
執行的結果如上圖,由此可見,Webpack是無法處理css文件,我們需要給安裝預處理css-loader。安裝步驟如下
npm install --save-dev css-loader
然後我們將loader 引入項目中,配置webpack.config.js配置如下:
const path = require('path')
module.exports = {
context: path.join(__dirname, './src'),
entry: {
index: './index.js'
},
output: {
path: path.join(__dirname, 'dist'),
filename: 'index.js'
},
mode: 'development',
module: {
rules: [
{
test: /\.css$/i,
use: [ 'css-loader'],
},
],
}
}
與loader相關的配置都在module對象中,其中module.rules代表了模塊的處理規則。每條規則內部可以包含很多配置項,這裏我們只使用了最重要的兩項—test和use。
- test可接收一個正則表達式或者一個元素爲正則表達式的數組,只有正則匹配上的模塊纔會使用這條規則。 如以/.css$/來匹配所有以.css結尾的文件。
- use可接收一個數組,數組包含該規則所使用的loader,也可以是字符串,對象等。
很多時候,在處理某一類資源時我們都需要使用多個loader。如,對於SCSS類型的資源來說,我們需要sass-loader來處理其語法,並將其編譯爲CSS;接着再用css-loader處理CSS的各類加載語法;最後使用style-loader來將樣式字符串包裝成style標籤插入頁面。
下面引入style-loader,安裝命令如下:
npm install --save-dev style-loader
配置代碼如下:
const path = require('path')
module.exports = {
context: path.join(__dirname, './src'),
entry: {
index: './index.js'
},
output: {
path: path.join(__dirname, 'dist'),
filename: 'index.js'
},
mode: 'development',
module: {
rules: [
{
test: /\.css$/i,
use: ['style-loader', 'css-loader'],
},
],
}
}
此時再進行打包,樣式就會生效了,應該會看到頁面中插入了一個style標籤,包含了CSS文件的樣式,這樣我們就完成了從JS文件加載CSS文件的配置。
打包效果如下圖:
運行效果如下圖
把style-loader放在css-loader前面,這是因爲在Webpack打包時是按照數組從右邊往左邊的順序將資源交給loader處理的,因此要把最後生效的放在左邊。
loader作爲預處理器通常會給開發者提供一些配置項,在引入loader的時候可以通過options將它們傳入
module: {
rules: [
{
test: /\.css$/i,
use: ['style-loader',
{
loader: 'css-loader',
options: {
// 有關css-loader的配置
}
}
],
},
],
}
- 其他配置
exclude與include是用來排除或包含指定目錄下的模塊,可接收正則表達式或者字符串(文件絕對路徑),以及由它們組成的數組
module: {
rules: [
{
test: /\.css$/i,
use: ['style-loader', 'css-loader'],
exclude: /node_modules/
},
],
}
exclude規則內的使node_modules中的模塊不會執行這條規則。該配置項通常是必加的,否則可能拖慢整體的打包速度。
module: {
rules: [
{
test: /\.css$/i,
use: ['style-loader', 'css-loader'],
include: /src/
},
],
}
include代表該規則只對正則匹配到的模塊生效。假如我們將include設置爲工程的源碼目錄,自然而然就將node_modules等目錄排除掉了。
如果exclude 和include同時存在,則exclude權限比較高
resource與issuer可用於更加精確地確定模塊規則的作用範圍,在Webpack中,我們認爲被加載模塊是resource,而加載者是issuer
module: {
rules: [
{
use: ['style-loader', 'css-loader'],
resource: {
test: /\.css$/i,
exclude: /node_modules/
},
issuer: {
test: /\.js$/i,
exclude: /node_modules/
}
},
],
}
通過添加resource對象來將外層的配置包起來,區分了resource和issuer中的規則,這樣就一目瞭然了。
enforce用來指定一個loader的種類,只接收“pre”或“post”兩種字符串類型的值。事實上,我們也可以不使用enforce而只要保證loader順序是正確的即可。配置enforce主要的目的是使模塊規則更加清晰,可讀性更強,尤其是在實際工程中,配置文件可能達到上百行的情況,難以保證各個loader都按照預想的方式工作,使用enforce可以強制指定loader的作用順序。
常用的預處理器
- babel-loader用來處理ES6+並將其編譯爲ES5,它使我們能夠在工程中使用最新的語言特性,同時不必特別關注這些特性在不同平臺的兼容問題。
npm install babel-loader babel-core babel-preset-env
- babel-loader:它是使Babel與Webpack協同工作的模塊。
- babel-core:顧名思義,它是Babel編譯器的核心模塊。
- babel-preset-env:它是Babel官方推薦的預置器,可根據用戶設置的目標環境自動添加所需的插件和補丁來編譯ES6+代碼。
配置文件如下:
{
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
cacheDirectory: true,
presets: [
[
'env', {
modules: false
}
]
]
}
}
}
由於babel文件很大沒,所以要排除node_modules|bower_components
對於babel-loader本身我們添加了cacheDirectory配置項,它會啓用緩存機制,在重複打包未改變過的模塊時防止二次編譯,同樣也會加快打包的速度
babel-loader支持從.babelrc文件讀取Babel配置,因此可以將presets和plugins從Webpack配置文件中提取出來,也能達到相同的效果。
- ts-loader
ts-loader與babel-loader的性質類似,它是用於連接Webpack與Typescript的模塊,安裝命令如下:
npm install ts-loader typescript
webapck.config.js配置如下
rules: [
{
test: /\.ts$/,
use:'ts-loader'
}
]
- html-loader
html-loader用於將HTML文件轉化爲字符串並進行格式化,這使得我們可以把一個HTML片段通過JS加載進來。 - handlebars-loader
handlebars-loader用於處理handlebars模板,在安裝時要額外安裝handlebars。 - file-loader
file-loader用於打包文件類型的資源,並返回其publicPath。
總結
有關Webpack預處理器(loader)就暫時分析到這裏,這僅代表個人觀點,歡迎拍磚,如想了解更多請掃描下面: