RemoteModule.js 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Tobias Koppers @sokra and Zackary Jackson @ScriptedAlchemy
  4. */
  5. "use strict";
  6. const { RawSource } = require("webpack-sources");
  7. const Module = require("../Module");
  8. const { REMOTE_AND_SHARE_INIT_TYPES } = require("../ModuleSourceTypeConstants");
  9. const { WEBPACK_MODULE_TYPE_REMOTE } = require("../ModuleTypeConstants");
  10. const RuntimeGlobals = require("../RuntimeGlobals");
  11. const makeSerializable = require("../util/makeSerializable");
  12. const FallbackDependency = require("./FallbackDependency");
  13. const RemoteToExternalDependency = require("./RemoteToExternalDependency");
  14. /** @typedef {import("../config/defaults").WebpackOptionsNormalizedWithDefaults} WebpackOptions */
  15. /** @typedef {import("../Compilation")} Compilation */
  16. /** @typedef {import("../Module").BuildCallback} BuildCallback */
  17. /** @typedef {import("../Module").CodeGenerationContext} CodeGenerationContext */
  18. /** @typedef {import("../Module").CodeGenerationResult} CodeGenerationResult */
  19. /** @typedef {import("../Module").LibIdentOptions} LibIdentOptions */
  20. /** @typedef {import("../Module").LibIdent} LibIdent */
  21. /** @typedef {import("../Module").NameForCondition} NameForCondition */
  22. /** @typedef {import("../Module").NeedBuildCallback} NeedBuildCallback */
  23. /** @typedef {import("../Module").NeedBuildContext} NeedBuildContext */
  24. /** @typedef {import("../Module").SourceTypes} SourceTypes */
  25. /** @typedef {import("../RequestShortener")} RequestShortener */
  26. /** @typedef {import("../ResolverFactory").ResolverWithOptions} ResolverWithOptions */
  27. /** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
  28. /** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
  29. /** @typedef {import("../util/fs").InputFileSystem} InputFileSystem */
  30. const RUNTIME_REQUIREMENTS = new Set([RuntimeGlobals.module]);
  31. /** @typedef {string[]} ExternalRequests */
  32. class RemoteModule extends Module {
  33. /**
  34. * @param {string} request request string
  35. * @param {ExternalRequests} externalRequests list of external requests to containers
  36. * @param {string} internalRequest name of exposed module in container
  37. * @param {string} shareScope the used share scope name
  38. */
  39. constructor(request, externalRequests, internalRequest, shareScope) {
  40. super(WEBPACK_MODULE_TYPE_REMOTE);
  41. this.request = request;
  42. this.externalRequests = externalRequests;
  43. this.internalRequest = internalRequest;
  44. this.shareScope = shareScope;
  45. this._identifier = `remote (${shareScope}) ${this.externalRequests.join(
  46. " "
  47. )} ${this.internalRequest}`;
  48. }
  49. /**
  50. * @returns {string} a unique identifier of the module
  51. */
  52. identifier() {
  53. return this._identifier;
  54. }
  55. /**
  56. * @param {RequestShortener} requestShortener the request shortener
  57. * @returns {string} a user readable identifier of the module
  58. */
  59. readableIdentifier(requestShortener) {
  60. return `remote ${this.request}`;
  61. }
  62. /**
  63. * @param {LibIdentOptions} options options
  64. * @returns {LibIdent | null} an identifier for library inclusion
  65. */
  66. libIdent(options) {
  67. return `${this.layer ? `(${this.layer})/` : ""}webpack/container/remote/${
  68. this.request
  69. }`;
  70. }
  71. /**
  72. * @param {NeedBuildContext} context context info
  73. * @param {NeedBuildCallback} callback callback function, returns true, if the module needs a rebuild
  74. * @returns {void}
  75. */
  76. needBuild(context, callback) {
  77. callback(null, !this.buildInfo);
  78. }
  79. /**
  80. * @param {WebpackOptions} options webpack options
  81. * @param {Compilation} compilation the compilation
  82. * @param {ResolverWithOptions} resolver the resolver
  83. * @param {InputFileSystem} fs the file system
  84. * @param {BuildCallback} callback callback function
  85. * @returns {void}
  86. */
  87. build(options, compilation, resolver, fs, callback) {
  88. this.buildMeta = {};
  89. this.buildInfo = {
  90. strict: true
  91. };
  92. this.clearDependenciesAndBlocks();
  93. if (this.externalRequests.length === 1) {
  94. this.addDependency(
  95. new RemoteToExternalDependency(this.externalRequests[0])
  96. );
  97. } else {
  98. this.addDependency(new FallbackDependency(this.externalRequests));
  99. }
  100. callback();
  101. }
  102. /**
  103. * @param {string=} type the source type for which the size should be estimated
  104. * @returns {number} the estimated size of the module (must be non-zero)
  105. */
  106. size(type) {
  107. return 6;
  108. }
  109. /**
  110. * @returns {SourceTypes} types available (do not mutate)
  111. */
  112. getSourceTypes() {
  113. return REMOTE_AND_SHARE_INIT_TYPES;
  114. }
  115. /**
  116. * @returns {NameForCondition | null} absolute path which should be used for condition matching (usually the resource path)
  117. */
  118. nameForCondition() {
  119. return this.request;
  120. }
  121. /**
  122. * @param {CodeGenerationContext} context context for code generation
  123. * @returns {CodeGenerationResult} result
  124. */
  125. codeGeneration({ moduleGraph, chunkGraph }) {
  126. const module = moduleGraph.getModule(this.dependencies[0]);
  127. const id = module && chunkGraph.getModuleId(module);
  128. const sources = new Map();
  129. sources.set("remote", new RawSource(""));
  130. const data = new Map();
  131. data.set("share-init", [
  132. {
  133. shareScope: this.shareScope,
  134. initStage: 20,
  135. init: id === undefined ? "" : `initExternal(${JSON.stringify(id)});`
  136. }
  137. ]);
  138. return { sources, data, runtimeRequirements: RUNTIME_REQUIREMENTS };
  139. }
  140. /**
  141. * @param {ObjectSerializerContext} context context
  142. */
  143. serialize(context) {
  144. const { write } = context;
  145. write(this.request);
  146. write(this.externalRequests);
  147. write(this.internalRequest);
  148. write(this.shareScope);
  149. super.serialize(context);
  150. }
  151. /**
  152. * @param {ObjectDeserializerContext} context context
  153. * @returns {RemoteModule} deserialized module
  154. */
  155. static deserialize(context) {
  156. const { read } = context;
  157. const obj = new RemoteModule(read(), read(), read(), read());
  158. obj.deserialize(context);
  159. return obj;
  160. }
  161. }
  162. makeSerializable(RemoteModule, "webpack/lib/container/RemoteModule");
  163. module.exports = RemoteModule;