You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

236 lines
8.8 KiB

4 years ago
  1. 'use strict';
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.uniteEntries = exports.uniteRules = undefined;
  6. var _unionWith2 = require('lodash/unionWith');
  7. var _unionWith3 = _interopRequireDefault(_unionWith2);
  8. var _differenceWith2 = require('lodash/differenceWith');
  9. var _differenceWith3 = _interopRequireDefault(_differenceWith2);
  10. var _mergeWith2 = require('lodash/mergeWith');
  11. var _mergeWith3 = _interopRequireDefault(_mergeWith2);
  12. var _isEqual2 = require('lodash/isEqual');
  13. var _isEqual3 = _interopRequireDefault(_isEqual2);
  14. var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
  15. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  16. function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
  17. var isArray = Array.isArray;
  18. function uniteRules(rules, key, newRule, rule) {
  19. if (String(rule.test) !== String(newRule.test) || (newRule.enforce || rule.enforce) && rule.enforce !== newRule.enforce || newRule.include && !isSameValue(rule.include, newRule.include) || newRule.exclude && !isSameValue(rule.exclude, newRule.exclude)) {
  20. return false;
  21. } else if (!rule.test && !rule.include && !rule.exclude && (rule.loader && rule.loader.split('?')[0]) !== (newRule.loader && newRule.loader.split('?')[0])) {
  22. // Don't merge the rule if there isn't any identifying fields and the loaders don't match
  23. return false;
  24. } else if ((rule.include || rule.exclude) && !newRule.include && !newRule.exclude) {
  25. // Don't merge child without include/exclude to parent that has either
  26. return false;
  27. }
  28. // apply the same logic for oneOf
  29. if (rule.oneOf && newRule.oneOf) {
  30. rule.oneOf = (0, _unionWith3.default)(rule.oneOf, newRule.oneOf, uniteRules.bind(null, {}, 'oneOf'));
  31. return true;
  32. }
  33. // newRule.loader should always override use, loaders and oneOf
  34. if (newRule.loader) {
  35. var optionsKey = newRule.options ? 'options' : newRule.query && 'query';
  36. delete rule.use;
  37. delete rule.loaders;
  38. delete rule.oneOf;
  39. rule.loader = newRule.loader;
  40. if (optionsKey) {
  41. rule[optionsKey] = newRule[optionsKey];
  42. }
  43. } else if (newRule.oneOf) {
  44. delete rule.use;
  45. delete rule.loaders;
  46. delete rule.loader;
  47. rule.oneOf = newRule.oneOf;
  48. } else if ((rule.use || rule.loaders || rule.loader) && (newRule.use || newRule.loaders)) {
  49. var expandEntry = function expandEntry(loader) {
  50. return typeof loader === 'string' ? { loader: loader } : loader;
  51. };
  52. // this is only here to avoid breaking existing tests
  53. var unwrapEntry = function unwrapEntry(entry) {
  54. return !entry.options && !entry.query ? entry.loader : entry;
  55. };
  56. var entries = void 0;
  57. if (rule.loader) {
  58. var _optionsKey = rule.options ? 'options' : rule.query && 'query';
  59. entries = [{ loader: rule.loader }];
  60. if (_optionsKey) {
  61. entries[0][_optionsKey] = rule[_optionsKey];
  62. }
  63. delete rule.loader;
  64. if (_optionsKey) {
  65. delete rule[_optionsKey];
  66. }
  67. } else {
  68. entries = [].concat(rule.use || rule.loaders).map(expandEntry);
  69. }
  70. var newEntries = [].concat(newRule.use || newRule.loaders).map(expandEntry);
  71. var loadersKey = rule.use || newRule.use ? 'use' : 'loaders';
  72. var resolvedKey = key + '.' + loadersKey;
  73. switch (rules[resolvedKey]) {
  74. case 'prepend':
  75. rule[loadersKey] = [].concat(_toConsumableArray((0, _differenceWith3.default)(newEntries, entries, uniteEntries)), _toConsumableArray(entries)).map(unwrapEntry);
  76. break;
  77. case 'replace':
  78. rule[loadersKey] = newRule.use || newRule.loaders;
  79. break;
  80. default:
  81. rule[loadersKey] = combineEntries(newEntries, entries).map(unwrapEntry);
  82. }
  83. }
  84. if (newRule.include) {
  85. rule.include = newRule.include;
  86. }
  87. if (newRule.exclude) {
  88. rule.exclude = newRule.exclude;
  89. }
  90. return true;
  91. }
  92. /**
  93. * Check equality of two values using lodash's isEqual
  94. * Arrays need to be sorted for equality checking
  95. * but clone them first so as not to disrupt the sort order in tests
  96. */
  97. function isSameValue(a, b) {
  98. var _map = [a, b].map(function (value) {
  99. return isArray(value) ? [].concat(_toConsumableArray(value)).sort() : value;
  100. }),
  101. _map2 = _slicedToArray(_map, 2),
  102. propA = _map2[0],
  103. propB = _map2[1];
  104. return (0, _isEqual3.default)(propA, propB);
  105. }
  106. function areEqualEntries(newEntry, entry) {
  107. var loaderNameRe = /^([^?]+)/ig;
  108. var _entry$loader$match = entry.loader.match(loaderNameRe),
  109. _entry$loader$match2 = _slicedToArray(_entry$loader$match, 1),
  110. loaderName = _entry$loader$match2[0];
  111. var _newEntry$loader$matc = newEntry.loader.match(loaderNameRe),
  112. _newEntry$loader$matc2 = _slicedToArray(_newEntry$loader$matc, 1),
  113. newLoaderName = _newEntry$loader$matc2[0];
  114. return loaderName === newLoaderName;
  115. }
  116. function uniteEntries(newEntry, entry) {
  117. if (areEqualEntries(newEntry, entry)) {
  118. // Replace query values with newer ones
  119. (0, _mergeWith3.default)(entry, newEntry);
  120. return true;
  121. }
  122. return false;
  123. }
  124. /* Combines entries and newEntries, while respecting the order of loaders in each.
  125. Iterates through new entries. If the new entry also exists in existing entries,
  126. we'll put in all of the loaders from existing entries that come before it (in case
  127. those are pre-requisites). Any remaining existing entries are added at the end.
  128. Since webpack processes right-to-left, we're working backwards through the arrays
  129. */
  130. function combineEntries(newEntries, existingEntries) {
  131. var resultSet = [];
  132. // We're iterating through newEntries, this keeps track of where we are in the existingEntries
  133. var existingEntriesIteratorIndex = existingEntries.length - 1;
  134. for (var i = newEntries.length - 1; i >= 0; i -= 1) {
  135. var currentEntry = newEntries[i];
  136. var indexInExistingEntries = findLastIndexUsingComparinator(existingEntries, currentEntry, areEqualEntries, existingEntriesIteratorIndex);
  137. var hasEquivalentEntryInExistingEntries = indexInExistingEntries !== -1;
  138. if (hasEquivalentEntryInExistingEntries) {
  139. // If the same entry exists in existing entries, we should add all of the entries that
  140. // come before to maintain order
  141. for (var j = existingEntriesIteratorIndex; j > indexInExistingEntries; j -= 1) {
  142. var existingEntry = existingEntries[j];
  143. // If this entry also exists in new entries, we'll add as part of iterating through
  144. // new entries so that if there's a conflict between existing entries and new entries,
  145. // new entries order wins
  146. var hasMatchingEntryInNewEntries = findLastIndexUsingComparinator(newEntries, existingEntry, areEqualEntries, i) !== -1;
  147. if (!hasMatchingEntryInNewEntries) {
  148. resultSet.unshift(existingEntry);
  149. }
  150. existingEntriesIteratorIndex -= 1;
  151. }
  152. uniteEntries(currentEntry, existingEntries[existingEntriesIteratorIndex]);
  153. // uniteEntries mutates the second parameter to be a merged version, so that's what's pushed
  154. resultSet.unshift(existingEntries[existingEntriesIteratorIndex]);
  155. existingEntriesIteratorIndex -= 1;
  156. } else {
  157. var alreadyHasMatchingEntryInResultSet = findLastIndexUsingComparinator(resultSet, currentEntry, areEqualEntries) !== -1;
  158. if (!alreadyHasMatchingEntryInResultSet) {
  159. resultSet.unshift(currentEntry);
  160. }
  161. }
  162. }
  163. // Add remaining existing entries
  164. for (existingEntriesIteratorIndex; existingEntriesIteratorIndex >= 0; existingEntriesIteratorIndex -= 1) {
  165. var _existingEntry = existingEntries[existingEntriesIteratorIndex];
  166. var _alreadyHasMatchingEntryInResultSet = findLastIndexUsingComparinator(resultSet, _existingEntry, areEqualEntries) !== -1;
  167. if (!_alreadyHasMatchingEntryInResultSet) {
  168. resultSet.unshift(_existingEntry);
  169. }
  170. }
  171. return resultSet;
  172. }
  173. function findLastIndexUsingComparinator(entries, entryToFind, comparinator, startingIndex) {
  174. startingIndex = startingIndex || entries.length - 1;
  175. for (var i = startingIndex; i >= 0; i -= 1) {
  176. if (areEqualEntries(entryToFind, entries[i])) {
  177. return i;
  178. }
  179. }
  180. return -1;
  181. }
  182. exports.uniteRules = uniteRules;
  183. exports.uniteEntries = uniteEntries;