AMDPlugin.js 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Tobias Koppers @sokra
  4. */
  5. "use strict";
  6. const {
  7. JAVASCRIPT_MODULE_TYPE_AUTO,
  8. JAVASCRIPT_MODULE_TYPE_DYNAMIC
  9. } = require("../ModuleTypeConstants");
  10. const RuntimeGlobals = require("../RuntimeGlobals");
  11. const {
  12. approve,
  13. evaluateToIdentifier,
  14. evaluateToString,
  15. toConstantDependency
  16. } = require("../javascript/JavascriptParserHelpers");
  17. const AMDDefineDependency = require("./AMDDefineDependency");
  18. const AMDDefineDependencyParserPlugin = require("./AMDDefineDependencyParserPlugin");
  19. const AMDRequireArrayDependency = require("./AMDRequireArrayDependency");
  20. const AMDRequireContextDependency = require("./AMDRequireContextDependency");
  21. const AMDRequireDependenciesBlockParserPlugin = require("./AMDRequireDependenciesBlockParserPlugin");
  22. const AMDRequireDependency = require("./AMDRequireDependency");
  23. const AMDRequireItemDependency = require("./AMDRequireItemDependency");
  24. const {
  25. AMDDefineRuntimeModule,
  26. AMDOptionsRuntimeModule
  27. } = require("./AMDRuntimeModules");
  28. const ConstDependency = require("./ConstDependency");
  29. const LocalModuleDependency = require("./LocalModuleDependency");
  30. const UnsupportedDependency = require("./UnsupportedDependency");
  31. /** @typedef {import("../../declarations/WebpackOptions").ModuleOptionsNormalized} ModuleOptions */
  32. /** @typedef {import("../Compiler")} Compiler */
  33. const PLUGIN_NAME = "AMDPlugin";
  34. class AMDPlugin {
  35. /**
  36. * @param {Record<string, any>} amdOptions the AMD options
  37. */
  38. constructor(amdOptions) {
  39. this.amdOptions = amdOptions;
  40. }
  41. /**
  42. * Apply the plugin
  43. * @param {Compiler} compiler the compiler instance
  44. * @returns {void}
  45. */
  46. apply(compiler) {
  47. const amdOptions = this.amdOptions;
  48. compiler.hooks.compilation.tap(
  49. PLUGIN_NAME,
  50. (compilation, { contextModuleFactory, normalModuleFactory }) => {
  51. compilation.dependencyTemplates.set(
  52. AMDRequireDependency,
  53. new AMDRequireDependency.Template()
  54. );
  55. compilation.dependencyFactories.set(
  56. AMDRequireItemDependency,
  57. normalModuleFactory
  58. );
  59. compilation.dependencyTemplates.set(
  60. AMDRequireItemDependency,
  61. new AMDRequireItemDependency.Template()
  62. );
  63. compilation.dependencyTemplates.set(
  64. AMDRequireArrayDependency,
  65. new AMDRequireArrayDependency.Template()
  66. );
  67. compilation.dependencyFactories.set(
  68. AMDRequireContextDependency,
  69. contextModuleFactory
  70. );
  71. compilation.dependencyTemplates.set(
  72. AMDRequireContextDependency,
  73. new AMDRequireContextDependency.Template()
  74. );
  75. compilation.dependencyTemplates.set(
  76. AMDDefineDependency,
  77. new AMDDefineDependency.Template()
  78. );
  79. compilation.dependencyTemplates.set(
  80. UnsupportedDependency,
  81. new UnsupportedDependency.Template()
  82. );
  83. compilation.dependencyTemplates.set(
  84. LocalModuleDependency,
  85. new LocalModuleDependency.Template()
  86. );
  87. compilation.hooks.runtimeRequirementInModule
  88. .for(RuntimeGlobals.amdDefine)
  89. .tap(PLUGIN_NAME, (module, set) => {
  90. set.add(RuntimeGlobals.require);
  91. });
  92. compilation.hooks.runtimeRequirementInModule
  93. .for(RuntimeGlobals.amdOptions)
  94. .tap(PLUGIN_NAME, (module, set) => {
  95. set.add(RuntimeGlobals.requireScope);
  96. });
  97. compilation.hooks.runtimeRequirementInTree
  98. .for(RuntimeGlobals.amdDefine)
  99. .tap(PLUGIN_NAME, (chunk, set) => {
  100. compilation.addRuntimeModule(chunk, new AMDDefineRuntimeModule());
  101. });
  102. compilation.hooks.runtimeRequirementInTree
  103. .for(RuntimeGlobals.amdOptions)
  104. .tap(PLUGIN_NAME, (chunk, set) => {
  105. compilation.addRuntimeModule(
  106. chunk,
  107. new AMDOptionsRuntimeModule(amdOptions)
  108. );
  109. });
  110. const handler = (parser, parserOptions) => {
  111. if (parserOptions.amd !== undefined && !parserOptions.amd) return;
  112. const tapOptionsHooks = (optionExpr, rootName, getMembers) => {
  113. parser.hooks.expression
  114. .for(optionExpr)
  115. .tap(
  116. PLUGIN_NAME,
  117. toConstantDependency(parser, RuntimeGlobals.amdOptions, [
  118. RuntimeGlobals.amdOptions
  119. ])
  120. );
  121. parser.hooks.evaluateIdentifier
  122. .for(optionExpr)
  123. .tap(
  124. PLUGIN_NAME,
  125. evaluateToIdentifier(optionExpr, rootName, getMembers, true)
  126. );
  127. parser.hooks.evaluateTypeof
  128. .for(optionExpr)
  129. .tap(PLUGIN_NAME, evaluateToString("object"));
  130. parser.hooks.typeof
  131. .for(optionExpr)
  132. .tap(
  133. PLUGIN_NAME,
  134. toConstantDependency(parser, JSON.stringify("object"))
  135. );
  136. };
  137. new AMDRequireDependenciesBlockParserPlugin(parserOptions).apply(
  138. parser
  139. );
  140. new AMDDefineDependencyParserPlugin(parserOptions).apply(parser);
  141. tapOptionsHooks("define.amd", "define", () => "amd");
  142. tapOptionsHooks("require.amd", "require", () => ["amd"]);
  143. tapOptionsHooks(
  144. "__webpack_amd_options__",
  145. "__webpack_amd_options__",
  146. () => []
  147. );
  148. parser.hooks.expression.for("define").tap(PLUGIN_NAME, expr => {
  149. const dep = new ConstDependency(
  150. RuntimeGlobals.amdDefine,
  151. expr.range,
  152. [RuntimeGlobals.amdDefine]
  153. );
  154. dep.loc = expr.loc;
  155. parser.state.module.addPresentationalDependency(dep);
  156. return true;
  157. });
  158. parser.hooks.typeof
  159. .for("define")
  160. .tap(
  161. PLUGIN_NAME,
  162. toConstantDependency(parser, JSON.stringify("function"))
  163. );
  164. parser.hooks.evaluateTypeof
  165. .for("define")
  166. .tap(PLUGIN_NAME, evaluateToString("function"));
  167. parser.hooks.canRename.for("define").tap(PLUGIN_NAME, approve);
  168. parser.hooks.rename.for("define").tap(PLUGIN_NAME, expr => {
  169. const dep = new ConstDependency(
  170. RuntimeGlobals.amdDefine,
  171. expr.range,
  172. [RuntimeGlobals.amdDefine]
  173. );
  174. dep.loc = expr.loc;
  175. parser.state.module.addPresentationalDependency(dep);
  176. return false;
  177. });
  178. parser.hooks.typeof
  179. .for("require")
  180. .tap(
  181. PLUGIN_NAME,
  182. toConstantDependency(parser, JSON.stringify("function"))
  183. );
  184. parser.hooks.evaluateTypeof
  185. .for("require")
  186. .tap(PLUGIN_NAME, evaluateToString("function"));
  187. };
  188. normalModuleFactory.hooks.parser
  189. .for(JAVASCRIPT_MODULE_TYPE_AUTO)
  190. .tap(PLUGIN_NAME, handler);
  191. normalModuleFactory.hooks.parser
  192. .for(JAVASCRIPT_MODULE_TYPE_DYNAMIC)
  193. .tap(PLUGIN_NAME, handler);
  194. }
  195. );
  196. }
  197. }
  198. module.exports = AMDPlugin;