AMDDefineDependency.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Tobias Koppers @sokra
  4. */
  5. "use strict";
  6. const RuntimeGlobals = require("../RuntimeGlobals");
  7. const makeSerializable = require("../util/makeSerializable");
  8. const NullDependency = require("./NullDependency");
  9. /** @import { ReplaceSource } from "webpack-sources" */
  10. /** @import LocalModule from "./LocalModule" */
  11. /** @import Dependency from "../Dependency" */
  12. /** @import { DependencyTemplateContext } from "../DependencyTemplate" */
  13. /** @import { Range } from "../javascript/JavascriptParser" */
  14. /** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext<[Range, Range | null, Range | null, Range | null, string | null, LocalModule | null]>} ObjectDeserializerContext */
  15. /** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext<[Range, Range | null, Range | null, Range | null, string | null, LocalModule | null]>} ObjectSerializerContext */
  16. /**
  17. * @typedef {object} Definition
  18. * @property {string} definition variable declarations
  19. * @property {string} content replacement text
  20. * @property {string[]} requests runtime requirements
  21. */
  22. /** @type {Map<string, Record<string, Definition>>} */
  23. const definitionsCache = new Map();
  24. /**
  25. * @param {string} moduleArgument the module argument name
  26. * @param {string} exportsArgument the exports argument name
  27. * @returns {Record<string, Definition>} definitions by branch
  28. */
  29. const getDefinitions = (moduleArgument, exportsArgument) => {
  30. const key = `${moduleArgument} ${exportsArgument}`;
  31. const cached = definitionsCache.get(key);
  32. if (cached !== undefined) return cached;
  33. /** @type {Record<string, Definition>} */
  34. const definitions = {
  35. f: {
  36. definition: "var __WEBPACK_AMD_DEFINE_RESULT__;",
  37. content: `!(__WEBPACK_AMD_DEFINE_RESULT__ = (#).call(${exportsArgument}, ${RuntimeGlobals.require}, ${exportsArgument}, ${moduleArgument}),
  38. __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (${moduleArgument}.exports = __WEBPACK_AMD_DEFINE_RESULT__))`,
  39. requests: [
  40. RuntimeGlobals.require,
  41. RuntimeGlobals.exports,
  42. RuntimeGlobals.module
  43. ]
  44. },
  45. o: {
  46. definition: "",
  47. content: `!(${moduleArgument}.exports = #)`,
  48. requests: [RuntimeGlobals.module]
  49. },
  50. of: {
  51. definition:
  52. "var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;",
  53. content: `!(__WEBPACK_AMD_DEFINE_FACTORY__ = (#),
  54. __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?
  55. (__WEBPACK_AMD_DEFINE_FACTORY__.call(${exportsArgument}, ${RuntimeGlobals.require}, ${exportsArgument}, ${moduleArgument})) :
  56. __WEBPACK_AMD_DEFINE_FACTORY__),
  57. __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (${moduleArgument}.exports = __WEBPACK_AMD_DEFINE_RESULT__))`,
  58. requests: [
  59. RuntimeGlobals.require,
  60. RuntimeGlobals.exports,
  61. RuntimeGlobals.module
  62. ]
  63. },
  64. af: {
  65. definition:
  66. "var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;",
  67. content: `!(__WEBPACK_AMD_DEFINE_ARRAY__ = #, __WEBPACK_AMD_DEFINE_RESULT__ = (#).apply(${exportsArgument}, __WEBPACK_AMD_DEFINE_ARRAY__),
  68. __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (${moduleArgument}.exports = __WEBPACK_AMD_DEFINE_RESULT__))`,
  69. requests: [RuntimeGlobals.exports, RuntimeGlobals.module]
  70. },
  71. ao: {
  72. definition: "",
  73. content: `!(#, ${moduleArgument}.exports = #)`,
  74. requests: [RuntimeGlobals.module]
  75. },
  76. aof: {
  77. definition:
  78. "var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;",
  79. content: `!(__WEBPACK_AMD_DEFINE_ARRAY__ = #, __WEBPACK_AMD_DEFINE_FACTORY__ = (#),
  80. __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?
  81. (__WEBPACK_AMD_DEFINE_FACTORY__.apply(${exportsArgument}, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__),
  82. __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (${moduleArgument}.exports = __WEBPACK_AMD_DEFINE_RESULT__))`,
  83. requests: [RuntimeGlobals.exports, RuntimeGlobals.module]
  84. },
  85. lf: {
  86. definition: "var XXX, XXXmodule;",
  87. content: `!(XXXmodule = { id: YYY, exports: {}, loaded: false }, XXX = (#).call(XXXmodule.exports, ${RuntimeGlobals.require}, XXXmodule.exports, XXXmodule), XXXmodule.loaded = true, XXX === undefined && (XXX = XXXmodule.exports))`,
  88. requests: [RuntimeGlobals.require, RuntimeGlobals.module]
  89. },
  90. lo: {
  91. definition: "var XXX;",
  92. content: "!(XXX = #)",
  93. requests: []
  94. },
  95. lof: {
  96. definition: "var XXX, XXXfactory, XXXmodule;",
  97. content: `!(XXXfactory = (#), (typeof XXXfactory === 'function' ? ((XXXmodule = { id: YYY, exports: {}, loaded: false }), (XXX = XXXfactory.call(XXXmodule.exports, ${RuntimeGlobals.require}, XXXmodule.exports, XXXmodule)), (XXXmodule.loaded = true), XXX === undefined && (XXX = XXXmodule.exports)) : XXX = XXXfactory))`,
  98. requests: [RuntimeGlobals.require, RuntimeGlobals.module]
  99. },
  100. laf: {
  101. definition: "var __WEBPACK_AMD_DEFINE_ARRAY__, XXX, XXXexports;",
  102. content:
  103. "!(__WEBPACK_AMD_DEFINE_ARRAY__ = #, XXX = (#).apply(XXXexports = {}, __WEBPACK_AMD_DEFINE_ARRAY__), XXX === undefined && (XXX = XXXexports))",
  104. requests: []
  105. },
  106. lao: {
  107. definition: "var XXX;",
  108. content: "!(#, XXX = #)",
  109. requests: []
  110. },
  111. laof: {
  112. definition: "var XXXarray, XXXfactory, XXXexports, XXX;",
  113. content: `!(XXXarray = #, XXXfactory = (#),
  114. (typeof XXXfactory === 'function' ?
  115. ((XXX = XXXfactory.apply(XXXexports = {}, XXXarray)), XXX === undefined && (XXX = XXXexports)) :
  116. (XXX = XXXfactory)
  117. ))`,
  118. requests: []
  119. }
  120. };
  121. definitionsCache.set(key, definitions);
  122. return definitions;
  123. };
  124. class AMDDefineDependency extends NullDependency {
  125. /**
  126. * Creates an instance of AMDDefineDependency.
  127. * @param {Range} range range
  128. * @param {Range | null} arrayRange array range
  129. * @param {Range | null} functionRange function range
  130. * @param {Range | null} objectRange object range
  131. * @param {string | null} namedModule true, when define is called with a name
  132. */
  133. constructor(range, arrayRange, functionRange, objectRange, namedModule) {
  134. super();
  135. this.range = range;
  136. this.arrayRange = arrayRange;
  137. this.functionRange = functionRange;
  138. this.objectRange = objectRange;
  139. /** @type {string | null} */
  140. this.namedModule = namedModule;
  141. /** @type {LocalModule | null} */
  142. this.localModule = null;
  143. }
  144. get type() {
  145. return "amd define";
  146. }
  147. /**
  148. * Serializes this instance into the provided serializer context.
  149. * @param {ObjectSerializerContext} context context
  150. */
  151. serialize(context) {
  152. context
  153. .write(this.range)
  154. .write(this.arrayRange)
  155. .write(this.functionRange)
  156. .write(this.objectRange)
  157. .write(this.namedModule)
  158. .write(this.localModule);
  159. super.serialize(context);
  160. }
  161. /**
  162. * Restores this instance from the provided deserializer context.
  163. * @param {ObjectDeserializerContext} context context
  164. */
  165. deserialize(context) {
  166. this.range = context.read();
  167. const c1 = context.rest;
  168. this.arrayRange = c1.read();
  169. const c2 = c1.rest;
  170. this.functionRange = c2.read();
  171. const c3 = c2.rest;
  172. this.objectRange = c3.read();
  173. const c4 = c3.rest;
  174. this.namedModule = c4.read();
  175. const c5 = c4.rest;
  176. this.localModule = c5.read();
  177. super.deserialize(c5.rest);
  178. }
  179. }
  180. makeSerializable(
  181. AMDDefineDependency,
  182. "webpack/lib/dependencies/AMDDefineDependency"
  183. );
  184. AMDDefineDependency.Template = class AMDDefineDependencyTemplate extends (
  185. NullDependency.Template
  186. ) {
  187. /**
  188. * Applies the plugin by registering its hooks on the compiler.
  189. * @param {Dependency} dependency the dependency for which the template should be applied
  190. * @param {ReplaceSource} source the current replace source which can be modified
  191. * @param {DependencyTemplateContext} templateContext the context object
  192. * @returns {void}
  193. */
  194. apply(dependency, source, { module, runtimeRequirements }) {
  195. const dep = /** @type {AMDDefineDependency} */ (dependency);
  196. const branch = this.branch(dep);
  197. const { definition, content, requests } = getDefinitions(
  198. module.moduleArgument,
  199. module.exportsArgument
  200. )[branch];
  201. for (const req of requests) {
  202. runtimeRequirements.add(req);
  203. }
  204. this.replace(dep, source, definition, content);
  205. }
  206. /**
  207. * Returns variable name.
  208. * @param {AMDDefineDependency} dependency dependency
  209. * @returns {string | false | null} variable name
  210. */
  211. localModuleVar(dependency) {
  212. return (
  213. dependency.localModule &&
  214. dependency.localModule.used &&
  215. dependency.localModule.variableName()
  216. );
  217. }
  218. /**
  219. * Returns branch.
  220. * @param {AMDDefineDependency} dependency dependency
  221. * @returns {string} branch
  222. */
  223. branch(dependency) {
  224. const localModuleVar = this.localModuleVar(dependency) ? "l" : "";
  225. const arrayRange = dependency.arrayRange ? "a" : "";
  226. const objectRange = dependency.objectRange ? "o" : "";
  227. const functionRange = dependency.functionRange ? "f" : "";
  228. return localModuleVar + arrayRange + objectRange + functionRange;
  229. }
  230. /**
  231. * Processes the provided dependency.
  232. * @param {AMDDefineDependency} dependency dependency
  233. * @param {ReplaceSource} source source
  234. * @param {string} definition definition
  235. * @param {string} text text
  236. */
  237. replace(dependency, source, definition, text) {
  238. const localModuleVar = this.localModuleVar(dependency);
  239. if (localModuleVar) {
  240. text = text.replace(/XXX/g, localModuleVar.replace(/\$/g, "$$$$"));
  241. definition = definition.replace(
  242. /XXX/g,
  243. localModuleVar.replace(/\$/g, "$$$$")
  244. );
  245. }
  246. if (dependency.namedModule) {
  247. text = text.replace(/YYY/g, JSON.stringify(dependency.namedModule));
  248. }
  249. const texts = text.split("#");
  250. if (definition) source.insert(0, definition);
  251. let current = dependency.range[0];
  252. if (dependency.arrayRange) {
  253. source.replace(
  254. current,
  255. dependency.arrayRange[0] - 1,
  256. /** @type {string} */ (texts.shift())
  257. );
  258. current = dependency.arrayRange[1];
  259. }
  260. if (dependency.objectRange) {
  261. source.replace(
  262. current,
  263. dependency.objectRange[0] - 1,
  264. /** @type {string} */ (texts.shift())
  265. );
  266. current = dependency.objectRange[1];
  267. } else if (dependency.functionRange) {
  268. source.replace(
  269. current,
  270. dependency.functionRange[0] - 1,
  271. /** @type {string} */ (texts.shift())
  272. );
  273. current = dependency.functionRange[1];
  274. }
  275. source.replace(
  276. current,
  277. dependency.range[1] - 1,
  278. /** @type {string} */ (texts.shift())
  279. );
  280. if (texts.length > 0) throw new Error("Implementation error");
  281. }
  282. };
  283. module.exports = AMDDefineDependency;