CommonJsPlugin.js 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  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 RuntimeModule = require("../RuntimeModule");
  8. const SelfModuleFactory = require("../SelfModuleFactory");
  9. const Template = require("../Template");
  10. const CommonJsExportsDependency = require("./CommonJsExportsDependency");
  11. const CommonJsFullRequireDependency = require("./CommonJsFullRequireDependency");
  12. const CommonJsRequireContextDependency = require("./CommonJsRequireContextDependency");
  13. const CommonJsRequireDependency = require("./CommonJsRequireDependency");
  14. const CommonJsSelfReferenceDependency = require("./CommonJsSelfReferenceDependency");
  15. const ModuleDecoratorDependency = require("./ModuleDecoratorDependency");
  16. const RequireHeaderDependency = require("./RequireHeaderDependency");
  17. const RequireResolveContextDependency = require("./RequireResolveContextDependency");
  18. const RequireResolveDependency = require("./RequireResolveDependency");
  19. const RequireResolveHeaderDependency = require("./RequireResolveHeaderDependency");
  20. const RuntimeRequirementsDependency = require("./RuntimeRequirementsDependency");
  21. const CommonJsExportsParserPlugin = require("./CommonJsExportsParserPlugin");
  22. const CommonJsImportsParserPlugin = require("./CommonJsImportsParserPlugin");
  23. const {
  24. evaluateToIdentifier,
  25. toConstantDependency
  26. } = require("../javascript/JavascriptParserHelpers");
  27. const CommonJsExportRequireDependency = require("./CommonJsExportRequireDependency");
  28. class CommonJsPlugin {
  29. apply(compiler) {
  30. compiler.hooks.compilation.tap(
  31. "CommonJsPlugin",
  32. (compilation, { contextModuleFactory, normalModuleFactory }) => {
  33. compilation.dependencyFactories.set(
  34. CommonJsRequireDependency,
  35. normalModuleFactory
  36. );
  37. compilation.dependencyTemplates.set(
  38. CommonJsRequireDependency,
  39. new CommonJsRequireDependency.Template()
  40. );
  41. compilation.dependencyFactories.set(
  42. CommonJsFullRequireDependency,
  43. normalModuleFactory
  44. );
  45. compilation.dependencyTemplates.set(
  46. CommonJsFullRequireDependency,
  47. new CommonJsFullRequireDependency.Template()
  48. );
  49. compilation.dependencyFactories.set(
  50. CommonJsRequireContextDependency,
  51. contextModuleFactory
  52. );
  53. compilation.dependencyTemplates.set(
  54. CommonJsRequireContextDependency,
  55. new CommonJsRequireContextDependency.Template()
  56. );
  57. compilation.dependencyFactories.set(
  58. RequireResolveDependency,
  59. normalModuleFactory
  60. );
  61. compilation.dependencyTemplates.set(
  62. RequireResolveDependency,
  63. new RequireResolveDependency.Template()
  64. );
  65. compilation.dependencyFactories.set(
  66. RequireResolveContextDependency,
  67. contextModuleFactory
  68. );
  69. compilation.dependencyTemplates.set(
  70. RequireResolveContextDependency,
  71. new RequireResolveContextDependency.Template()
  72. );
  73. compilation.dependencyTemplates.set(
  74. RequireResolveHeaderDependency,
  75. new RequireResolveHeaderDependency.Template()
  76. );
  77. compilation.dependencyTemplates.set(
  78. RequireHeaderDependency,
  79. new RequireHeaderDependency.Template()
  80. );
  81. compilation.dependencyTemplates.set(
  82. CommonJsExportsDependency,
  83. new CommonJsExportsDependency.Template()
  84. );
  85. compilation.dependencyFactories.set(
  86. CommonJsExportRequireDependency,
  87. normalModuleFactory
  88. );
  89. compilation.dependencyTemplates.set(
  90. CommonJsExportRequireDependency,
  91. new CommonJsExportRequireDependency.Template()
  92. );
  93. const selfFactory = new SelfModuleFactory(compilation.moduleGraph);
  94. compilation.dependencyFactories.set(
  95. CommonJsSelfReferenceDependency,
  96. selfFactory
  97. );
  98. compilation.dependencyTemplates.set(
  99. CommonJsSelfReferenceDependency,
  100. new CommonJsSelfReferenceDependency.Template()
  101. );
  102. compilation.dependencyFactories.set(
  103. ModuleDecoratorDependency,
  104. selfFactory
  105. );
  106. compilation.dependencyTemplates.set(
  107. ModuleDecoratorDependency,
  108. new ModuleDecoratorDependency.Template()
  109. );
  110. compilation.hooks.runtimeRequirementInModule
  111. .for(RuntimeGlobals.harmonyModuleDecorator)
  112. .tap("CommonJsPlugin", (module, set) => {
  113. set.add(RuntimeGlobals.module);
  114. set.add(RuntimeGlobals.requireScope);
  115. });
  116. compilation.hooks.runtimeRequirementInModule
  117. .for(RuntimeGlobals.nodeModuleDecorator)
  118. .tap("CommonJsPlugin", (module, set) => {
  119. set.add(RuntimeGlobals.module);
  120. set.add(RuntimeGlobals.requireScope);
  121. });
  122. compilation.hooks.runtimeRequirementInTree
  123. .for(RuntimeGlobals.harmonyModuleDecorator)
  124. .tap("CommonJsPlugin", (chunk, set) => {
  125. compilation.addRuntimeModule(
  126. chunk,
  127. new HarmonyModuleDecoratorRuntimeModule()
  128. );
  129. });
  130. compilation.hooks.runtimeRequirementInTree
  131. .for(RuntimeGlobals.nodeModuleDecorator)
  132. .tap("CommonJsPlugin", (chunk, set) => {
  133. compilation.addRuntimeModule(
  134. chunk,
  135. new NodeModuleDecoratorRuntimeModule()
  136. );
  137. });
  138. const handler = (parser, parserOptions) => {
  139. if (parserOptions.commonjs !== undefined && !parserOptions.commonjs)
  140. return;
  141. parser.hooks.typeof
  142. .for("module")
  143. .tap(
  144. "CommonJsPlugin",
  145. toConstantDependency(parser, JSON.stringify("object"))
  146. );
  147. parser.hooks.expression
  148. .for("require.main")
  149. .tap(
  150. "CommonJsPlugin",
  151. toConstantDependency(
  152. parser,
  153. `${RuntimeGlobals.moduleCache}[${RuntimeGlobals.entryModuleId}]`,
  154. [RuntimeGlobals.moduleCache, RuntimeGlobals.entryModuleId]
  155. )
  156. );
  157. parser.hooks.expression
  158. .for("module.loaded")
  159. .tap("CommonJsPlugin", expr => {
  160. parser.state.module.buildInfo.moduleConcatenationBailout =
  161. "module.loaded";
  162. const dep = new RuntimeRequirementsDependency([
  163. RuntimeGlobals.moduleLoaded
  164. ]);
  165. dep.loc = expr.loc;
  166. parser.state.module.addPresentationalDependency(dep);
  167. return true;
  168. });
  169. parser.hooks.expression
  170. .for("module.id")
  171. .tap("CommonJsPlugin", expr => {
  172. parser.state.module.buildInfo.moduleConcatenationBailout =
  173. "module.id";
  174. const dep = new RuntimeRequirementsDependency([
  175. RuntimeGlobals.moduleId
  176. ]);
  177. dep.loc = expr.loc;
  178. parser.state.module.addPresentationalDependency(dep);
  179. return true;
  180. });
  181. parser.hooks.evaluateIdentifier.for("module.hot").tap(
  182. "CommonJsPlugin",
  183. evaluateToIdentifier("module.hot", "module", () => ["hot"], null)
  184. );
  185. new CommonJsImportsParserPlugin(parserOptions).apply(parser);
  186. new CommonJsExportsParserPlugin(compilation.moduleGraph).apply(
  187. parser
  188. );
  189. };
  190. normalModuleFactory.hooks.parser
  191. .for("javascript/auto")
  192. .tap("CommonJsPlugin", handler);
  193. normalModuleFactory.hooks.parser
  194. .for("javascript/dynamic")
  195. .tap("CommonJsPlugin", handler);
  196. }
  197. );
  198. }
  199. }
  200. class HarmonyModuleDecoratorRuntimeModule extends RuntimeModule {
  201. constructor() {
  202. super("harmony module decorator");
  203. }
  204. /**
  205. * @returns {string} runtime code
  206. */
  207. generate() {
  208. const { runtimeTemplate } = this.compilation;
  209. return Template.asString([
  210. `${
  211. RuntimeGlobals.harmonyModuleDecorator
  212. } = ${runtimeTemplate.basicFunction("module", [
  213. "module = Object.create(module);",
  214. "if (!module.children) module.children = [];",
  215. "Object.defineProperty(module, 'exports', {",
  216. Template.indent([
  217. "enumerable: true,",
  218. `set: ${runtimeTemplate.basicFunction("", [
  219. "throw new Error('ES Modules may not assign module.exports or exports.*, Use ESM export syntax, instead: ' + module.id);"
  220. ])}`
  221. ]),
  222. "});",
  223. "return module;"
  224. ])};`
  225. ]);
  226. }
  227. }
  228. class NodeModuleDecoratorRuntimeModule extends RuntimeModule {
  229. constructor() {
  230. super("node module decorator");
  231. }
  232. /**
  233. * @returns {string} runtime code
  234. */
  235. generate() {
  236. const { runtimeTemplate } = this.compilation;
  237. return Template.asString([
  238. `${RuntimeGlobals.nodeModuleDecorator} = ${runtimeTemplate.basicFunction(
  239. "module",
  240. [
  241. "module.paths = [];",
  242. "if (!module.children) module.children = [];",
  243. "return module;"
  244. ]
  245. )};`
  246. ]);
  247. }
  248. }
  249. module.exports = CommonJsPlugin;