CommonJsPlugin.js 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Tobias Koppers @sokra
  4. */
  5. "use strict";
  6. const ConstDependency = require("./ConstDependency");
  7. const CommonJsRequireDependency = require("./CommonJsRequireDependency");
  8. const CommonJsRequireContextDependency = require("./CommonJsRequireContextDependency");
  9. const RequireResolveDependency = require("./RequireResolveDependency");
  10. const RequireResolveContextDependency = require("./RequireResolveContextDependency");
  11. const RequireResolveHeaderDependency = require("./RequireResolveHeaderDependency");
  12. const RequireHeaderDependency = require("./RequireHeaderDependency");
  13. const NullFactory = require("../NullFactory");
  14. const RequireResolveDependencyParserPlugin = require("./RequireResolveDependencyParserPlugin");
  15. const CommonJsRequireDependencyParserPlugin = require("./CommonJsRequireDependencyParserPlugin");
  16. const ParserHelpers = require("../ParserHelpers");
  17. class CommonJsPlugin {
  18. constructor(options) {
  19. this.options = options;
  20. }
  21. apply(compiler) {
  22. const options = this.options;
  23. compiler.hooks.compilation.tap(
  24. "CommonJsPlugin",
  25. (compilation, { contextModuleFactory, normalModuleFactory }) => {
  26. compilation.dependencyFactories.set(
  27. CommonJsRequireDependency,
  28. normalModuleFactory
  29. );
  30. compilation.dependencyTemplates.set(
  31. CommonJsRequireDependency,
  32. new CommonJsRequireDependency.Template()
  33. );
  34. compilation.dependencyFactories.set(
  35. CommonJsRequireContextDependency,
  36. contextModuleFactory
  37. );
  38. compilation.dependencyTemplates.set(
  39. CommonJsRequireContextDependency,
  40. new CommonJsRequireContextDependency.Template()
  41. );
  42. compilation.dependencyFactories.set(
  43. RequireResolveDependency,
  44. normalModuleFactory
  45. );
  46. compilation.dependencyTemplates.set(
  47. RequireResolveDependency,
  48. new RequireResolveDependency.Template()
  49. );
  50. compilation.dependencyFactories.set(
  51. RequireResolveContextDependency,
  52. contextModuleFactory
  53. );
  54. compilation.dependencyTemplates.set(
  55. RequireResolveContextDependency,
  56. new RequireResolveContextDependency.Template()
  57. );
  58. compilation.dependencyFactories.set(
  59. RequireResolveHeaderDependency,
  60. new NullFactory()
  61. );
  62. compilation.dependencyTemplates.set(
  63. RequireResolveHeaderDependency,
  64. new RequireResolveHeaderDependency.Template()
  65. );
  66. compilation.dependencyFactories.set(
  67. RequireHeaderDependency,
  68. new NullFactory()
  69. );
  70. compilation.dependencyTemplates.set(
  71. RequireHeaderDependency,
  72. new RequireHeaderDependency.Template()
  73. );
  74. const handler = (parser, parserOptions) => {
  75. if (
  76. typeof parserOptions.commonjs !== "undefined" &&
  77. !parserOptions.commonjs
  78. )
  79. return;
  80. const requireExpressions = [
  81. "require",
  82. "require.resolve",
  83. "require.resolveWeak"
  84. ];
  85. for (let expression of requireExpressions) {
  86. parser.hooks.typeof
  87. .for(expression)
  88. .tap(
  89. "CommonJsPlugin",
  90. ParserHelpers.toConstantDependency(
  91. parser,
  92. JSON.stringify("function")
  93. )
  94. );
  95. parser.hooks.evaluateTypeof
  96. .for(expression)
  97. .tap(
  98. "CommonJsPlugin",
  99. ParserHelpers.evaluateToString("function")
  100. );
  101. parser.hooks.evaluateIdentifier
  102. .for(expression)
  103. .tap(
  104. "CommonJsPlugin",
  105. ParserHelpers.evaluateToIdentifier(expression, true)
  106. );
  107. }
  108. parser.hooks.evaluateTypeof
  109. .for("module")
  110. .tap("CommonJsPlugin", ParserHelpers.evaluateToString("object"));
  111. parser.hooks.assign.for("require").tap("CommonJsPlugin", expr => {
  112. // to not leak to global "require", we need to define a local require here.
  113. const dep = new ConstDependency("var require;", 0);
  114. dep.loc = expr.loc;
  115. parser.state.current.addDependency(dep);
  116. parser.scope.definitions.add("require");
  117. return true;
  118. });
  119. parser.hooks.canRename
  120. .for("require")
  121. .tap("CommonJsPlugin", () => true);
  122. parser.hooks.rename.for("require").tap("CommonJsPlugin", expr => {
  123. // define the require variable. It's still undefined, but not "not defined".
  124. const dep = new ConstDependency("var require;", 0);
  125. dep.loc = expr.loc;
  126. parser.state.current.addDependency(dep);
  127. return false;
  128. });
  129. parser.hooks.typeof.for("module").tap("CommonJsPlugin", () => true);
  130. parser.hooks.evaluateTypeof
  131. .for("exports")
  132. .tap("CommonJsPlugin", ParserHelpers.evaluateToString("object"));
  133. new CommonJsRequireDependencyParserPlugin(options).apply(parser);
  134. new RequireResolveDependencyParserPlugin(options).apply(parser);
  135. };
  136. normalModuleFactory.hooks.parser
  137. .for("javascript/auto")
  138. .tap("CommonJsPlugin", handler);
  139. normalModuleFactory.hooks.parser
  140. .for("javascript/dynamic")
  141. .tap("CommonJsPlugin", handler);
  142. }
  143. );
  144. }
  145. }
  146. module.exports = CommonJsPlugin;