SystemPlugin.js 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  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 WebpackError = require("../WebpackError");
  12. const {
  13. evaluateToString,
  14. expressionIsUnsupported,
  15. toConstantDependency
  16. } = require("../javascript/JavascriptParserHelpers");
  17. const makeSerializable = require("../util/makeSerializable");
  18. const ConstDependency = require("./ConstDependency");
  19. const SystemRuntimeModule = require("./SystemRuntimeModule");
  20. /** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */
  21. /** @typedef {import("../Compiler")} Compiler */
  22. /** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */
  23. /** @typedef {import("../javascript/JavascriptParser")} Parser */
  24. /** @typedef {import("../javascript/JavascriptParser").Range} Range */
  25. const PLUGIN_NAME = "SystemPlugin";
  26. class SystemPlugin {
  27. /**
  28. * Applies the plugin by registering its hooks on the compiler.
  29. * @param {Compiler} compiler the compiler instance
  30. * @returns {void}
  31. */
  32. apply(compiler) {
  33. compiler.hooks.compilation.tap(
  34. PLUGIN_NAME,
  35. (compilation, { normalModuleFactory }) => {
  36. compilation.hooks.runtimeRequirementInModule
  37. .for(RuntimeGlobals.system)
  38. .tap(PLUGIN_NAME, (module, set) => {
  39. set.add(RuntimeGlobals.requireScope);
  40. });
  41. compilation.hooks.runtimeRequirementInTree
  42. .for(RuntimeGlobals.system)
  43. .tap(PLUGIN_NAME, (chunk, _set) => {
  44. compilation.addRuntimeModule(chunk, new SystemRuntimeModule());
  45. });
  46. /**
  47. * Handles the hook callback for this code path.
  48. * @param {Parser} parser parser parser
  49. * @param {JavascriptParserOptions} parserOptions parserOptions
  50. * @returns {void}
  51. */
  52. const handler = (parser, parserOptions) => {
  53. if (parserOptions.system === undefined || !parserOptions.system) {
  54. return;
  55. }
  56. /**
  57. * Sets not supported.
  58. * @param {string} name name
  59. */
  60. const setNotSupported = (name) => {
  61. parser.hooks.evaluateTypeof
  62. .for(name)
  63. .tap(PLUGIN_NAME, evaluateToString("undefined"));
  64. parser.hooks.expression
  65. .for(name)
  66. .tap(
  67. PLUGIN_NAME,
  68. expressionIsUnsupported(
  69. parser,
  70. `${name} is not supported by webpack.`
  71. )
  72. );
  73. };
  74. parser.hooks.typeof
  75. .for("System.import")
  76. .tap(
  77. PLUGIN_NAME,
  78. toConstantDependency(parser, JSON.stringify("function"))
  79. );
  80. parser.hooks.evaluateTypeof
  81. .for("System.import")
  82. .tap(PLUGIN_NAME, evaluateToString("function"));
  83. parser.hooks.typeof
  84. .for("System")
  85. .tap(
  86. PLUGIN_NAME,
  87. toConstantDependency(parser, JSON.stringify("object"))
  88. );
  89. parser.hooks.evaluateTypeof
  90. .for("System")
  91. .tap(PLUGIN_NAME, evaluateToString("object"));
  92. setNotSupported("System.set");
  93. setNotSupported("System.get");
  94. setNotSupported("System.register");
  95. parser.hooks.expression.for("System").tap(PLUGIN_NAME, (expr) => {
  96. const dep = new ConstDependency(
  97. RuntimeGlobals.system,
  98. /** @type {Range} */ (expr.range),
  99. [RuntimeGlobals.system]
  100. );
  101. dep.loc = /** @type {DependencyLocation} */ (expr.loc);
  102. parser.state.module.addPresentationalDependency(dep);
  103. return true;
  104. });
  105. parser.hooks.call.for("System.import").tap(PLUGIN_NAME, (expr) => {
  106. parser.state.module.addWarning(
  107. new SystemImportDeprecationWarning(
  108. /** @type {DependencyLocation} */ (expr.loc)
  109. )
  110. );
  111. return parser.hooks.importCall.call({
  112. type: "ImportExpression",
  113. source:
  114. /** @type {import("estree").Literal} */
  115. (expr.arguments[0]),
  116. loc: expr.loc,
  117. range: expr.range,
  118. options: null
  119. });
  120. });
  121. };
  122. normalModuleFactory.hooks.parser
  123. .for(JAVASCRIPT_MODULE_TYPE_AUTO)
  124. .tap(PLUGIN_NAME, handler);
  125. normalModuleFactory.hooks.parser
  126. .for(JAVASCRIPT_MODULE_TYPE_DYNAMIC)
  127. .tap(PLUGIN_NAME, handler);
  128. }
  129. );
  130. }
  131. }
  132. class SystemImportDeprecationWarning extends WebpackError {
  133. /**
  134. * Creates an instance of SystemImportDeprecationWarning.
  135. * @param {DependencyLocation} loc location
  136. */
  137. constructor(loc) {
  138. super(
  139. "System.import() is deprecated and will be removed soon. Use import() instead.\n" +
  140. "For more info visit https://webpack.js.org/guides/code-splitting/"
  141. );
  142. this.name = "SystemImportDeprecationWarning";
  143. this.loc = loc;
  144. }
  145. }
  146. makeSerializable(
  147. SystemImportDeprecationWarning,
  148. "webpack/lib/dependencies/SystemPlugin",
  149. "SystemImportDeprecationWarning"
  150. );
  151. module.exports = SystemPlugin;
  152. module.exports.SystemImportDeprecationWarning = SystemImportDeprecationWarning;