插件提供了无限的机会在 webpack 构建系统中执行自定义操作。这允许您创建自定义资产类型,执行独特的构建修改,甚至在使用中间件时增强 webpack 运行时。以下是编写插件时会变得有用的 webpack 的一些功能。
编译完成后,可以遍历编译中的所有结构。
class MyPlugin {
apply(compiler) {
compiler.hooks.emit.tapAsync('MyPlugin', (compilation, callback) => {
// Explore each chunk (build output):
compilation.chunks.forEach((chunk) => {
// Explore each module within the chunk (built inputs):
chunk.getModules().forEach((module) => {
// Explore each source file path that was included into the module:
module.buildInfo &&
module.buildInfo.fileDependencies &&
module.buildInfo.fileDependencies.forEach((filepath) => {
// we've learned a lot about the source structure now...
});
});
// Explore each asset filename generated by the chunk:
chunk.files.forEach((filename) => {
// Get the asset source for each file generated by the chunk:
var source = compilation.assets[filename].source();
});
});
callback();
});
}
}
module.exports = MyPlugin;
compilation.modules
: 编译中的一组模块(构建输入)。每个模块管理从源库构建原始文件。module.fileDependencies
: 包含到模块中的源文件路径数组。这包括源 JavaScript 文件本身(例如:index.js
)以及它所需要的全部依赖项资产文件(样式表、图像等)。查看依赖项有助于了解哪些源文件属于某个模块。compilation.chunks
: 编译中的一组块(构建输出)。每个块管理最终渲染资产的组合。chunk.getModules()
: 包含到块中的模块数组。扩展来说,您可以查看每个模块的依赖项,以了解哪些原始源文件被馈送到块中。chunk.files
: 块生成的输出文件名集。您可以从 compilation.assets
表中访问这些资产源。在运行 webpack 中间件时,每个编译都包含一个 fileDependencies
Set
(正在观察的文件)和一个 fileTimestamps
Map
,它将观察到的文件路径映射到时间戳。这些对于检测编译中哪些文件已更改非常有用。
class MyPlugin {
constructor() {
this.startTime = Date.now();
this.prevTimestamps = new Map();
}
apply(compiler) {
compiler.hooks.emit.tapAsync('MyPlugin', (compilation, callback) => {
const changedFiles = Array.from(compilation.fileTimestamps.keys()).filter(
(watchfile) => {
return (
(this.prevTimestamps.get(watchfile) || this.startTime) <
(compilation.fileTimestamps.get(watchfile) || Infinity)
);
}
);
this.prevTimestamps = compilation.fileTimestamps;
callback();
});
}
}
module.exports = MyPlugin;
您还可以将新的文件路径馈送到观察图,以便在这些文件更改时接收编译触发器。将有效文件路径添加到 compilation.fileDependencies
Set
中,以将其添加到观察到的文件中。
与观察图类似,您可以通过跟踪其哈希值来监控编译中更改的块(或模块)。
class MyPlugin {
constructor() {
this.chunkVersions = {};
}
apply(compiler) {
compiler.hooks.emit.tapAsync('MyPlugin', (compilation, callback) => {
var changedChunks = compilation.chunks.filter((chunk) => {
var oldVersion = this.chunkVersions[chunk.name];
this.chunkVersions[chunk.name] = chunk.hash;
return chunk.hash !== oldVersion;
});
callback();
});
}
}
module.exports = MyPlugin;