HashedModuleIdsPlugin.js 2.5 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 {
  7. compareModulesByPreOrderIndexOrIdentifier
  8. } = require("../util/comparators");
  9. const createSchemaValidation = require("../util/create-schema-validation");
  10. const createHash = require("../util/createHash");
  11. const {
  12. getUsedModuleIdsAndModules,
  13. getFullModuleName
  14. } = require("./IdHelpers");
  15. /** @typedef {import("../../declarations/plugins/HashedModuleIdsPlugin").HashedModuleIdsPluginOptions} HashedModuleIdsPluginOptions */
  16. /** @typedef {import("../Compiler")} Compiler */
  17. const validate = createSchemaValidation(
  18. require("../../schemas/plugins/HashedModuleIdsPlugin.check.js"),
  19. () => require("../../schemas/plugins/HashedModuleIdsPlugin.json"),
  20. {
  21. name: "Hashed Module Ids Plugin",
  22. baseDataPath: "options"
  23. }
  24. );
  25. class HashedModuleIdsPlugin {
  26. /**
  27. * @param {HashedModuleIdsPluginOptions=} options options object
  28. */
  29. constructor(options = {}) {
  30. validate(options);
  31. /** @type {HashedModuleIdsPluginOptions} */
  32. this.options = {
  33. context: undefined,
  34. hashFunction: "md4",
  35. hashDigest: "base64",
  36. hashDigestLength: 4,
  37. ...options
  38. };
  39. }
  40. /**
  41. * Apply the plugin
  42. * @param {Compiler} compiler the compiler instance
  43. * @returns {void}
  44. */
  45. apply(compiler) {
  46. const options = this.options;
  47. compiler.hooks.compilation.tap("HashedModuleIdsPlugin", compilation => {
  48. compilation.hooks.moduleIds.tap("HashedModuleIdsPlugin", () => {
  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. /** @type {NonNullable<HashedModuleIdsPluginOptions["hashFunction"]>} */ (
  61. options.hashFunction
  62. )
  63. );
  64. hash.update(ident || "");
  65. const hashId = /** @type {string} */ (
  66. hash.digest(options.hashDigest)
  67. );
  68. let len = options.hashDigestLength;
  69. while (usedIds.has(hashId.slice(0, len)))
  70. /** @type {number} */ (len)++;
  71. const moduleId = hashId.slice(0, len);
  72. chunkGraph.setModuleId(module, moduleId);
  73. usedIds.add(moduleId);
  74. }
  75. });
  76. });
  77. }
  78. }
  79. module.exports = HashedModuleIdsPlugin;