SystemPlugin.js 4.7 KB

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