You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

158 lines
4.9 KiB

4 years ago
  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 (parserOptions.commonjs !== undefined && !parserOptions.commonjs)
  76. return;
  77. const requireExpressions = [
  78. "require",
  79. "require.resolve",
  80. "require.resolveWeak"
  81. ];
  82. for (let expression of requireExpressions) {
  83. parser.hooks.typeof
  84. .for(expression)
  85. .tap(
  86. "CommonJsPlugin",
  87. ParserHelpers.toConstantDependency(
  88. parser,
  89. JSON.stringify("function")
  90. )
  91. );
  92. parser.hooks.evaluateTypeof
  93. .for(expression)
  94. .tap(
  95. "CommonJsPlugin",
  96. ParserHelpers.evaluateToString("function")
  97. );
  98. parser.hooks.evaluateIdentifier
  99. .for(expression)
  100. .tap(
  101. "CommonJsPlugin",
  102. ParserHelpers.evaluateToIdentifier(expression, true)
  103. );
  104. }
  105. parser.hooks.evaluateTypeof
  106. .for("module")
  107. .tap("CommonJsPlugin", ParserHelpers.evaluateToString("object"));
  108. parser.hooks.assign.for("require").tap("CommonJsPlugin", expr => {
  109. // to not leak to global "require", we need to define a local require here.
  110. const dep = new ConstDependency("var require;", 0);
  111. dep.loc = expr.loc;
  112. parser.state.current.addDependency(dep);
  113. parser.scope.definitions.add("require");
  114. return true;
  115. });
  116. parser.hooks.canRename
  117. .for("require")
  118. .tap("CommonJsPlugin", () => true);
  119. parser.hooks.rename.for("require").tap("CommonJsPlugin", expr => {
  120. // define the require variable. It's still undefined, but not "not defined".
  121. const dep = new ConstDependency("var require;", 0);
  122. dep.loc = expr.loc;
  123. parser.state.current.addDependency(dep);
  124. return false;
  125. });
  126. parser.hooks.typeof.for("module").tap("CommonJsPlugin", () => true);
  127. parser.hooks.evaluateTypeof
  128. .for("exports")
  129. .tap("CommonJsPlugin", ParserHelpers.evaluateToString("object"));
  130. new CommonJsRequireDependencyParserPlugin(options).apply(parser);
  131. new RequireResolveDependencyParserPlugin(options).apply(parser);
  132. };
  133. normalModuleFactory.hooks.parser
  134. .for("javascript/auto")
  135. .tap("CommonJsPlugin", handler);
  136. normalModuleFactory.hooks.parser
  137. .for("javascript/dynamic")
  138. .tap("CommonJsPlugin", handler);
  139. }
  140. );
  141. }
  142. }
  143. module.exports = CommonJsPlugin;