您好,登錄后才能下訂單哦!
小編給大家分享一下Webpack實(shí)現(xiàn)Loader的方法,希望大家閱讀完這篇文章后大所收獲,下面讓我們一起去探討吧!
如何實(shí)現(xiàn)一個(gè)Loader?
我們在上幾節(jié)有講過loader,今天我們來深入了解它們,最暴力的方式莫過于動(dòng)手實(shí)現(xiàn)它們
好了,回到正題, 先來回顧一下loader
loader定義: 用于對模塊的源代碼進(jìn)行轉(zhuǎn)換。loader 可以使你在 import 或"加載"模塊時(shí)預(yù)處理文件
簡單使用
module.exports = { //... module: { rules: [ { test: /\.js$/, use: [ { // loader 是導(dǎo)出為一個(gè)a函數(shù)的 node 模塊。該函數(shù)在 loader 轉(zhuǎn)換資源的時(shí)候調(diào)用 // 給定的函數(shù)將調(diào)用 loader API,并通過 this 上下文訪問 loader: path.resolve('loader.js'), options: {/* ... */} } ] } ] } };
回顧了loader的定義及簡單使用后,我們再來分析一下實(shí)現(xiàn)loader的思路
單一職責(zé),一個(gè)loader只做一件事
鏈?zhǔn)浇M合,鏈中的每個(gè) loader 會(huì)將轉(zhuǎn)換應(yīng)用在已處理過的資源上
模塊化,是導(dǎo)出為一個(gè)函數(shù)的 node 模塊
參數(shù)合并,loader 可以通過 options 對象配置
基于上面分析的幾點(diǎn),我們開始動(dòng)手
// 這個(gè)就是一個(gè)最簡單loader, // 如果我們的loader有依賴其它模塊,也得以module的寫法將在在頂部引入 import fs from 'fs'; export default function(source){ return source }
我們發(fā)現(xiàn)上面直接使用了return,是因?yàn)槭峭筋惖膌oader且返回的內(nèi)容唯一,如果你希望你的loader支持鏈?zhǔn)秸{(diào)用,將結(jié)果返給下一個(gè)loader繼續(xù)使用,這時(shí)候就需要用webpack提供的api
這里我們簡單看一下this.callback的定義,一個(gè)可以同步或者異步調(diào)用的可以返回多個(gè)結(jié)果的函數(shù)。預(yù)期的參數(shù)是
this.callback( err: Error | null, content: string | Buffer, sourceMap?: SourceMap, meta?: any )
// loader-utils 它提供了很多有用的工具 // 最常用的一個(gè)就是獲取傳入 loader 的 options import { getOptions } from 'loader-utils'; export default function(source, other) { const options = getOptions(this) // do whatever you want // ... this.callback(null, source, other) }
手寫一個(gè)loader對沒有研究過的聽上去好像有點(diǎn)難,事實(shí)上, 掌握上面所介紹的內(nèi)容及思想,就可以開始寫一個(gè)簡單的 Loader 了, 我們再來用簡單的代碼綏一下loader到底是什么?
// 首先loader它是一個(gè)node模塊,這很好理解 export const lessToCss = function(source, other) { // source 就是你即將要轉(zhuǎn)換的文件源 // TODO // 將轉(zhuǎn)換好的文件源流轉(zhuǎn)至一個(gè)管道 this.callback(null, source, other) }
loader api中有幾個(gè)好用的家伙這里就順便帶一下
this.cacheable() 從提高執(zhí)行效率上,如何處理利用緩存是極其重要的, webpack 中this.cacheable就可以輕松將loader緩存了
this.async() 當(dāng)一個(gè)loader無依賴時(shí),我們應(yīng)該異步的去返回結(jié)果
下方貼上less-loader的源碼,代碼很簡潔,結(jié)合上方我們所分析的,也很容易理解
import processResult from './processResult'; const render = pify(less.render.bind(less)); function lessLoader(source) { const loaderContext = this; const options = getOptions(loaderContext); const done = loaderContext.async(); const isSync = typeof done !== 'function'; if (isSync) { throw new Error( 'Synchronous compilation is not supported anymore. See https://github.com/webpack-contrib/less-loader/issues/84' ); } processResult(loaderContext, render(source, options)); }
總結(jié)
loader是一個(gè)node模塊
編寫loader時(shí)要遵循單一原則,每個(gè)loader只做一種"轉(zhuǎn)義"工作
webpack為我們提供了豐富的loader api
webpack為我們還提供了工具函數(shù)集——loader-utils
看完了這篇文章,相信你對Webpack實(shí)現(xiàn)Loader的方法有了一定的了解,想了解更多相關(guān)知識,歡迎關(guān)注億速云行業(yè)資訊頻道,感謝各位的閱讀!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。