webpack loader的"套路"

學習webpack loader,最後模擬style-loader、less-loaderjavascript

什麼是loader

  • loader是一個函數,用來把文件轉換成webpack識別的模塊。

loader API

  • this.callback,一個能夠同步或者異步調用的能夠返回多個結果的函數。
  • this.async,異步的loader,返回this.callback

如何編寫loader

設置

  • webpack默認從node_modules裏找loader
  • 直接引入loader
{
  test: /\.js$/
  use: [
    {
      loader: path.resolve('path/to/loader.js'),
      options: {/* ... */}
    }
  ]
}
複製代碼
  • 若是有多個loader的目錄,能夠設置loader的目錄,webpack會從設置的目錄裏找到loader
resolveLoader: {
  modules: [
    'node_modules',
    path.resolve(__dirname, 'loaders')  //本身開發的loaders
  ]
}
複製代碼

簡單用法

  • 當使用一個loader時,這個loader函數只有一個參數,參數是包含文件內容的字符串。
  • 同步loader能夠返回一個表明模塊轉化後的簡單的值
  • loader的返回值是javascript代碼字符串或者是Buffer
//css-loader 把css解析成webpack識別的模塊
module.exports = function(source) {
  return `module.exports=${source}`;
}
複製代碼

複雜用法

  • 當配置多個loader時,loader的執行順序時從右往左,右邊的執行結果做爲參數傳到左邊。
  • less-loader把less轉化成css,傳給css-loader,css-loader把結果給style-loader,style-loader返回javascript代碼字符串。
{
    test:/\.less$/,
    use:[
        'style-loader','css-loader','less-loader'
    ]
}
複製代碼

編寫原則

  • 單一職責。每一個loader只負責一件事情。
  • 使用鏈式調用,確保loader的依賴關係的正確。
  • 無狀態性,確保loader在不一樣模塊轉換之間不保存狀態。每次運行都應該獨立於其餘編譯模塊以及相同模塊以前的編譯結果。

loader工具庫

  • loader-utils,能夠獲取loader的options
  • schema-utils,校驗loader的options的合法性

模擬less-loader、css-loader、style-loader

  • less-loader負責把less編譯成css
const less = require('less');
module.exports = function (source) {
    less.render(source, (e, output)=>{
        this.callback(e,output.css);    //把編譯後的css返回給下一個loader
    });
};

複製代碼
  • css-loader負責把css交給下一個loader
module.exports = function (source) {
    return source;          //source是上個loader的返回值,若是沒有上一個loader,則是css的內容
};
複製代碼
  • style-loader把css添加到style標籤裏
module.exports = function (source) {
    return `const e = document.createElement('style'); e.innerHTML = ${JSON.stringify(source)}; document.head.appendChild(e);`;
};
複製代碼
  • 雖然每一個loader功能簡單,可是loader以前職責單一,方便擴展。
總結

webpack loader的功能遠不止這些,本文算是編寫loader的"套路"入門篇。css

參考
相關文章
相關標籤/搜索