webpack loader开发

98 阅读1分钟

接触webpack也很久了,也手撸过项目,最近想研究一下loader,就自己写了一个less loader来练手。

初始化环境

mkdir my-loader && cd my-loader 
yarn init 
# or 
npm init

安装依赖

yarn add -D webpack webpack-cli

添加webpack配置

// webpack 在node环境运行,不支持es6 module 
const path = require('path') 
module.exports = { 
    ... 
    module: { 
        rules: [ 
            { 
                test: /\.less$/, 
                use: [path.resolve(__dirname,'src/my-loader.js')] 
            } 
        ] 
    } 
}

添加 loader 代码

在src目录下创建my-loader.js

const less = require('less') 
module.exports = async function(source){ 
    let cssObj = await less.render(source) 
    this.callback(null, cssObj.css) 
}

现在已经可以正常使用less了,接下来还要支持less的一些配置。

现在添加 lessOptions 的配置

const path = require('path') 
module.exports = { 
    ... 
    module: { 
        rules: [ 
            { 
                test: /\.less$/, 
                use: [ 
                    { 
                        loader: path.resolve(__dirname,'src/my-loader.js'), // +++ 添加 options 配置 
                        options: { // +++ 添加了 less 配置
                            lessOptions:{ 
                                modifyVars: { 
                                    pramiry: 'red' 
                                }
                            } 
                        } 
                    } 
                ] 
            } 
        ] 
    } 
}

修改 my-loader.js 使用 this.getOptions()来获取 lessOptions 的配置

const less = require('less') 
module.exports = async function(source){ 
    const options = this.getOptions() // +++ 获取 options 
    let cssObj = await less.render(source, options) // +++ 添加 options 
    this.callback(null, cssObj.css) 
}

Loader API

/** 
    * 
    * @param {string|Buffer} content Content of the resource file 
    * @param {object} [map] SourceMap data consumable by https://github.com/mozilla/source-map 
    * @param {any} [meta] Meta data, could be anything 
*/ 
function webpackLoader(content, map, meta) { 
    // code of your webpack loader 
}

同步编译

module.exports = function (content, map, meta) { 
    return someSyncOperation(content)
};

异步编译

module.exports = function (content, map, meta) { 
    let callback = this.async()
    someAsyncOperation(content, function (err, result) { 
        if (err) return callback(err); callback(null, result, map, meta); }); };

Loader Context

this.async

生成一个异步回调,返回 this.callback

this.callback

一个回调方法,可以同步或异步调用

this.callback( err: Error | null, content: string | Buffer, sourceMap?: SourceMap, meta?: any )

this.getOptions

获取 loader options

中文网没有更新,还是老的开发文档

Writing a Loader | webpack