HashedModuleIdsPlugin.js 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Tobias Koppers @sokra
  4. */
  5. "use strict";
  6. const { DEFAULTS } = require("../config/defaults");
  7. const {
  8. compareModulesByPreOrderIndexOrIdentifier
  9. } = require("../util/comparators");
  10. const createHash = require("../util/createHash");
  11. const {
  12. getFullModuleName,
  13. getUsedModuleIdsAndModules
  14. } = require("./IdHelpers");
  15. /** @typedef {import("../../declarations/plugins/ids/HashedModuleIdsPlugin").HashedModuleIdsPluginOptions} HashedModuleIdsPluginOptions */
  16. /** @typedef {import("../Compiler")} Compiler */
  17. const PLUGIN_NAME = "HashedModuleIdsPlugin";
  18. class HashedModuleIdsPlugin {
  19. /**
  20. * Creates an instance of HashedModuleIdsPlugin.
  21. * @param {HashedModuleIdsPluginOptions=} options options object
  22. */
  23. constructor(options = {}) {
  24. /** @type {HashedModuleIdsPluginOptions} */
  25. this.options = options;
  26. }
  27. /**
  28. * Applies the plugin by registering its hooks on the compiler.
  29. * @param {Compiler} compiler the compiler instance
  30. * @returns {void}
  31. */
  32. apply(compiler) {
  33. compiler.hooks.validate.tap(PLUGIN_NAME, () => {
  34. compiler.validate(
  35. () => require("../../schemas/plugins/ids/HashedModuleIdsPlugin.json"),
  36. this.options,
  37. {
  38. name: "Hashed Module Ids Plugin",
  39. baseDataPath: "options"
  40. },
  41. (options) =>
  42. require("../../schemas/plugins/ids/HashedModuleIdsPlugin.check")(
  43. options
  44. )
  45. );
  46. });
  47. compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
  48. compilation.hooks.moduleIds.tap(PLUGIN_NAME, () => {
  49. const chunkGraph = compilation.chunkGraph;
  50. const context = this.options.context
  51. ? this.options.context
  52. : compiler.context;
  53. const [usedIds, modules] = getUsedModuleIdsAndModules(compilation);
  54. const modulesInNaturalOrder = modules.sort(
  55. compareModulesByPreOrderIndexOrIdentifier(compilation.moduleGraph)
  56. );
  57. for (const module of modulesInNaturalOrder) {
  58. const ident = getFullModuleName(module, context, compiler.root);
  59. const hash = createHash(
  60. this.options.hashFunction || DEFAULTS.HASH_FUNCTION
  61. );
  62. hash.update(ident || "");
  63. const hashId = hash.digest(this.options.hashDigest || "base64");
  64. let len = this.options.hashDigestLength || 4;
  65. while (usedIds.has(hashId.slice(0, len))) {
  66. /** @type {number} */ (len)++;
  67. }
  68. const moduleId = hashId.slice(0, len);
  69. chunkGraph.setModuleId(module, moduleId);
  70. usedIds.add(moduleId);
  71. }
  72. });
  73. });
  74. }
  75. }
  76. module.exports = HashedModuleIdsPlugin;