DelegatedModuleFactoryPlugin.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  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").DelegatedModuleData} DelegatedModuleData */
  10. /** @typedef {import("./DelegatedModule").DelegatedModuleSourceRequest} DelegatedModuleSourceRequest */
  11. /** @typedef {import("./DelegatedModule").DelegatedModuleType} DelegatedModuleType */
  12. /** @typedef {import("./NormalModuleFactory")} NormalModuleFactory */
  13. /** @typedef {import("./util/identifier").AssociatedObjectForCache} AssociatedObjectForCache */
  14. /**
  15. * Defines the options type used by this module.
  16. * @typedef {object} Options
  17. * @property {DelegatedModuleSourceRequest} source source
  18. * @property {NonNullable<DllReferencePluginOptions["context"]>} context absolute context path to which lib ident is relative to
  19. * @property {DllReferencePluginOptionsContent} content content
  20. * @property {DllReferencePluginOptions["type"]} type type
  21. * @property {DllReferencePluginOptions["extensions"]} extensions extensions
  22. * @property {DllReferencePluginOptions["scope"]} scope scope
  23. * @property {AssociatedObjectForCache=} associatedObjectForCache object for caching
  24. */
  25. const PLUGIN_NAME = "DelegatedModuleFactoryPlugin";
  26. class DelegatedModuleFactoryPlugin {
  27. /**
  28. * Creates an instance of DelegatedModuleFactoryPlugin.
  29. * @param {Options} options options
  30. */
  31. constructor(options) {
  32. this.options = options;
  33. options.type = options.type || "require";
  34. options.extensions = options.extensions || ["", ".js", ".json", ".wasm"];
  35. }
  36. /**
  37. * Applies the plugin by registering its hooks on the compiler.
  38. * @param {NormalModuleFactory} normalModuleFactory the normal module factory
  39. * @returns {void}
  40. */
  41. apply(normalModuleFactory) {
  42. const scope = this.options.scope;
  43. if (scope) {
  44. normalModuleFactory.hooks.factorize.tapAsync(
  45. PLUGIN_NAME,
  46. (data, callback) => {
  47. const [dependency] = data.dependencies;
  48. const { request } = dependency;
  49. if (request && request.startsWith(`${scope}/`)) {
  50. const innerRequest = `.${request.slice(scope.length)}`;
  51. /** @type {undefined | DelegatedModuleData} */
  52. let resolved;
  53. if (innerRequest in this.options.content) {
  54. resolved = this.options.content[innerRequest];
  55. return callback(
  56. null,
  57. new DelegatedModule(
  58. this.options.source,
  59. resolved,
  60. /** @type {DelegatedModuleType} */
  61. (this.options.type),
  62. innerRequest,
  63. request
  64. )
  65. );
  66. }
  67. const extensions =
  68. /** @type {string[]} */
  69. (this.options.extensions);
  70. for (let i = 0; i < extensions.length; i++) {
  71. const extension = extensions[i];
  72. const requestPlusExt = innerRequest + extension;
  73. if (requestPlusExt in this.options.content) {
  74. resolved = this.options.content[requestPlusExt];
  75. return callback(
  76. null,
  77. new DelegatedModule(
  78. this.options.source,
  79. resolved,
  80. /** @type {DelegatedModuleType} */
  81. (this.options.type),
  82. requestPlusExt,
  83. request + extension
  84. )
  85. );
  86. }
  87. }
  88. }
  89. return callback();
  90. }
  91. );
  92. } else {
  93. normalModuleFactory.hooks.module.tap(PLUGIN_NAME, (module) => {
  94. const request = module.libIdent(this.options);
  95. if (request && request in this.options.content) {
  96. const resolved = this.options.content[request];
  97. return new DelegatedModule(
  98. this.options.source,
  99. resolved,
  100. /** @type {DelegatedModuleType} */
  101. (this.options.type),
  102. request,
  103. module
  104. );
  105. }
  106. return module;
  107. });
  108. }
  109. }
  110. }
  111. module.exports = DelegatedModuleFactoryPlugin;