首頁  >  文章  >  web前端  >  Webpack如何實作Loader? (附代碼)

Webpack如何實作Loader? (附代碼)

不言
不言轉載
2019-04-03 09:11:361838瀏覽

這篇文章帶給大家的內容是關於Webpack如何實現Loader? (附代碼),有一定的參考價值,有需要的朋友可以參考一下,希望對你有幫助。

如何實作一個Loader?

我們在上幾節有講過loader,今天我們來深入了解它們,最暴力的方式莫過於動手實現它們

#好了,回到正題, 先來回顧一下loader

loader定義: 用於轉換模組的原始程式碼。 loader 可以讓你在import 或"載入"模組時預處理檔案

簡單使用

module.exports = {
  //...
  module: {
    rules: [
      {
        test: /\.js$/,
        use: [
          {
            // loader 是导出为一个a函数的 node 模块。该函数在 loader 转换资源的时候调用
            // 给定的函数将调用 loader API,并通过 this 上下文访问
            loader: path.resolve('loader.js'),
            options: {/* ... */}
          }
        ]
      }
    ]
  }
};

回顧了loader的定義及簡單使用後,我們再來分析一下實作loader的想法

單一職責,一個loader只做一件事

鍊式組合,鏈中的每個loader 會將轉換應用在已處理過的資源上

模組化,是導出為一個函數的node 模組

參數合併,loader 可以透過options 物件配置

基於上面分析的幾點,我們開始動手

// 这个就是一个最简单loader,
// 如果我们的loader有依赖其它模块,也得以module的写法将在在顶部引入
import fs from 'fs';
export default function(source){
    return source
}

我們發現上面直接使用了return,是因為是同步類的loader且返回的內容唯一,如果你希望你的loader支持鍊式調用,將結果返給下一個loader繼續使用,這時候就需要用webpack提供的api

這裡我們簡單看一下this .callback的定義,一個可以同步或非同步呼叫的可以傳回多個結果的函數。預期的參數是

this.callback(
  err: Error | null,
  content: string | Buffer,
  sourceMap?: SourceMap,
  meta?: any
)
// loader-utils 它提供了很多有用的工具
// 最常用的一个就是获取传入 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)
}

手寫一個loader對沒有研究過的聽上去好像有點難,事實上, 掌握上面所介紹的內容及思想,就可以開始寫一個簡單的Loader 了, 我們再來用簡單的程式碼綏一下loader到底是什麼?

// 首先loader它是一个node模块,这很好理解
export const lessToCss = function(source, other) {
    // source 就是你即将要转换的文件源
    // TODO
    // 将转换好的文件源流转至一个管道
    this.callback(null, source, other)
}
讓你的loader更好用

loader api中有幾個好用的傢伙這裡就順便帶一下

#this.cacheable() 從提高執行效率上,如何處理利用快取是極其重要的, webpack 中this.cacheable就可以輕鬆將loader快取了

this.async() 當一個loader無依賴時,我們應該異步的去返回結果

案例分析

下方貼上less-loader的源碼,程式碼很簡潔,結合上方我們所分析的,也很容易理解

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));
}

總結

loader是一個node模組

寫loader時要遵循單一原則,每個loader只做一種"轉義"工作

webpack為我們提供了豐富的loader api

webpack為我們也提供了工具函數集-loader-utils

【相關推薦:JavaScript影片教學

以上是Webpack如何實作Loader? (附代碼)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:segmentfault.com。如有侵權,請聯絡admin@php.cn刪除