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.

86 lines
2.3 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 ParserHelpers = require("./ParserHelpers");
  7. const ConstDependency = require("./dependencies/ConstDependency");
  8. const NullFactory = require("./NullFactory");
  9. class ProvidePlugin {
  10. constructor(definitions) {
  11. this.definitions = definitions;
  12. }
  13. apply(compiler) {
  14. const definitions = this.definitions;
  15. compiler.hooks.compilation.tap(
  16. "ProvidePlugin",
  17. (compilation, { normalModuleFactory }) => {
  18. compilation.dependencyFactories.set(ConstDependency, new NullFactory());
  19. compilation.dependencyTemplates.set(
  20. ConstDependency,
  21. new ConstDependency.Template()
  22. );
  23. const handler = (parser, parserOptions) => {
  24. Object.keys(definitions).forEach(name => {
  25. var request = [].concat(definitions[name]);
  26. var splittedName = name.split(".");
  27. if (splittedName.length > 0) {
  28. splittedName.slice(1).forEach((_, i) => {
  29. const name = splittedName.slice(0, i + 1).join(".");
  30. parser.hooks.canRename
  31. .for(name)
  32. .tap("ProvidePlugin", ParserHelpers.approve);
  33. });
  34. }
  35. parser.hooks.expression.for(name).tap("ProvidePlugin", expr => {
  36. let nameIdentifier = name;
  37. const scopedName = name.includes(".");
  38. let expression = `require(${JSON.stringify(request[0])})`;
  39. if (scopedName) {
  40. nameIdentifier = `__webpack_provided_${name.replace(
  41. /\./g,
  42. "_dot_"
  43. )}`;
  44. }
  45. if (request.length > 1) {
  46. expression += request
  47. .slice(1)
  48. .map(r => `[${JSON.stringify(r)}]`)
  49. .join("");
  50. }
  51. if (
  52. !ParserHelpers.addParsedVariableToModule(
  53. parser,
  54. nameIdentifier,
  55. expression
  56. )
  57. ) {
  58. return false;
  59. }
  60. if (scopedName) {
  61. ParserHelpers.toConstantDependency(
  62. parser,
  63. nameIdentifier
  64. )(expr);
  65. }
  66. return true;
  67. });
  68. });
  69. };
  70. normalModuleFactory.hooks.parser
  71. .for("javascript/auto")
  72. .tap("ProvidePlugin", handler);
  73. normalModuleFactory.hooks.parser
  74. .for("javascript/dynamic")
  75. .tap("ProvidePlugin", handler);
  76. // Disable ProvidePlugin for javascript/esm, see https://github.com/webpack/webpack/issues/7032
  77. }
  78. );
  79. }
  80. }
  81. module.exports = ProvidePlugin;