自定义Loader

遵循规范,输入,输出。

同步loader

loader函数的第一个入参总是content,即上一个loader输出的内容,返回值可以是处理后的内容或者使用this.callback回调内容,返回值为undefined。

  1. module.exports = function(content, map, meta) {
  2. return someSyncOperation(content);//直接返回处理后的内容
  3. };
  1. module.exports = function(content, map, meta) {
  2. this.callback(null, someSyncOperation(content), map, meta);
  3. return; // 当调用 callback() 时总是返回 undefined
  4. };

异步loader

使用 this.async 来获取 callback 函数:

  1. module.exports = function(content, map, meta) {
  2. var callback = this.async();
  3. someAsyncOperation(content, function(err, result) {
  4. if (err) return callback(err);
  5. callback(null, result, map, meta);
  6. });
  7. };

“Raw”loader

默认情况下,资源文件会被转化为 UTF-8 字符串,然后传给 loader。通过设置 raw,loader 可以接收原始的 Buffer。每一个 loader 都可以用 String 或者 Buffer 的形式传递它的处理结果。Complier 将会把它们在 loader 之间相互转换。
raw-loader.js

  1. module.exports = function(content) {
  2. assert(content instanceof Buffer);
  3. return someSyncOperation(content);
  4. // 返回值也可以是一个 `Buffer`
  5. // 即使不是 raw loader 也没问题
  6. };
  7. module.exports.raw = true;

越过 loader(Pitching loader)

可以利用pitching阶段做一些事情,

  1. module.exports = function(content) {
  2. return someSyncOperation(content, this.data.value);
  3. };
  4. module.exports.pitch = function(remainingRequest, precedingRequest, data) {
  5. data.value = 42;
  6. };

loader的上下文对象

  • this.version
  • this.context:模块所在的目录
  • this.request:解析出来的模块加载字符串
  • this.query:对应loader的options配置项
  • this.callback:
    1. this.callback(
    2. err: Error | null,
    3. content: string | Buffer,
    4. sourceMap?: SourceMap,
    5. meta?: any
    6. );
  1. 第一个参数必须是 Error 或者 null
  2. 第二个参数是一个 string 或者 Buffer
  3. 可选的:第三个参数必须是一个可以被这个模块解析的 source map。
  4. 可选的:第四个选项,会被 webpack 忽略,可以是任何东西(例如一些元数据)。
  • this.async
  • this.data:pitch阶段和正常阶段之间共享的data对象
  • this.cacheable:设置是否可缓存标志的函数
  • this.loaders:所有loader组成的数组,在pitch阶段可以写入:

    loaders = [{request: string, path: string, query: string, module: function}]
    
  • this.loaderIndex:当前loader在loaders数组中的索引

  • this.resource:request中的资源部分,报错参数,如”/abc/resource.js?rrr”
  • this.resourcePatch:资源路径,不包括参数
  • this.resourceQuery:资源的query参数
  • this.target: 从配置项中传递过来,web/node等
  • this.sourceMap
  • this.emitWarning/this.emitError
  • this.loadModule
  • this.resolve
  • this.addDependency
  • this.addContextDependency
  • this.clearDependencies
  • this.emitFile
  • this.fs

    自定义Plugin

    步骤

  • 定义一个JavaScript命名函数;

  • 在定义的插件函数上定义一个apply方法;
  • 指定一个绑定到webpack自身的事件钩子;
  • 处理webpack内部实例的特定数据;
  • 功能完成后调用webpack提供的回调。 ```javascript // 1.一个 JavaScript 命名函数。 function MyExampleWebpackPlugin() {

}; // 2.在插件函数的 prototype 上定义一个 apply 方法。 MyExampleWebpackPlugin.prototype.apply = function(compiler) { // 3.指定一个挂载到 webpack 自身的事件钩子。 compiler.plugin(‘webpacksEventHook’, function( compilation / 4.处理 webpack 内部实例的特定数据。/, callback) { console.log(“This is an example plugin!!!”); // 5.功能完成后调用 webpack 提供的回调。 callback(); }); };

<a name="mszeI"></a>
### Compiler和Compilation

- compiler:webpack运行整体的hook,如解析输入输出等。
```javascript
compiler.hooks.someHook.tap(...)
  • compilation:编译过程中细节的hooks,如加载模块儿相关的hook

    compilation.hooks.someHook.tap(...)
    

    resolver和parser

  • parser:解析模块语句等细节处的hook

    compiler.hooks.normalModuleFactory.tap(factory => {
    factory.hooks.parser.tap((parser, options) => {
      parser.hooks.someHook.tap(...)
    })
    })
    

  • sourceMap原理