如何自己編寫一個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:"您好" } } ] }] } }
