1. 程式人生 > 實用技巧 >Webpack4.0各個擊破(6)loader篇

Webpack4.0各個擊破(6)loader篇

目錄

一. loader綜述

loaderwebpack的核心概念之一,它的基本工作流是將一個檔案以字串的形式讀入,對其進行語法分析及轉換(或者直接在loader中引入現成的編譯工具,例如sass-loader中就引入了node-sass將SCSS程式碼轉換為CSS程式碼,再交由css-loader處理),然後交由下一環節進行處理,所有載入的模組最終都會經過moduleFactory處理,轉成javascript可以識別和執行的程式碼,從而完成模組的整合。

loader支援鏈式呼叫,所以開發上需要嚴格遵循“單一職責”

原則,即每個loader只負責自己需要負責的事情:將輸入資訊進行處理,並輸出為下一個loader可識別的格式。

實際開發中,很少會出現需要自己寫loader來實現複雜需求的場景,如果某個副檔名的檔案無法快速整合到自動化構建工具裡,估計很快就會被拋棄了,大家都那麼忙是吧。但是瞭解loader的基本原理和編譯器的基本原理卻是非常有必要的。

二. 如何寫一個loader

如果需要編寫一個功能完整的loader,建議先到webpack的官方網站瀏覽一下loader有哪些API,地址:webpack官網-loader API,其中對於編寫同步loader非同步loader如何跳過loader如何獲取options

配置項等等都做了非常詳細的解釋,本篇中不再贅述。

假設現在要實現一個dash-loader,它的功能是載入並處理名稱為*.tpl.html的檔案,將其變為一個CommonJs模組。也就是說要完成一個如下的基本轉換:

轉換前的文字:

<div>
    <h3>這裡是標題</h3>
    <p>這裡是內容</p>    
</div>

轉換後的文字:

var str = '<div><h3>這裡是標題</h3><p>這裡是內容</p></div>';
module.exports = str;

那麼webpack.config.js中需要增加如下的配置:

...
module:{
    rules:[{
        test: /\.tpl\.html$/,
        use:[{
            loader:'dash-loader'
        }]
    }]
}

在專案的node_modules依賴資料夾中新建dash-loader資料夾,並在其中新建一個index.js檔案,內容的基本格式為:

//index.js
module.exports = function(source){
    var tpl="";
    source.split(/\r?\n/).forEach(function(line){
        line=line.trim();
        if(!line.length){
            return;
        }
        //對line進行處理...
        tpl+=line;
    });
    return "var tpl=\'" + tpl + "\'\nmodule.exports = tpl"; 
}

最終由dash-loader返回的資料就好像是從某個CommonJs模組中讀入的一樣了。

三. loader的編譯器本質

瞭解了loader的基本結構,那麼loader裡到底應該寫點什麼才能完成程式碼轉換呢?這就涉及到了一個新的概念——編譯器(Compiler)。一個基本的編譯器,需要經過tokenize,parse,transform,stringify幾個核心步驟,它的應用是非常廣的,SPA中的virtual-DOM的解析,babel中的ES6語法解析等等,babel的官網曾經推薦過一個非常棒的開源專案(10k+Star),詳細講述瞭如何一步一步實現一個編譯器的,建議感興趣的同學可以自行學習:

【The-Super-Tiny-Compiler】——https://github.com/jamiebuilds/the-super-tiny-compiler

筆者最近在閱讀《你不知道的javascript》一書,發現第一節就在講述基本的編譯原理,是的,你每天都在用的javascript的編譯過程,和上面提及的都是一樣的,你說要不要學?

【參考】

《如何編寫一個loader》

作者:大史不說話
連結:Webpack4.0各個擊破(6)loader篇
來源:部落格園
著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。