内部机制
Webpack 自定义加载器与插件
Webpack 核心的两个模块即是 Loaders 与 Plugins,Loaders 负责载入各种各样的资源、样式与脚本文件,而 Plugins 负责对载入的文件进行处理并且最终输出到编译后的文件中。加载器可以串联。可以通过管道来处理资源,最后一个加载器需要输出为 JavaScript,中间别的加载器可以输出任意的格式到下一个加载器。
Plugin | 插件
/**
* webpack插件开发采用'动态原型模式'
* 插件开发,最重要的两个对象:compiler、compilation
* @param options
* @constructor
*/
function MyPlugin(options) {
// 根据 options 配置你的插件
}
// 我们可以在原型上添加一些方法
MyPlugin.prototype.someFunc = function () {
/*something*/
};
// apply方法是必须要有的,因为当我们使用一个插件时(new somePlugins({})),webpack会去寻找插件的apply方法并执行
MyPlugin.prototype.apply = function (compiler) {
// compiler是什么?compiler是webpack的'编译器'引用
// compiler.plugin('***')和compilation.plugin('***')代表什么?
// document.addEventListener熟悉吧?其实是类似的
// compiler.plugin('***')就相当于给compiler设置了事件监听
// 所以compiler.plugin('compile')就代表:当编译器监听到compile事件时,我们应该做些什么
// compile('编译器'对'开始编译'这个事件的监听)
compiler.plugin("compile", function (params) {
console.log("The compiler is starting to compile...");
});
// compilation('编译器'对'编译ing'这个事件的监听)
compiler.plugin("compilation", function (compilation) {
console.log("The compiler is starting a new compilation...");
// 在compilation事件监听中,我们可以访问compilation引用,它是一个代表编译过程的对象引用
// 我们一定要区分compiler和compilation,一个代表编译器实体,另一个代表编译过程
// optimize('编译过程'对'优化文件'这个事件的监听)
compilation.plugin("optimize", function () {
console.log("The compilation is starting to optimize files...");
});
});
// emit('编译器'对'生成最终资源'这个事件的监听)
compiler.plugin("emit", function (compilation, callback) {
console.log("The compilation is going to emit files...");
// compilation.chunks是块的集合(构建后将要输出的文件,即编译之后得到的结果)
compilation.chunks.forEach(function (chunk) {
// chunk.modules是模块的集合(构建时webpack梳理出的依赖,即import、require的module)
// 形象一点说:chunk.modules是原材料,下面的chunk.files才是最终的成品
chunk.modules.forEach(function (module) {
// module.fileDependencies就是具体的文件,最真实的资源【举例,在css中@import("reset.css"),这里的reset.css就是fileDependencie】
module.fileDependencies.forEach(function (filepath) {
// 到这一步,就可以操作源文件了
});
});
// 最终生成的文件的集合
chunk.files.forEach(function (filename) {
// source()可以得到每个文件的源码
var source = compilation.assets[filename].source();
});
});
// callback在最后必须调用
callback();
});
};
// 以上compiler和compilation的事件监听只是一小部分,详细API可见该链接http://www.css88.com/doc/webpack2/api/plugins/
module.exports = MyPlugin;