webpack原理:
- Entry:入口,Webpack 执行构建的第一步将从 Entry 开始,可抽象成输入。
- Module:模块,在 Webpack 里一切皆模块,一个模块对应着一个文件。Webpack 会从配置的 Entry 开始递归找出所有依赖的模块。
- Chunk:代码块,一个 Chunk 由多个模块组合而成,用于代码合并与分割。
- Loader:模块转换器,用于把模块原内容按照需求转换成新内容。
- Plugin:扩展插件,在 Webpack 构建流程中的特定时机注入扩展逻辑来改变构建结果或做你想要的事情。
- Output:输出结果,在 Webpack 经过一系列处理并得出最终想要的代码后输出结果。
正常使用 webpack 插件所需要编写的代码,分成两步:
- 通过一个命令例如
npm install --save-dev build-time-analysis-webpack-plugin
将插件加入依赖; - 在
webpack.config.js
文件头部引入插件,在配置plugins
字段中添加一个插件实例;
webpack 插件的构成:
- 一个 JavaScript 函数或 JavaScript 类,用于承接这个插件模块的所有逻辑;
- 在它原型上定义的
apply
方法,会在安装插件时被调用,并被 webpack compiler 调用一次; - 指定一个触及到 webpack 本身的事件钩子,即下文会提及的 hooks,用于特定时机处理额外的逻辑;
- 对 webpack 实例内部做一些操作处理;
- 在功能流程完成后可以调用 webpack 提供的回调函数;
示例:
const pluginName = "ModuleWebpackPlugin"; class ModuleWebpackPlugin{ constructor(options = {}) { this.options = options; // console.log('Plugin options', this.options); } apply(compiler) { compiler.hooks.done.tap(pluginName, compilation => { console.log('It is done!'); }); } } module.exports = ModuleWebpackPlugin;
compiler 这个对象包含了 webpack 环境所有的的配置信息,包含 options,loaders,plugins 这些信息,这个对象在 webpack 启动时候被实例化,它是全局唯一的,可以简单地把它理解为 webpack 实例。
为了在指定生命周期做自定义的一些逻辑处理,我们需要在 compiler 暴露的钩子上指明我们的 tap 配置,一般这由一个字符串命名和一个回调函数组成。一般来说,compile 过程中会触发如下几个钩子:
https://webpack.js.org/api/compiler-hooks/
- beforeRun
- run
- beforeCompile
- compile
- make
- seal
假设我们想在 compiler.run() 之前处理逻辑,那么就要调用 beforeRun 钩子来处理:
compiler.hooks.beforeRun.tap( 'testPlugin', (comp) => { // ... } );
compilation 对象包含了当前的模块资源、编译生成资源、变化的文件等。当 webpack 以开发模式运行时,每当检测到一个文件变化,一次新的 compilation 将被创建。compilation 对象也提供了很多事件回调供插件做扩展。通过 compilation 也能读取到 compiler 对象。两者的区别在于,前者代表了整个 webpack 从启动到关闭的生命周期,而 compilation 只代表一次单独的编译。
compilation 也对应有不同的钩子: https://webpack.js.org/api/compilation-hooks/
参考链接:https://zhuanlan.zhihu.com/p/94577244