在文件夹中新建一个js文件:
class FileListPlugin {
static defaultOptions = {
outputFile: "assets.md",
};
// 需要传入自定义插件构造函数的任意选项
//(这是自定义插件的公开API)
constructor(options = {}) {
// 在应用默认选项前,先应用用户指定选项
// 合并后的选项暴露给插件方法
// 记得在这里校验所有选项
this.options = { ...FileListPlugin.defaultOptions, ...options };
}
apply(compiler) {
const pluginName = FileListPlugin.name;
console.log(pluginName, "pluginname");
// webpack 模块实例,可以通过 compiler 对象访问,
// 这样确保使用的是模块的正确版本
// (不要直接 require/import webpack)
const { webpack } = compiler;
// console.log(webpack, "webpack");
// console.log(compiler, "compiler");
// Compilation 对象提供了对一些有用常量的访问。
const { Compilation } = webpack;
// console.log(webpack.sources, "webpack.sources");
// RawSource 是其中一种 “源码”("sources") 类型,
// 用来在 compilation 中表示资源的源码
const { RawSource } = webpack.sources;
// 绑定到 “thisCompilation” 钩子,
// 以便进一步绑定到 compilation 过程更早期的阶段
compiler.hooks.thisCompilation.tap(pluginName, (compilation) => {
// 绑定到资源处理流水线(assets processing pipeline)
compilation.hooks.processAssets.tap(
{
name: pluginName,
// 用某个靠后的资源处理阶段,
// 确保所有资源已被插件添加到 compilation
stage: Compilation.PROCESS_ASSETS_STAGE_SUMMARIZE,
},
(assets) => {
// "assets" 是一个包含 compilation 中所有资源(assets)的对象。
// 该对象的键是资源的路径,
// 值是文件的源码
// 遍历所有资源,
// 生成 Markdown 文件的内容
// console.log(assets, "assets");
const content =
"# In this build:\n\n" +
Object.keys(assets)
.map((filename) => `- ${filename}`)
.join("\n");
// 向 compilation 添加新的资源,
// 这样 webpack 就会自动生成并输出到 output 目录
compilation.emitAsset(
this.options.outputFile,
new RawSource(content)
);
}
);
});
}
}
module.exports = { FileListPlugin };
使用:
const { FileListPlugin } = require("./src/MyPlugins/file-list-plugin");
plugins: [
// 添加插件,使用默认选项
new FileListPlugin(),
]
插件的核心
本质是一个js的类 那么类可以有的属性 方法 等 都可以用在编写插件中; 必须要有的是apply(compiler),在webpack源码中会使用该方法并传入compiler对象; 附上源码:
const createCompiler = rawOptions => {
const options = getNormalizedWebpackOptions(rawOptions);
applyWebpackOptionsBaseDefaults(options);
const compiler = new Compiler(
/** @type {string} */ (options.context),
options
);
new NodeEnvironmentPlugin({
infrastructureLogging: options.infrastructureLogging
}).apply(compiler);
if (Array.isArray(options.plugins)) {
for (const plugin of options.plugins) {
if (typeof plugin === "function") {
plugin.call(compiler, compiler);
} else if (plugin) {
plugin.apply(compiler);//此处调用了apply 传入了compiler
}
}
}
applyWebpackOptionsDefaults(options);
compiler.hooks.environment.call();
compiler.hooks.afterEnvironment.call();
new WebpackOptionsApply().process(options, compiler);
compiler.hooks.initialize.call();
return compiler;
};