我們先來創(chuàng)建一個項目
mkdir make-loader // 創(chuàng)建一個文件夾
npm init -y //初始化項目,生成package.json文件,package.json記錄項目的信息,以及依賴包
mkdir src //根目錄下創(chuàng)建src文件夾,并寫入任意代碼
npm install webpack webpack-cli --save-dev // 安裝 webpack
touch webpack.config.js // 創(chuàng)建webpack配置文件并配置

image.png
webpack初始配置如下

image.png
如果我們希望在引入一個JS文件的時候,遇到代碼里的Hello,就把它變?yōu)?code>Hello World,這個時候我們就可以通過一個loader來進(jìn)行修改
-
首先,我們index.js里的代碼是這樣的
image.png - 我們希望打包過后,生成的main.js里是 console.log('Hello World'),這個時候我們可以編寫一個loader,loader本質(zhì)上就是一個函數(shù),而且不能寫箭頭函數(shù),必須是聲明式的函數(shù),因為webpack在調(diào)用loader的時候,會把laoder函數(shù)里的this指向做一個變更,之后才可以用this里的一些方法,如果寫成箭頭函數(shù),this指向就會有問題,就沒辦法使用本來屬于this的一些方法了。方法接受一個參數(shù)
source,這個參數(shù)就是引入文件的源代碼,拿到引入文件的內(nèi)容進(jìn)行處理后再return出去
image.png -
寫好loader之后怎么用?注意調(diào)用自己在目錄內(nèi)寫的loader的時候,要寫絕對路徑。而不是單純的loader名
image.png - 配置 好以后,我們再去打包,我們編寫的laoder會對src下的index.js代碼進(jìn)行分析處理。代碼里打印的
Hello,變?yōu)榱?code>Hello World
image.png -
我們可以把這個loader寫的再復(fù)雜一些
image.png - 傳遞的參數(shù),在loader里,可以通過
this.query來獲取
image.png - 然后
Hello就被替換成了everyone
image.png
當(dāng)然,有的時候,我們配置的參數(shù)可能比較詭異,我們?nèi)?shù)的時候直接用this.query不是很方便。這個時候我們用webpack推薦的loader-utils這樣一個模塊,幫我們分析一些內(nèi)容。我們打開webpack官網(wǎng),API下的

image.png
具體步驟如下
- 安裝
loader-utils
npm install loader-utils --save-dev
- 安裝好以后,通過node的方式引入,
loader-utils會調(diào)用getOptions方法,并且把this傳進(jìn)去,幫我們分析this.query
image.png -
我們再打包,結(jié)果是一樣的。
image.png
如果我們想在loader里,除了把處理后的源代碼傳遞出去,還要把sourceMap,或者其他的東西一起傳遞出去,這個時候 return就不用了。我們需要this.callback方法

image.png
-
我們用this.callback方法代替return
image.png -
再次打包,結(jié)果是一樣的
image.png
如果我們在loader里要進(jìn)行一些異步的操作,比如下邊這樣

image.png
-
延遲一秒鐘后,把編譯結(jié)果返回,這個時候,如果打包會報錯
image.png - 原因是,當(dāng)我們?nèi)ヒ胍粋€文件的時候,loader代碼從上到下執(zhí)行,而setTimeout里的代碼,要1秒后才會執(zhí)行,所以我們一開始打包執(zhí)行l(wèi)oader的時候,并沒用return結(jié)果出去,這個時候就會報錯
如果我們想要在loader里寫一些異步的東西,我們該怎么處理呢?
-
我們要調(diào)用
this.async
image.png -
代碼里我們這樣寫
image.png -
我們再次打包,結(jié)果沒邊
image.png
image.png -
如果我們把定時器事件改為5000
image.png -
再次打包,打包耗時將會超過5秒
image.png
假如,我們現(xiàn)在不單單有剛才的異步loader,還有一個同步的loader,我們想達(dá)成的目標(biāo)是,通過異步loader把Hello變成everyone,然后再通過同步的loader,把everyone替換成 hello everyone,這種多個loader的情況,我們該怎么辦呢?
-
首先我們創(chuàng)建在
loaders文件夾下再創(chuàng)建一個loader,名字叫replaceLoaderAsync
image.png -
然后我們把原來的
replaceLoader代碼改為
image.png -
然后,我們再去配置
webpack.config.js
image.png -
我們再運行打包,是我們想要的結(jié)果
image.png
平時我們引用loader都是像下邊這樣寫的,并不是加path.resolve(xxxx)

image.png
-
但是這樣寫之后,肯定是不好用的,因為loader會到node_modules里去找,而不會到我們自己寫的
loaders文件夾里去找
image.png -
這個時候,我們可以借助
webpack的參數(shù)resolveLoaders,這個參數(shù)resolveLoaders會幫我們在引入loader的時候干一些事情
image.png -
這樣配置的意思是,當(dāng)我們引入一個loader的時候,它會先到node_modules里去找,看有沒有,如果沒有再到loaders里去找,如果loaders有對應(yīng)的loader,它就會用對應(yīng)的loader幫我們解析文件,配置好后,我們再打包,沒問題
image.png
























