從0實現一個webpack loader

Ilion發表於2019-05-02

在實現之前我們先來了解以下webpack的打包流程:

  • 初始化配置物件,建立compiler物件
  • 例項化外掛,呼叫外掛的apply方法,掛載外掛的監聽
  • 從入口檔案執行編譯,按照檔案型別呼叫相應的loader,在合適的時間呼叫plugin執行,並查詢各個模組的依賴
  • 將編譯後的程式碼組裝成一個個程式碼塊(chunk),並安依賴和配置確定輸出內容
  • 根據output把檔案輸出到物件的目錄下

可以看出loader在webpack打包的過程中起到了至關重要的作用。

loader到底做了什麼?

由於webpack是基於Node的所以webpack只能識別.js檔案,所以針對其他的檔案就需要轉譯,這時候就需要用到我們的loader了。

loader是檔案載入器,能夠載入資原始檔,並對這些檔案進行特定的處理,然後打包的指定檔案中,簡單來說就是將webpack傳入的字串做出特定的處理修改。

比如:A.less -> A.css

loader特點

  • loader的執行順序和程式碼書寫的順序是相反的,即:最後一個loader最先執行,第一個loader最後執行
  • 第一個執行的loader會接收原始檔做為引數,下一次執行的loader會接收前一個loader執行的返回值做為引數

loader編寫原則

  • 單一原則: 每個 Loader 只做一件事;
  • 鏈式呼叫: Webpack 會按順序鏈式呼叫每個 Loader;
  • 統一原則: 遵循 Webpack 制定的設計規則和結構,輸入與輸出均為字串,各個 Loader 完全獨立,即插即用;

實現loader

需求:將.txt字尾的檔案中的內容倒敘並大寫。

首先建立webpack-loader資料夾。輸入npm init -y初始化。安裝webapck和webpack-cli:npm i webpack webpack-cli -D

package.json檔案下新增指令碼

...
"scripts": {
    "build": "webpack",
    ...
}
...
複製程式碼

建立test.txt資料夾輸入內容:hello world

建立loaders資料夾新建兩個loader: 編寫兩個loader是為了符合單一職責原則。

// loader1,倒敘
module.exports = function (src) {
 src = src.split('').reverse().join('')
 return src;
}
// loader2,大寫
module.exports = function (src) {
   src = src.toUpperCase()
  // 這裡為什麼要這麼寫?因為直接返回轉換後的字串會報語法錯誤,
  // 這麼寫import後轉換成可以使用的字串
  return `module.exports = '${src}'`
 }
複製程式碼

新增webpack.config.js配置檔案

const path = require('path')

module.exports = {
  entry: {
    app: './test.txt'
  },
  module: {
    rules: [
      {
        test: /\.txt$/,
        use: [
          './loaders/myloader2.js','./loaders/myloader1.js'
        ]
      }
    ]
  },
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name].txt'
  }
}
複製程式碼

檔案結構

從0實現一個webpack loader

最後:輸入命令列npm run build 打包成功,並生成了dist/app.txt檔案。

從0實現一個webpack loader

從0實現一個webpack loader

開啟app.txt檔案在最後找到了轉譯後的字元:

從0實現一個webpack loader

參考:juejin.im/post/5cb01f…

相關文章