HashedModuleIdsPlugin.js 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  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. /**
  16. * @import {
  17. * HashedModuleIdsPluginOptions
  18. * } from "../../declarations/plugins/ids/HashedModuleIdsPlugin"
  19. */
  20. /** @import Compiler from "../Compiler" */
  21. const PLUGIN_NAME = "HashedModuleIdsPlugin";
  22. class HashedModuleIdsPlugin {
  23. /**
  24. * Creates an instance of HashedModuleIdsPlugin.
  25. * @param {HashedModuleIdsPluginOptions=} options options object
  26. */
  27. constructor(options = {}) {
  28. /** @type {HashedModuleIdsPluginOptions} */
  29. this.options = options;
  30. }
  31. /**
  32. * Applies the plugin by registering its hooks on the compiler.
  33. * @param {Compiler} compiler the compiler instance
  34. * @returns {void}
  35. */
  36. apply(compiler) {
  37. compiler.hooks.validate.tap(PLUGIN_NAME, () => {
  38. compiler.validate(
  39. () => require("../../schemas/plugins/ids/HashedModuleIdsPlugin.json"),
  40. this.options,
  41. {
  42. name: "Hashed Module Ids Plugin",
  43. baseDataPath: "options"
  44. },
  45. (options) =>
  46. require("../../schemas/plugins/ids/HashedModuleIdsPlugin.check")(
  47. options
  48. )
  49. );
  50. });
  51. compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
  52. compilation.hooks.moduleIds.tap(PLUGIN_NAME, () => {
  53. const chunkGraph = compilation.chunkGraph;
  54. const context = this.options.context
  55. ? this.options.context
  56. : compiler.context;
  57. const [usedIds, modules] = getUsedModuleIdsAndModules(compilation);
  58. const modulesInNaturalOrder = modules.sort(
  59. compareModulesByPreOrderIndexOrIdentifier(compilation.moduleGraph)
  60. );
  61. for (const module of modulesInNaturalOrder) {
  62. const ident = getFullModuleName(module, context, compiler.root);
  63. const hash = createHash(
  64. this.options.hashFunction || DEFAULTS.HASH_FUNCTION
  65. );
  66. hash.update(ident || "");
  67. const hashId = hash.digest(this.options.hashDigest || "base64");
  68. let len = this.options.hashDigestLength || 4;
  69. while (usedIds.has(hashId.slice(0, len))) {
  70. /** @type {number} */ (len)++;
  71. }
  72. const moduleId = hashId.slice(0, len);
  73. chunkGraph.setModuleId(module, moduleId);
  74. usedIds.add(moduleId);
  75. }
  76. });
  77. });
  78. }
  79. }
  80. module.exports = HashedModuleIdsPlugin;