webpack module.rules执行顺序

756 阅读1分钟
rule.use中的loader执行顺序是从右到左,从下到上执行的,类似于栈的执行顺序,后进先出
module: {
        rules: [
            {
                test: /.less$/,
                use: ['style-loader', 'css-loader', 'less-loader'],
            },
        ],
    }

那么rules中的各个匹配规则执行顺序是怎么样呢?

module: {
    rules: [
        {
            test: /\\.less$/,
            loader: 'style-loader',
        },
        {
            test: /\\.less$/,
            loader: 'css-loader',
        },
        {
            test: /\\.less$/,
            loader: 'less-loader'
        }
    ]
}

自己写了三个loader

loaderone.js
module.exports = function(source) {
    console.info('---------------loaderone');
    return source;
};

loadertwo.js
module.exports = function(source) {
    console.info('---------------loadertwo');
    return source;
};

loaderthree.js
module.exports = function(source) {
    console.info('---------------loaderthree');
    return source;
};
module: {
    rules: [
        {
            test: /\\.less$/,
            loader: 'style-loader',
        },
        {
            test: /\\.less$/,
            use: [{
                loader: path.resolve(__dirname, 'loaderthree'),
            }],
        },
        {
            test: /\\.less$/,
            loader: 'css-loader',
        },
        {
            test: /\\.less$/,
            use: [{
                loader: path.resolve(__dirname, 'loadertwo'),
            }],
        },
        {
            test: /\\.less$/,
            loader: 'less-loader'
        },
        {
            test: /\\.less$/,
            use: [{
                loader: path.resolve(__dirname, 'loaderone'),
            }],
        },
    ]
}
输出顺序为  loaderone loadertwo loaderthree
说明rules中的执行顺序也是按照从右到左,从下到上来执行的。

假如我们想控制rules中各个匹配规则的执行顺序,可以通过rule.enforce来控制,这个字段有两个值:

  • pre(优先执行)
  • post(最后执行)
module: {
    rules: [
        {
            test: /\\.less$/,
            loader: 'style-loader',
        },
        {
            test: /\\.less$/,
            enforce: 'pre'
            use: [{
                loader: path.resolve(__dirname, 'loaderthree'),
            }],
        },
        {
            test: /\\.less$/,
            loader: 'css-loader',
        },
        {
            test: /\\.less$/,
            use: [{
                loader: path.resolve(__dirname, 'loadertwo'),
            }],
        },
        {
            test: /\\.less$/,
            loader: 'less-loader'
        },
        {
            test: /\\.less$/,
            enforce: 'post'
            use: [{
                loader: path.resolve(__dirname, 'loaderone'),
            }],
        },
    ]
}
输出为:loaderthree  loadertwo loaderone

如果未设置enfore,这个只默认为normal,执行顺序优先级为pre > normal > post,除此之外还有一个额外的种类(inline类型官方不推荐用)

image.png

在进出loader的时候都会经历两个阶段,pitch阶段与normal阶段

  • pitch阶段就是执行loader上的pitch方法(loader函数上的可选属性,本质是一个函数)
  • normal阶段就是执行loader函数

对上面的loader文件增加pitch函数

loaderone.js
function loaderone(source) {
    console.info('normal--loaderone');
    return source;
}
loaderone.pitch = () => {
    console.info('pitch--loaderone');
};
module.exports = loaderone;

loadertwo.js
function loadertwo(source) {
    console.info('normal--loadertwo');
    return source;
}
loadertwo.pitch = () => {
    console.info('pitch--loadertwo');
};
module.exports = loadertwo;

loaderthree.js
function loaderthree(source) {
    console.info('normal--loaderthree');
    return source;
}
loaderthree.pitch = () => {
    console.info('pitch--loaderthree');
};
module.exports = loaderthree;
module: {
    rules: [
        {
            test: /\\.less$/,
            loader: 'style-loader',
        },
        {
            test: /\\.less$/,
            use: [{
                loader: path.resolve(__dirname, 'loaderthree'),
            }],
        },
        {
            test: /\\.less$/,
            loader: 'css-loader',
        },
        {
            test: /\\.less$/,
            use: [{
                loader: path.resolve(__dirname, 'loadertwo'),
            }],
        },
        {
            test: /\\.less$/,
            loader: 'less-loader'
        },
        {
            test: /\\.less$/,
            use: [{
                loader: path.resolve(__dirname, 'loaderone'),
            }],
        },
    ]
}
输出为:
pitch--loaderthree  
pitch--loadertwo 
pitch--loaderone 
normal--loaderone 
normal--loadertwo
normal--loaderthree

参考文章:blog.csdn.net/qq_41581588…