webpack手写同步loader

  • Loader其实就是一个函数,只需要自定义一个模块,在模块中暴露一个函数,在函数中实现Loader相关的功能即可
  • 注意点

    • 这个函数必须是一个普通函数(es5),不能是箭头函数(es6),因为webpack在调用Loader的时候会修改这个函数中的this,而如果是箭头函数webpack就不能修改了
    • webpack在调用Loader的时候会将打包文件的内容传递给实现Loader的函数中的形参,拿到内容后就可以对内容进行操作,然后再将操作后的内容返回回去即可
    • 在loader中返回的数据必须是字符串类型或者是二进制类型

  • 需求:将index.js中的nhw替换为nb

  • index.js:console.log("123nhw123");
  • 创建一个ReplaceLoader模块:主要用来替换文本内容

loader目录

// module.exports将函数暴露出去,source可拿到打包文件内容,return将操作后的内容返回
module.exports = function (source) {
    source = source.replace(/nhw/g, "nb");
    return source;
};
  • 在webpack.config.js中添加配置:

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

  • 处理loader参数

  • 在webpack.config.js中配置Loader的时候, 可以通过options配置一些额外的参数

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

---

  • 获取参数方法一(不推荐)

  • 通过loader函数中的this获取 this.query

---

  • 获取方法二(推荐)

  • 通过loader-utils模块获取

    • 安装模块:npm install --save-d loader-utils
    • 导入模块:const loaderUtils = require('loader-utils');
    • ReplaceLoader.js:

      const loaderUtils = require('loader-utils');
      module.exports = function (source) {
          // console.log(this.query.name);
          let options = loaderUtils.getOptions(this);
          console.log(options.name);
          source = source.replace(/nhw/g, options.name);
          return source;
      };

  • 校验loader参数

  • 通过schema-utils模块来校验

    • 安装模块:npm install --save-d schema-utils
    • 导入模块:const validateOptions = require('schema-utils');
    • ReplaceLoader.js:

      • 当options中传递的参数类型不符就会报错
      const loaderUtils = require('loader-utils');
      const validateOptions = require('schema-utils');
      
      module.exports = function (source) {
          // 1.获取webpack传递过来的参数
          // console.log(this.query.name);
          let options = loaderUtils.getOptions(this);
          console.log(options.name);
          // 2.定制校验的规则
          let schema = {
              type: "object",
              // 可以在properties中告诉webpack, 当前loader可以传递哪些参数
              properties: {
                  // 可以传递name参数
                  name: {
                      // name参数的数据类型必须是字符串类型
                      type: "string"
                  }
              },
              additionalProperties: false
          };
          // 3.利用校验方法校验传递过来的参数是否符合指定的规则
          validateOptions(schema, options, 'RepalceLoader');
          source = source.replace(/nhw/g, options.name);
          return source;
      };

  • 简化loader使用

  • 只编写loader的名称,不需要通过path指定loader的路径
  • 在webpack.config.js中使用resolveLoader配置来简化

    module.exports = {
        resolveLoader: {
            // 起别名
            alias: {
                ReplaceLoader: path.resolve(__dirname, "loader/ReplaceLoader.js")
            }
            // 或者先在node_modules目录下查找再在./loader目录下查找
            // modules: [ 'node_modules', './loader'],
        },
    }
  • 于是在loader中只用写:loader: path.resolve('ReplaceLoader'),

    module: {
        rules: [{
            test: /\.js$/,
            use: [{
                loader: 'ReplaceLoader',
                options: {
                    name: "lyt"
                }
            }]
        }]
    }

最后修改:2021 年 04 月 11 日 02 : 09 AM
如果觉得我的文章对你有用,请随意赞赏!