HashedModuleIdsPlugin.js 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  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. const validate = createSchemaValidation(
  17. require("../../schemas/plugins/HashedModuleIdsPlugin.check.js"),
  18. () => require("../../schemas/plugins/HashedModuleIdsPlugin.json"),
  19. {
  20. name: "Hashed Module Ids Plugin",
  21. baseDataPath: "options"
  22. }
  23. );
  24. class HashedModuleIdsPlugin {
  25. /**
  26. * @param {HashedModuleIdsPluginOptions=} options options object
  27. */
  28. constructor(options = {}) {
  29. validate(options);
  30. /** @type {HashedModuleIdsPluginOptions} */
  31. this.options = {
  32. context: null,
  33. hashFunction: "md4",
  34. hashDigest: "base64",
  35. hashDigestLength: 4,
  36. ...options
  37. };
  38. }
  39. apply(compiler) {
  40. const options = this.options;
  41. compiler.hooks.compilation.tap("HashedModuleIdsPlugin", compilation => {
  42. compilation.hooks.moduleIds.tap("HashedModuleIdsPlugin", () => {
  43. const chunkGraph = compilation.chunkGraph;
  44. const context = this.options.context
  45. ? this.options.context
  46. : compiler.context;
  47. const [usedIds, modules] = getUsedModuleIdsAndModules(compilation);
  48. const modulesInNaturalOrder = modules.sort(
  49. compareModulesByPreOrderIndexOrIdentifier(compilation.moduleGraph)
  50. );
  51. for (const module of modulesInNaturalOrder) {
  52. const ident = getFullModuleName(module, context, compiler.root);
  53. const hash = createHash(options.hashFunction);
  54. hash.update(ident || "");
  55. const hashId = /** @type {string} */ (
  56. hash.digest(options.hashDigest)
  57. );
  58. let len = options.hashDigestLength;
  59. while (usedIds.has(hashId.slice(0, len))) len++;
  60. const moduleId = hashId.slice(0, len);
  61. chunkGraph.setModuleId(module, moduleId);
  62. usedIds.add(moduleId);
  63. }
  64. });
  65. });
  66. }
  67. }
  68. module.exports = HashedModuleIdsPlugin;