WatchIgnorePlugin.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Tobias Koppers @sokra
  4. */
  5. "use strict";
  6. const { groupBy } = require("./util/ArrayHelpers");
  7. const createSchemaValidation = require("./util/create-schema-validation");
  8. /** @typedef {import("../declarations/plugins/WatchIgnorePlugin").WatchIgnorePluginOptions} WatchIgnorePluginOptions */
  9. /** @typedef {import("./Compiler")} Compiler */
  10. /** @typedef {import("./util/fs").WatchFileSystem} WatchFileSystem */
  11. const validate = createSchemaValidation(
  12. require("../schemas/plugins/WatchIgnorePlugin.check.js"),
  13. () => require("../schemas/plugins/WatchIgnorePlugin.json"),
  14. {
  15. name: "Watch Ignore Plugin",
  16. baseDataPath: "options"
  17. }
  18. );
  19. const IGNORE_TIME_ENTRY = "ignore";
  20. class IgnoringWatchFileSystem {
  21. /**
  22. * @param {WatchFileSystem} wfs original file system
  23. * @param {(string|RegExp)[]} paths ignored paths
  24. */
  25. constructor(wfs, paths) {
  26. this.wfs = wfs;
  27. this.paths = paths;
  28. }
  29. watch(files, dirs, missing, startTime, options, callback, callbackUndelayed) {
  30. files = Array.from(files);
  31. dirs = Array.from(dirs);
  32. /**
  33. * @param {string} path path to check
  34. * @returns {boolean} true, if path is ignored
  35. */
  36. const ignored = path =>
  37. this.paths.some(p =>
  38. p instanceof RegExp ? p.test(path) : path.indexOf(p) === 0
  39. );
  40. const [ignoredFiles, notIgnoredFiles] = groupBy(files, ignored);
  41. const [ignoredDirs, notIgnoredDirs] = groupBy(dirs, ignored);
  42. const watcher = this.wfs.watch(
  43. notIgnoredFiles,
  44. notIgnoredDirs,
  45. missing,
  46. startTime,
  47. options,
  48. (err, fileTimestamps, dirTimestamps, changedFiles, removedFiles) => {
  49. if (err) return callback(err);
  50. for (const path of ignoredFiles) {
  51. fileTimestamps.set(path, IGNORE_TIME_ENTRY);
  52. }
  53. for (const path of ignoredDirs) {
  54. dirTimestamps.set(path, IGNORE_TIME_ENTRY);
  55. }
  56. callback(
  57. err,
  58. fileTimestamps,
  59. dirTimestamps,
  60. changedFiles,
  61. removedFiles
  62. );
  63. },
  64. callbackUndelayed
  65. );
  66. return {
  67. close: () => watcher.close(),
  68. pause: () => watcher.pause(),
  69. getContextTimeInfoEntries: () => {
  70. const dirTimestamps = watcher.getContextTimeInfoEntries();
  71. for (const path of ignoredDirs) {
  72. dirTimestamps.set(path, IGNORE_TIME_ENTRY);
  73. }
  74. return dirTimestamps;
  75. },
  76. getFileTimeInfoEntries: () => {
  77. const fileTimestamps = watcher.getFileTimeInfoEntries();
  78. for (const path of ignoredFiles) {
  79. fileTimestamps.set(path, IGNORE_TIME_ENTRY);
  80. }
  81. return fileTimestamps;
  82. },
  83. getInfo:
  84. watcher.getInfo &&
  85. (() => {
  86. const info = watcher.getInfo();
  87. const { fileTimeInfoEntries, contextTimeInfoEntries } = info;
  88. for (const path of ignoredFiles) {
  89. fileTimeInfoEntries.set(path, IGNORE_TIME_ENTRY);
  90. }
  91. for (const path of ignoredDirs) {
  92. contextTimeInfoEntries.set(path, IGNORE_TIME_ENTRY);
  93. }
  94. return info;
  95. })
  96. };
  97. }
  98. }
  99. class WatchIgnorePlugin {
  100. /**
  101. * @param {WatchIgnorePluginOptions} options options
  102. */
  103. constructor(options) {
  104. validate(options);
  105. this.paths = options.paths;
  106. }
  107. /**
  108. * Apply the plugin
  109. * @param {Compiler} compiler the compiler instance
  110. * @returns {void}
  111. */
  112. apply(compiler) {
  113. compiler.hooks.afterEnvironment.tap("WatchIgnorePlugin", () => {
  114. compiler.watchFileSystem = new IgnoringWatchFileSystem(
  115. compiler.watchFileSystem,
  116. this.paths
  117. );
  118. });
  119. }
  120. }
  121. module.exports = WatchIgnorePlugin;