loader

webpack做的事情,仅仅是分析出各种模块的依赖关系,然后形成资源列表,最终打包生成到指定的文件中。 更多的功能需要借助webpack loaders和webpack plugins完成。

webpack loader: loader本质上是一个函数,它的作用是将某个源码字符串转换成另一个源码字符串返回。(把一个代码变成另一个代码)
image.png
loader函数的将在模块解析的过程中被调用,以得到最终的源码。
全流程:
image.png
chunk中解析模块的流程:
image.png
chunk中解析模块的更详细流程:
image.png
处理loaders流程:
image.png
loader配置:
完整配置

  1. module.exports = {
  2. module: { //针对模块的配置,目前版本只有两个配置,rules、noParse
  3. rules: [ //模块匹配规则,可以存在多个规则
  4. { //每个规则是一个对象
  5. test: /\.js$/, //匹配的模块正则
  6. use: [ //匹配到后应用的规则模块
  7. { //其中一个规则
  8. loader: "模块路径", //loader模块的路径,该字符串会被放置到require中
  9. options: { //向对应loader传递的额外参数
  10. }
  11. }
  12. ]
  13. }
  14. ]
  15. }
  16. }

简化配置

  1. module.exports = {
  2. module: { //针对模块的配置,目前版本只有两个配置,rules、noParse
  3. rules: [ //模块匹配规则,可以存在多个规则
  4. { //每个规则是一个对象
  5. test: /\.js$/, //匹配的模块正则
  6. use: ["模块路径1", "模块路径2"]//loader模块的路径,该字符串会被放置到require中
  7. }
  8. ]
  9. }
  10. }

例子1:
webpack.config:

module.exports = {
    mode: "development",
    module: {
        rules: [
            {
                test: /index\.js$/, //正则表达式,匹配模块的路径
                use: [
                    {
                        loader:"./loaders/test-loader" , //加载器的路径
                        options:{
                            changeVar:"未知数"
                        }
                    }//每个加载器的使用是一个对象
                ] //匹配到了之后,使用哪些加载器
            }, //规则3
        ], //模块的匹配规则
        //noParse:是否不熬解析某个模块
    }
}

index.js:

未知数 a = 1;
未知数 b = 3
// require("./a");

test-loader.js:

var loaderUtils = require("loader-utils")   //首先要安装loader-utils工具库

module.exports = function(sourceCode){
    //sourceCode : 变量 a = 1;
    console.log("test-loader运行了")
    var options = loaderUtils.getOptions(this)
    console.log(options)
    var reg = new RegExp(options.changeVar, "g");
    return sourceCode.replace(reg, "var");
}

最终mainjs:
image.png
例子2:4321😢

loader1.js:
module.exports = function(sourceCode){
    console.log("loader1");
    return sourceCode;
}

loader2.js:
module.exports = function(sourceCode){
    console.log("loader2");
    return sourceCode;
}

loader3.js:
module.exports = function(sourceCode){
    console.log("loader3");
    return sourceCode;
}

loader4.js:
module.exports = function(sourceCode){
    console.log("loader4");
    return sourceCode;
}

webpack.config.js:
module.exports = {
    mode: "development",
    module: {
        rules: [
            {
                test: /index\.js$/, //正则表达式,匹配模块的路径
                use: ["./loaders/loader1", "./loaders/loader2"] //匹配到了之后,使用哪些加载器
            }, //规则1
            {
                test: /\.js$/, //正则表达式,匹配模块的路径
                use: ["./loaders/loader3", "./loaders/loader4"] //匹配到了之后,使用哪些加载器
            }
        ], //模块的匹配规则
    }
}

最后效果:
image.png
例子3:432143

index.js:
require("./a");

webpack.config.js:
module.exports = {
    mode: "development",
    module: {
        rules: [
            {
                test: /index\.js$/, //正则表达式,匹配模块的路径
                use: ["./loaders/loader1", "./loaders/loader2"] //匹配到了之后,使用哪些加载器
            }, //规则1
            {
                test: /\.js$/, //正则表达式,匹配模块的路径
                use: ["./loaders/loader3", "./loaders/loader4"] //匹配到了之后,使用哪些加载器
            }, //规则2
            {
                test: /index\.js$/, //正则表达式,匹配模块的路径
                use: [
                    {
                        loader:"./loaders/test-loader" , //加载器的路径
                        options:{
                            changeVar:"未知数"
                        }
                    }//每个加载器的使用是一个对象
                ] //匹配到了之后,使用哪些加载器
            }, //规则3
        ], //模块的匹配规则
        //noParse:是否不熬解析某个模块
    }
}

上题loader1-4.

最后效果:
image.png

loader中是否可以使用ES6 module? 不可以,必须用CommonJS,因为最终编译结果无load,他是在node环境下使用。