Webpack--自己寫一個Loader

先直接來看代碼:

module.exports = function(source){
    return source.replace('Webpack', 'JavaScript');
}

這三行代碼就實現了一個最簡單的Loader,它的作用是將源碼中出現的所有’Webpack’替換成’JavaScript’。

參數source就是所處理的文件的代碼,是一個字符串。

所導出的函數必須是使用function關鍵字聲明的,不可以使用箭頭函數,因爲Webpack會修改函數的this,而箭頭函數沒有自己的this,所以可能會出錯。

寫好的Loader就可以在配置文件中引入使用:

const path = require('path');
module.exports = {
    mode: 'development',
    entry: {
        index: './src/index.js'
    },
    
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: '[name].js'
    },
    module: {
        rules: [{
            test: /\.js/,
            use: [path.resolve(__dirname, './loader/replaceLoader.js')]
        }]
    }
}

一般我們使用的Loader都是通過npm或者yarn安裝的,那麼配置的時候直接寫Loader名即可,然而自己寫的Loader則需要寫絕對路徑。

這裏岔開一下,如果我們希望自己寫的Loader也能直接通過Loader名的方式引用,只需要配置resolveLoader即可:

module.exports = {
    ...,
    resolveLoader: {
        modules: ['./node_modules', './loader']
    }
}

上述配置的意思是當需要使用Loader的時候,先去./node_modules裏尋找,找不到就到./lodaer目錄裏去找。

配置完成之後就可以打包了,沒有問題的話就能看到打包生成的文件出現了我們希望的變化。
在這裏插入圖片描述


我們在使用第三方Loader的時候,經常會通過options來爲Loader進行一些配置,那麼我們自己寫的Loader該怎麼接受並處理這些options呢?

首先現在配置文件裏進行配置:

module.exports = {
    ...,
    module: {
        rules: [{
            test: /\.js$/,
            use: [{
                loader: path.resolve(__dirname, './loader/replaceLoader.js'),
                options: {
                    name: 'CSS'
                }
            }]
        }]
    }
}

上面的配置項爲我們寫的Loader傳入了一個 name option。那麼,我們可以在Loader之中,通過this.query.name得到我們傳入的參數。

module.exports = function(source) {
    return source.replace('Webpack', this.query.name);
}

這樣預期打包的結果就應該是console.log('Hello CSS')

在這裏插入圖片描述


除了用直接return的方法,還可以通過this.callback來返回處理後的結果。

module.exports = function(source) {
    const result = source.replace('Webpack', this.query.name);
    this.callback(null, result);
}

this.callback可以接受四個參數,分別是錯誤信息,處理後的結果,sourceMap,和一些額外信息。


如果說希望在Loader裏面執行一些異步的代碼,則需要調用this.async()

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

this.async返回的結果就是一個this.callback


之前我們是通過this.query來獲取我們在配置文件中傳入的配置項。而Webpack的官方文檔推薦的是通過loader-utils這個庫來獲取。

const loaderUtils = require('loader-utils');

module.exports = function(source) {
    const options = loaderUtils.getOptions(this);
    return source.replace('Webpack', options.name);
}
```’
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章