来!简单写个webpack loader

302 阅读1分钟

目的

一般来说很少这种需求,但是有了这种需求之后,发现很难找到copy的对象,这篇文章就是给那些想写webpack loader的一个参考的例子,偶尔我也可以回来看看,毕竟我也容易忘记(还是写的少,但是这种东西怎么写得多呢???)

先看用法

写一个简单替换url的loader

 module.exports = {
    module: {
      	rules: [{
        test: /\.js$/,
        loader: 'path-replace-loader',
        exclude: /(node_modules)/,
        options: {
          path: 'ORIGINAL_PATH',
          replacePath: "REPLACE_PATH"
        }
      }]
    }
  }

就是如上用

源码来了

const fs = require("fs")
const loaderUtils = reuqire('loader-utils')

module.exports = function(source) {
  // this是指向谁呢?指向一个load的runner对象(其实我也不懂)
  // 转换需要大量计算,非常耗时,所以下面这行代码就是在需要被处理的文件或者其依赖的文件没有发生变化时,是不会重新调用对应的Loader去执行转换操作
  this.cacheable && this.cacheable()
  // webpack 内部的处理异步方法
  const callback = this.async()
  // 配置
  const options = loaderUtils.getOptions(this)

  if(this.resourcePath.indexOf(options.path) > -1) {
   const newPath = this.resourcePath.replace(options.path, options.replacePath)
   fs.readFile(newPath, (err, data) => {
     if(err) {
       if(err.code === 'ENOENT') return callback(null, source)
     }
     // 使用该方法将新的文件加入webpack依赖中,并且通过callback返回内容
     this.addDependency(newPath)
     callback(null, data)
   })
  }else {
   callback(null, source)
  }
}

 // 通过exports.raw 属性告诉webpack该Loader是否需要二进制数据
 module.exports.raw = true

总结

大概一个简单的loader出炉了,其实如果你想copy一下,然后仿照一下,还是可以用了,所以就先这样了,欢迎评论里面告诉我这个this指向了谁