揭秘webpack插件工作流程和原理( 六 )

监听文件变化Webpack 会从配置的入口模块出发,依次找出所有的依赖模块,当入口模块或者其依赖的模块发生变化时,就会触发一次新的 Compilation 。
在开发插件时经常需要知道是哪个文件发生变化导致了新的 Compilation,为此可以使用如下代码:
// 当依赖的文件发生变化时会触发 watch-run 事件compiler.hooks.watchRun.tap('MyPlugin', (watching, callback) => {  // 获取发生变化的文件列表  const changedFiles = watching.compiler.watchFileSystem.watcher.mtimes;  // changedFiles 格式为键值对,键为发生变化的文件路径 。  if (changedFiles[filePath] !== undefined) {    // filePath 对应的文件发生了变化  }  callback();});默认情况下 Webpack 只会监视入口和其依赖的模块是否发生变化,在有些情况下项目可能需要引入新的文件,例如引入一个 HTML 文件 。由于 JAVAScript 文件不会去导入 HTML 文件,Webpack 就不会监听 HTML 文件的变化,编辑 HTML 文件时就不会重新触发新的 Compilation 。为了监听 HTML 文件的变化,我们需要把 HTML 文件加入到依赖列表中,为此可以使用如下代码:
compiler.hooks.afterCompile.tap('MyPlugin', (compilation, callback) => {  // 把 HTML 文件添加到文件依赖列表,好让 Webpack 去监听 HTML 模块文件,在 HTML 模版文件发生变化时重新启动一次编译  compilation.fileDependencies.push(filePath);  callback();});3、修改输出资源有些场景下插件需要修改、增加、删除输出的资源,要做到这点需要监听emit 事件,因为发生 emit 事件时所有模块的转换和代码块对应的文件已经生成好,需要输出的资源即将输出,因此emit事件是修改 Webpack 输出资源的最后时机 。
所有需要输出的资源会存放在 compilation.assets中,compilation.assets 是一个键值对,键为需要输出的文件名称,值为文件对应的内容 。
设置 compilation.assets 的代码如下:
// 设置名称为 fileName 的输出资源  compilation.assets[fileName] = {    // 返回文件内容    source: () => {      // fileContent 既可以是代表文本文件的字符串,也可以是代表二进制文件的 Buffer      return fileContent;      },    // 返回文件大小      size: () => {      return Buffer.byteLength(fileContent, 'utf8');    }  };  callback();判断webpack使用了哪些插件// 判断当前配置使用使用了 ExtractTextPlugin,// compiler 参数即为 Webpack 在 apply(compiler) 中传入的参数function hasExtractTextPlugin(compiler) {  // 当前配置所有使用的插件列表  const plugins = compiler.options.plugins;  // 去 plugins 中寻找有没有 ExtractTextPlugin 的实例  return plugins.find(plugin=>plugin.__proto__.constructor === ExtractTextPlugin) != null;}以上4种方法来源于文章: [Webpack学习-Plugin] :http://wushaobin.top/2019/03/15/webpackPlugin/
管理 Warnings 和 Errors做一个实验,如果你在 apply函数内插入 throw new Error("Message"),会发生什么,终端会打印出 Unhandled rejection Error: Message 。然后 webpack 中断执行 。为了不影响 webpack 的执行,要在编译期间向用户发出警告或错误消息,则应使用 compilation.warnings 和 compilation.errors 。
compilation.warnings.push("warning");compilation.errors.push("error");文章中的案例demo代码展示https://github.com/6fedcom/fe-blog/tree/master/webpack/plugin
webpack打包过程或者插件代码里该如何调试?

  1. 在当前webpack项目工程文件夹下面,执行命令行:
node --inspect-brk ./node_modules/webpack/bin/webpack.js --inline --progress其中参数--inspect-brk就是以调试模式启动node:
终端会输出:
Debugger listening on ws://127.0.0.1:9229/1018c03f-7473-4d60-b62c-949a6404c81dFor help, see: https://nodejs.org/en/docs/inspector
  1. 谷歌浏览器输入 chrome://inspect/#devices

揭秘webpack插件工作流程和原理


推荐阅读