DelegatedModuleFactoryPlugin.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Tobias Koppers @sokra
  4. */
  5. "use strict";
  6. const DelegatedModule = require("./DelegatedModule");
  7. /** @typedef {import("../declarations/plugins/DllReferencePlugin").DllReferencePluginOptions} DllReferencePluginOptions */
  8. /** @typedef {import("../declarations/plugins/DllReferencePlugin").DllReferencePluginOptionsContent} DllReferencePluginOptionsContent */
  9. /** @typedef {import("./DelegatedModule").Data} Data */
  10. /** @typedef {import("./DelegatedModule").SourceRequest} SourceRequest */
  11. /** @typedef {import("./DelegatedModule").Type} Type */
  12. /** @typedef {import("./NormalModuleFactory")} NormalModuleFactory */
  13. /**
  14. * @typedef {object} Options
  15. * @property {SourceRequest} source source
  16. * @property {NonNullable<DllReferencePluginOptions["context"]>} context absolute context path to which lib ident is relative to
  17. * @property {DllReferencePluginOptionsContent} content content
  18. * @property {DllReferencePluginOptions["type"]} type type
  19. * @property {DllReferencePluginOptions["extensions"]} extensions extensions
  20. * @property {DllReferencePluginOptions["scope"]} scope scope
  21. * @property {object=} associatedObjectForCache object for caching
  22. */
  23. class DelegatedModuleFactoryPlugin {
  24. /**
  25. * @param {Options} options options
  26. */
  27. constructor(options) {
  28. this.options = options;
  29. options.type = options.type || "require";
  30. options.extensions = options.extensions || ["", ".js", ".json", ".wasm"];
  31. }
  32. /**
  33. * @param {NormalModuleFactory} normalModuleFactory the normal module factory
  34. * @returns {void}
  35. */
  36. apply(normalModuleFactory) {
  37. const scope = this.options.scope;
  38. if (scope) {
  39. normalModuleFactory.hooks.factorize.tapAsync(
  40. "DelegatedModuleFactoryPlugin",
  41. (data, callback) => {
  42. const [dependency] = data.dependencies;
  43. const { request } = dependency;
  44. if (request && request.startsWith(`${scope}/`)) {
  45. const innerRequest = `.${request.slice(scope.length)}`;
  46. let resolved;
  47. if (innerRequest in this.options.content) {
  48. resolved = this.options.content[innerRequest];
  49. return callback(
  50. null,
  51. new DelegatedModule(
  52. this.options.source,
  53. resolved,
  54. /** @type {Type} */ (this.options.type),
  55. innerRequest,
  56. request
  57. )
  58. );
  59. }
  60. const extensions =
  61. /** @type {string[]} */
  62. (this.options.extensions);
  63. for (let i = 0; i < extensions.length; i++) {
  64. const extension = extensions[i];
  65. const requestPlusExt = innerRequest + extension;
  66. if (requestPlusExt in this.options.content) {
  67. resolved = this.options.content[requestPlusExt];
  68. return callback(
  69. null,
  70. new DelegatedModule(
  71. this.options.source,
  72. resolved,
  73. /** @type {Type} */ (this.options.type),
  74. requestPlusExt,
  75. request + extension
  76. )
  77. );
  78. }
  79. }
  80. }
  81. return callback();
  82. }
  83. );
  84. } else {
  85. normalModuleFactory.hooks.module.tap(
  86. "DelegatedModuleFactoryPlugin",
  87. module => {
  88. const request = module.libIdent(this.options);
  89. if (request && request in this.options.content) {
  90. const resolved = this.options.content[request];
  91. return new DelegatedModule(
  92. this.options.source,
  93. resolved,
  94. /** @type {Type} */ (this.options.type),
  95. request,
  96. module
  97. );
  98. }
  99. return module;
  100. }
  101. );
  102. }
  103. }
  104. }
  105. module.exports = DelegatedModuleFactoryPlugin;