ModuleFilenameHelpers.js 5.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Tobias Koppers @sokra
  4. */
  5. "use strict";
  6. const ModuleFilenameHelpers = exports;
  7. ModuleFilenameHelpers.ALL_LOADERS_RESOURCE = "[all-loaders][resource]";
  8. ModuleFilenameHelpers.REGEXP_ALL_LOADERS_RESOURCE = /\[all-?loaders\]\[resource\]/gi;
  9. ModuleFilenameHelpers.LOADERS_RESOURCE = "[loaders][resource]";
  10. ModuleFilenameHelpers.REGEXP_LOADERS_RESOURCE = /\[loaders\]\[resource\]/gi;
  11. ModuleFilenameHelpers.RESOURCE = "[resource]";
  12. ModuleFilenameHelpers.REGEXP_RESOURCE = /\[resource\]/gi;
  13. ModuleFilenameHelpers.ABSOLUTE_RESOURCE_PATH = "[absolute-resource-path]";
  14. ModuleFilenameHelpers.REGEXP_ABSOLUTE_RESOURCE_PATH = /\[abs(olute)?-?resource-?path\]/gi;
  15. ModuleFilenameHelpers.RESOURCE_PATH = "[resource-path]";
  16. ModuleFilenameHelpers.REGEXP_RESOURCE_PATH = /\[resource-?path\]/gi;
  17. ModuleFilenameHelpers.ALL_LOADERS = "[all-loaders]";
  18. ModuleFilenameHelpers.REGEXP_ALL_LOADERS = /\[all-?loaders\]/gi;
  19. ModuleFilenameHelpers.LOADERS = "[loaders]";
  20. ModuleFilenameHelpers.REGEXP_LOADERS = /\[loaders\]/gi;
  21. ModuleFilenameHelpers.QUERY = "[query]";
  22. ModuleFilenameHelpers.REGEXP_QUERY = /\[query\]/gi;
  23. ModuleFilenameHelpers.ID = "[id]";
  24. ModuleFilenameHelpers.REGEXP_ID = /\[id\]/gi;
  25. ModuleFilenameHelpers.HASH = "[hash]";
  26. ModuleFilenameHelpers.REGEXP_HASH = /\[hash\]/gi;
  27. function getAfter(str, token) {
  28. const idx = str.indexOf(token);
  29. return idx < 0 ? "" : str.substr(idx);
  30. }
  31. function getBefore(str, token) {
  32. const idx = str.lastIndexOf(token);
  33. return idx < 0 ? "" : str.substr(0, idx);
  34. }
  35. function getHash(str) {
  36. const hash = require("crypto").createHash("md5");
  37. hash.update(str);
  38. return hash.digest("hex").substr(0, 4);
  39. }
  40. function asRegExp(test) {
  41. if(typeof test === "string") test = new RegExp("^" + test.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"));
  42. return test;
  43. }
  44. ModuleFilenameHelpers.createFilename = function createFilename(module, moduleFilenameTemplate, requestShortener) {
  45. let absoluteResourcePath;
  46. let hash;
  47. let identifier;
  48. let moduleId;
  49. let shortIdentifier;
  50. if(module === undefined) module = "";
  51. if(typeof module === "string") {
  52. shortIdentifier = requestShortener.shorten(module);
  53. identifier = shortIdentifier;
  54. moduleId = "";
  55. absoluteResourcePath = module.split("!").pop();
  56. hash = getHash(identifier);
  57. } else {
  58. shortIdentifier = module.readableIdentifier(requestShortener);
  59. identifier = requestShortener.shorten(module.identifier());
  60. moduleId = module.id;
  61. absoluteResourcePath = module.identifier().split("!").pop();
  62. hash = getHash(identifier);
  63. }
  64. const resource = shortIdentifier.split("!").pop();
  65. const loaders = getBefore(shortIdentifier, "!");
  66. const allLoaders = getBefore(identifier, "!");
  67. const query = getAfter(resource, "?");
  68. const resourcePath = resource.substr(0, resource.length - query.length);
  69. if(typeof moduleFilenameTemplate === "function") {
  70. return moduleFilenameTemplate({
  71. identifier: identifier,
  72. shortIdentifier: shortIdentifier,
  73. resource: resource,
  74. resourcePath: resourcePath,
  75. absoluteResourcePath: absoluteResourcePath,
  76. allLoaders: allLoaders,
  77. query: query,
  78. moduleId: moduleId,
  79. hash: hash
  80. });
  81. }
  82. return moduleFilenameTemplate
  83. .replace(ModuleFilenameHelpers.REGEXP_ALL_LOADERS_RESOURCE, identifier)
  84. .replace(ModuleFilenameHelpers.REGEXP_LOADERS_RESOURCE, shortIdentifier)
  85. .replace(ModuleFilenameHelpers.REGEXP_RESOURCE, resource)
  86. .replace(ModuleFilenameHelpers.REGEXP_RESOURCE_PATH, resourcePath)
  87. .replace(ModuleFilenameHelpers.REGEXP_ABSOLUTE_RESOURCE_PATH, absoluteResourcePath)
  88. .replace(ModuleFilenameHelpers.REGEXP_ALL_LOADERS, allLoaders)
  89. .replace(ModuleFilenameHelpers.REGEXP_LOADERS, loaders)
  90. .replace(ModuleFilenameHelpers.REGEXP_QUERY, query)
  91. .replace(ModuleFilenameHelpers.REGEXP_ID, moduleId)
  92. .replace(ModuleFilenameHelpers.REGEXP_HASH, hash);
  93. };
  94. ModuleFilenameHelpers.createFooter = function createFooter(module, requestShortener) {
  95. if(!module) module = "";
  96. if(typeof module === "string") {
  97. return [
  98. "// WEBPACK FOOTER //",
  99. `// ${requestShortener.shorten(module)}`
  100. ].join("\n");
  101. } else {
  102. return [
  103. "//////////////////",
  104. "// WEBPACK FOOTER",
  105. `// ${module.readableIdentifier(requestShortener)}`,
  106. `// module id = ${module.id}`,
  107. `// module chunks = ${module.mapChunks(c => c.id).join(" ")}`
  108. ].join("\n");
  109. }
  110. };
  111. ModuleFilenameHelpers.replaceDuplicates = function replaceDuplicates(array, fn, comparator) {
  112. const countMap = Object.create(null);
  113. const posMap = Object.create(null);
  114. array.forEach((item, idx) => {
  115. countMap[item] = (countMap[item] || []);
  116. countMap[item].push(idx);
  117. posMap[item] = 0;
  118. });
  119. if(comparator) {
  120. Object.keys(countMap).forEach(item => {
  121. countMap[item].sort(comparator);
  122. });
  123. }
  124. return array.map((item, i) => {
  125. if(countMap[item].length > 1) {
  126. if(comparator && countMap[item][0] === i)
  127. return item;
  128. return fn(item, i, posMap[item]++);
  129. } else return item;
  130. });
  131. };
  132. ModuleFilenameHelpers.matchPart = function matchPart(str, test) {
  133. if(!test) return true;
  134. test = asRegExp(test);
  135. if(Array.isArray(test)) {
  136. return test.map(asRegExp).filter(function(regExp) {
  137. return regExp.test(str);
  138. }).length > 0;
  139. } else {
  140. return test.test(str);
  141. }
  142. };
  143. ModuleFilenameHelpers.matchObject = function matchObject(obj, str) {
  144. if(obj.test)
  145. if(!ModuleFilenameHelpers.matchPart(str, obj.test)) return false;
  146. if(obj.include)
  147. if(!ModuleFilenameHelpers.matchPart(str, obj.include)) return false;
  148. if(obj.exclude)
  149. if(ModuleFilenameHelpers.matchPart(str, obj.exclude)) return false;
  150. return true;
  151. };