webpack的loader和plugin

2020-05-03  本文已影响0人  风雅欢乐

loader

webpack loader: loader本质上是一个函数,它的作用是将某个源码字符串转换成另一个源码字符串返回。

loader函数将在模块解析的过程中被调用,以得到最终的源码。按照loader配置的书写顺序, 多个loader从后往前依次调用, 后面一个loader的输出结果传入前一个loader继续处理.

2020-01-13-09-35-44.png

代码示例

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

module.exports = function (sourceCode) {
    var options = loaderUtils.getOptions(this);
    var reg = new RegExp(options.changeVar, "g");
    return sourceCode.replace(reg, "var");
}

在配置文件中的options处书写的额外参数, 可以在loader函数内的this中读取到, webpack在this对象内放了很多东西. 使用load-utils包可以帮助我们解析this对象的内容.

plugin

loader的功能定位是转换代码,而一些其他的操作难以使用loader完成,比如:

plugin的本质是一个带有apply方法的对象, 习惯上我们会将该对象写成构造函数的模式.

apply方法有一个参数compiler, compiler对象是在初始化阶段创建的, 整个webpack打包过程中只有一个compiler对象, 后续完成打包工作的是compiler对象内部创建的compilation(每一次具体的打包过程都会有新的compilation对象). apply方法会在创建好compiler对象后调用, 并向方法传入compiler.

代码示例

module.exports = class MyPlugin {
    
    constructor(filename = 'filelist.txt') {
        this.filename = filename;
    }
    
    apply(compiler) {
        // 在这里注册事件, 类似于window.onload
        compiler.hooks.emit.tap("MyPlugin-emit", function(compilation) {
            // 事件处理函数
            var fileList = [];
            for (const key in compilation.assets) {
                var content = `[${key}] 大小: ${compilation.assets[key].size()}b`;
                fileList.push(content);
            }
            var str = fileList.join("\n\n");
            compilation.assets[this.filename] = {
                source() {
                    return str;
                },
                size() {
                    return str.length;
                }
            };
        });
    }
}

常用扩展

webpack内置插件

所有的webpack内置插件都作为webpack的静态属性存在

const webpack = require("webpack");
new webpack.插件名(options);

解决路径问题

在某些情况下, 例如将图片用file-loader输出到dist/img目录下, js文件输出到dist/scripts目录下, 页面文件输出到dist/html目录下, 此时js对图片的引用会产生问题.

这种问题发生的根本原因是: 模块中的路径来自于某个loader或plugin, 当产生路径时, loader或plugin只有相对于dist目录的路径, 并不知道该路径将在哪个资源中使用, 从而无法确定最终的正确路径.

面对这种情况, 需要依靠webpack的配置publicPath解决.

注意: publicPath通常在output配置项中, 本身没有任何作用, 但是某些loader和plugin会读取这个publicPath, 并且它们导出的地址前面, 拼接上这个配置. 通常output里配置为publicPath: "/" 这样, 文件的地址就变成了绝对路径.

一般, 会用到publicPath的loader和plugin, 本身也会支持在自己的配置项中再单独配置publicPath项.

上一篇 下一篇

猜你喜欢

热点阅读