非常教程

Webpack参考手册

接口 | API

加载程序 API | Loader API

所谓 loader 只是一个导出为函数的 JavaScript 模块。loader runner 会调用这个函数,然后把上一个 loader 产生的结果或者资源文件(resource file)传入进去。函数的 this 上下文将由 webpack 填充,并且 loader runner 具有一些有用方法,可以使 loader 改变为异步调用方式,或者获取 query 参数。

第一个 loader 的传入参数只有一个:资源文件(resource file)的内容。compiler 需要得到最后一个 loader 产生的处理结果。这个处理结果应该是 String 或者 Buffer(被转换为一个 string),代表了模块的 JavaScript 源码。另外还可以传递一个可选的 SourceMap 结果(格式为 JSON 对象)。

如果是单个处理结果,可以在同步模式中直接返回。如果有多个处理结果,则必须调用 this.callback()。在异步模式中,必须调用 this.async(),来指示 loader runner 等待异步结果,它会返回 this.callback() 回调函数,随后 loader 必须返回 undefined 并且调用该回调函数。

例子

同步加载程序

sync-loader.js

module.exports = function(content) {
  return someSyncOperation(content);
};

sync-loader-with-multiple-results.js

module.exports = function(content) {
  this.callback(null, someSyncOperation(content), sourceMaps, ast);
  return; // always return undefined when calling callback()
};

异步加载程序

async-loader.js

module.exports = function(content) {
    var callback = this.async();
    someAsyncOperation(content, function(err, result) {
        if(err) return callback(err);
        callback(null, result);
    });
};

async-loader-with-multiple-results.js

module.exports = function(content) {
    var callback = this.async();
    someAsyncOperation(content, function(err, result, sourceMaps, ast) {
        if(err) return callback(err);
        callback(null, result, sourceMaps, ast);
    });
};

T> loader 最初被设计为可以在同步 loader pipeline(如 Node.js ,使用 enhanced-require),与异步 pipeline(如 webpack )中运行。然而在 Node.js 这样的单线程环境下进行耗时长的同步计算不是个好主意,我们建议尽可能地使你的 loader 异步化。但如果计算量很小,同步 loader 也是可以的。

“原始”加载程序

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

raw-loader.js

module.exports = function(content) {
    assert(content instanceof Buffer);
    return someSyncOperation(content);
    // return value can be a `Buffer` too
    // This is also allowed if loader is not "raw"
};
module.exports.raw = true;

越过 loader(Pitching loader)

loader 总是__从右到左地被调用。有些情况下,loader 只关心 request 后面的__元数据(metadata),并且忽略前一个 loader 的结果。在实际(从右到左)执行 loader 之前,会先__从左到右__调用 loader 上的 pitch 方法。对于以下 use 配置:

如果加载程序在该pitch方法中传递结果,则该过程将转向并跳过剩余的加载程序,继续调用更多的左加载程序。data可以在音调和正常呼叫之间传递。

module.exports = function(content) {
    return someSyncOperation(content, this.data.value);
};
module.exports.pitch = function(remainingRequest, precedingRequest, data) {
    if(someCondition()) {
        // fast exit
        return "module.exports = require(" + JSON.stringify("-!" + remainingRequest) + ");";
    }
    data.value = 42;
};

加载器上下文

加载器上下文表示分配给该this属性的加载器内可用的属性。

给出以下示例,需要调用:In /abc/file.js

require("./loader1?xyz!loader2!./resource?rrr");

this.version

Loader API版本。目前2。这对提供向后兼容性很有用。使用该版本,您可以指定用于重大更改的自定义逻辑或回退。

this.context

模块的目录。可以用作解决其他问题的上下文。

在这个例子中:/abc因为resource.js在这个目录下

this.request

已解析的请求字符串。

在这个例子中: "/abc/loader1.js?xyz!/abc/node_modules/loader2/index.js!/abc/resource.js?rrr"

this.query

1. 如果这个 loader 配置了 options 对象的话,this.query 就指向这个 option 对象。

2. 如果 loader 中没有 options,而是以 query 字符串作为参数调用时,this.query 就是一个以 ? 开头的字符串。

options 已取代 query,所以此属性废弃。使用 loader-utils 中的 getOptions 方法来提取给定 loader 的 option。

this.callback

可以同步或异步调用以返回多个结果的函数。预期的参数是:

this.callback(
    err: Error | null,
    content: string | Buffer,
    sourceMap?: SourceMap,
    abstractSyntaxTree?: AST
);
  1. 第一个参数必须是Errornull
  1. 第二个参数a string或a Buffer
  1. 可选:第三个参数必须是可由该模块解析的 source map。
  1. 可选:第四个选项,会被 webpack 忽略,可以是任何东西(例如一些元数据)。

如果这个函数被调用,你应该返回undefined以避免不明确的加载结果。

this.async

告诉 loader-runner 这个 loader 将会异步地回调。返回 this.callback

this.data

在 pitch 阶段和正常阶段之间共享的 data 对象。

this.cacheable

一个设置可缓存标志的函数:

cacheable(flag = true: boolean)

默认情况下,loader 的处理结果会被标记为可缓存。调用这个方法然后传入 false,可以关闭 loader 的缓存。

一个可缓存的 loader 在输入和相关依赖没有变化时,必须返回相同的结果。这意味着 loader 除了 this.addDependency 里指定的以外,不应该有其它任何外部依赖。

this.loaders

所有 loader 组成的数组。它在 pitch 阶段的时候是可以写入的。

loaders = [{request: string, path: string, query: string, module: function}]

在这个例子中:

[
  {
    request: "/abc/loader1.js?xyz",
    path: "/abc/loader1.js",
    query: "?xyz",
    module: [Function]
  },
  {
    request: "/abc/node_modules/loader2/index.js",
    path: "/abc/node_modules/loader2/index.js",
    query: "",
    module: [Function]
  }
]

this.loaderIndex

当前加载器的loaders数组中的索引。

在这个例子中:在loader1中0,在loader2中:1

this.resource

request 中的资源部分,包括 query 参数。

在这个例子中: "/abc/resource.js?rrr"

this.resourcePath

资源文件。

在这个例子中: "/abc/resource.js"

this.resourceQuery

资源的 query 参数。

在这个例子中: "?rrr"

this.target

编译的目标。从配置选项中传递过来的。

示例值:"web""node"

this.webpack

这个布尔值在被webpack编译时设置为true。

loader 最初被设计为可以同时当 Babel transform 用。如果你编写了一个 loader 可以同时兼容二者,那么可以使用这个属性了解是否存在可用的 loaderContext 和 webpack 特性。

this.sourceMap

应该生成一个 source map。因为生成 source map 可能会非常耗时,你应该确认 source map 确实有必要请求。

this.emitWarning

emitWarning(message: string)

发出警告。

this.emitError

emitError(message: string)

发出错误。

this.loadModule

loadModule(request: string, callback: function(err, source, sourceMap, module))

解析给定的 request 到一个模块,应用所有配置的 loader ,并且在回调函数中传入生成的 source 、sourceMap 和 模块实例(通常是 NormalModule 的一个实例)。如果你需要获取其他模块的源代码来生成结果的话,你可以使用这个函数。

this.resolve

resolve(context: string, request: string, callback: function(err, result: string))

像 require 表达式一样解析一个 request 。

this.addDependency

addDependency(file: string)
dependency(file: string) // shortcut

加入一个文件作为产生 loader 结果的依赖,使它们的任何变化可以被监听到。例如,html-loader 就使用了这个技巧,当它发现 srcsrc-set 属性时,就会把这些属性上的 url 加入到被解析的 html 文件的依赖中。

this.addContextDependency

addContextDependency(directory: string)

添加一个目录作为加载器结果的依赖关系。

this.clearDependencies

clearDependencies()

删除加载器结果的所有依赖关系。即使是最初的依赖和其他装载机的这些。考虑使用pitch

this.emitFile

emitFile(name: string, content: Buffer|string, sourceMap: {...})

发出一个文件。这是特定于webpack的。

this.fs

访问compilationinputFileSystem财产。

弃用的上下文属性

由于我们正计划将它们从上下文中移除,因此非常不鼓励使用这些属性。他们仍然列在这里作为文件目的。

this.exec

exec(code: string, filename: string)

像模块一样执行一些代码片段。如果需要,请参阅此评论以获取替换方法。

this.resolveSync

resolveSync(context: string, request: string) -> string

解决请求表达式这样的请求。

this.value

将值传递给下一个加载器。如果你知道你的结果导出是否作为模块执行,在这里设置这个值(作为唯一的元素数组)。

this.inputValue

从最后一个加载器传入。如果您要将输入参数作为模块执行,请考虑读取此变量以获取快捷方式(用于性能)。

this.options

传递给编译器的选项。

this.debug

布尔标志。它在调试模式下被设置。

this.minimize

结果应该最小化。

this._compilation

Hacky访问webpack的编译对象。

this._compiler

Hacky访问webpack的编译器对象。

this._module

Hacky访问正在加载的Module对象。

Webpack

webpack 是一个模块打包器。webpack 处理带有依赖关系的模块,生成一系列表示这些模块的静态资源。

主页 https://webpack.js.org/
源码 https://github.com/webpack/webpack
发布版本 3.8.1

Webpack目录

1.指南 | Guides
2.接口 | API
3.概念 | Concepts
4.组态 | Configuration
5.装载 | Loaders