webpack学习记录(三)——自定义Loader

198 阅读1分钟

Loader 基础

由于 Webpack 是运行在 Node.js 之上的,一个 Loader 其实就是一个 Node.js 模块,这个模块需要导出一个函数。

一个最简单的 Loader 的源码如下:

module.exports = function(source) {
  // source 为 compiler 传递给 Loader 的一个文件的原内容
  // 该函数把原内容返回了,相当于该 Loader 没有做任何转换
  return source;
};

获得 Loader 的 options

webpack内置的loader-utils可以帮助你获得传入的options配置,以便控制loader

const loaderUtils = require('loader-utils');
module.exports = function(source) {
  // 获取到用户给当前 Loader 传入的 options
  const options = loaderUtils.getOptions(this);
  return source;
};

同步与异步

Loader 也有同步和异步之分,上面介绍的Loader都是同步的Loader。有些场景下转换的步骤需要用异步完成的,例如网络请求。

    module.exports = function(source) {
    // 告诉 Webpack 本次转换是异步的,Loader 会在 callback 中回调结果
    var callback = this.async();
    someAsyncOperation(source, function(err, result, sourceMaps, ast) {
        // 通过 callback 返回异步执行后的结果
        callback(err, result, sourceMaps, ast);
    });
};

更多的loader API参考

实战

目的:写一个把console.log(xxxx)的都转化成console.log('hello world')的loader

1.创建一个my-loader文件

在index.js:

module.exports = function (source) {
  
  return source.replace(/console\.log\(.+\)/, "console.log('hello world')");
    
};

2.使用本地的自定义的my-loader

ResolveLoader 用于配置 Webpack 如何寻找 Loader。 默认情况下只会去 node_modules 目录下寻找,为了让 Webpack 加载放在本地项目中的 Loader 需要修改 resolveLoader.modules。 webpack.config.js:

 const path = require('path');

module.exports = {
  entry:{
    index:'./src/index.js',
  },

  module: {
    rules: [
      {
        test: /\.js$/,
        use: ['my-loader'],  //使用自定义的loader
      }
    ]
  },
  resolveLoader:{
    // 去哪些目录下寻找 Loader,有先后顺序之分
    modules: [path.resolve(__dirname,'./loader/'),'node_modules'],
  },
};

好了,这样一个自定义的loader就写好了~