webpack-自定義loader


如何自己編寫一個loader:

loader是一個函數,聲明式函數,不能使用箭頭函數;拿到源碼,做進一步的修飾處理,再返回處理后的源碼就可以了

官方文檔:https://webpack.js.org/contribute/writing-a-loader

接口文檔:https://webpack.js.org/api/loaders

簡單案例:創建一個替換源碼中字符串的loader

創建一個項目文件夾,並初始化:npm init -y

安裝webpack webpack-cli:npm i webpack webpack-cli -D

項目里創建一個文件夾src,再創建一個文件夾myLoaders存放自己寫的loader

創建配置文件:webpack.config.js

##webpack.config.js
const path = require("path")
module.exports = {
    mode:"development",
    entry:"./src/index.js",
    output:{
        path:path.resolve(__dirname,"./dist"),
        filename:"[name].js"
    },
    module:{
        rules:[{                  //配置loader
            test:/\.js$/,
            use:[
                {
                    loader:path.resolve(__dirname,'./myLoaders/replaceLoader.js'),
                    options:{
                        name:"替換傳參"
                    }
                }
            ]
        }]
    }
}
##寫一個替換的loader----replaceLoader.js
//loader是一個函數,不可以是箭頭函數
module.exports  = function(source){
    //source為接收的源代碼
    //不能用箭頭函數的原因是,會改變this的指向,接收參數需要借助this
    //如果loader配置了options對象,this.query指向這個options對象
    console.log(source,this.query);
    //必須有返回值
    return source.replace("world","kkb")
}

運行:npm run dev

 

 傳參:this.query

 

 另一種傳參的方法是,安裝loader-utils,處理loader參數的工具

this.callback:可用來返回多個信息,不止是處理好的源碼

返回四個參數:

err:錯誤信息;content:string | Buffer;sourceMap:可被這個模塊解析的source map;meta:任意信息;

##replaceLoader.js
//loader是一個函數,不可以是箭頭函數
module.exports  = function(source){
    //return source.replace("world","kkb")
    const result = source.replace("world",this.query.name);
    this.callback(null,result)
}

this.async:處理loader里有異步的事情---告訴loader-runner這個loader將會異步回調,返回this.callback

##replaceLoader.js
module.exports  = function(source){
    setTimeout(() => {
        const result = source.replace("world",this.query.name);
        return result
    },1000)
    
}
執行npm run dev報錯,說明loader不會自動解析異步操作

解決辦法:this.async

module.exports  = function(source){
    //this.async返回一個callback,他=this.callback
    const callback = this.async();//告訴loader-runner這里有異步操作
    setTimeout(() => {
        const result = source.replace("world",this.query.name);
        callback(null,result)
    },1000)    
}

 

處理多個loader的順序問題: 執行順序:自右往左,自下往上

##webpack.config.js
const path = require("path")
module.exports = {
    mode:"development",
    entry:"./src/index.js",
    output:{
        path:path.resolve(__dirname,"./dist"),
        filename:"[name].js"
    },
    module:{
        rules:[{
            test:/\.js$/,//配置loader
            use:[
                path.resolve(__dirname,"./myLoaders/replaceLoader.js"),  
                {
                    loader:path.resolve(__dirname,'./myLoaders/replaceLoaderAaync.js'),
                    options:{
                        name:"您好"
                    }
                }             
            ]
        }]
    }
}
##replaceLoader.js

module.exports  = function(source){
    return source.replace("world","word");   
}
##replaceLoaderAaync.js

module.exports = function(source){
    const callback = this.async();
    setTimeout(() => {
        const result = source.replace("hello",this.query.name);
        callback(null,result)
    },1000)  
}

loader的路徑問題:loader配置的時候,路徑太繁瑣,我們可以對路徑進行一下設置

##webpack.config.js

const path = require("path")
module.exports = {
    resolveLoader:{
        modules:["node_moudles","./myLoaders"]//遇到loader,先去node_modules里找,然后再去./myLoaders里找
    },
    module:{
        rules:[{
            test:/\.js$/,//配置loader
            use:[
                "replaceLoader", //本地路徑  如果是npm安裝進來的 不用考慮路徑
                {
                    loader:'replaceLoaderAaync',
                    options:{
                        name:"您好"
                    }
                }             
            ]
        }]
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM