ImportMetaContextPlugin.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Ivan Kopeykin @vankop
  4. */
  5. "use strict";
  6. const {
  7. JAVASCRIPT_MODULE_TYPE_AUTO,
  8. JAVASCRIPT_MODULE_TYPE_ESM
  9. } = require("../ModuleTypeConstants");
  10. const ContextElementDependency = require("./ContextElementDependency");
  11. const ImportMetaContextDependency = require("./ImportMetaContextDependency");
  12. const ImportMetaContextDependencyParserPlugin = require("./ImportMetaContextDependencyParserPlugin");
  13. const ImportMetaGlobDependency = require("./ImportMetaGlobDependency");
  14. const ImportMetaGlobDependencyParserPlugin = require("./ImportMetaGlobDependencyParserPlugin");
  15. const { isImportMetaFieldEnabled } = require("./ImportMetaPlugin");
  16. /**
  17. * @import {
  18. * JavascriptParserOptions
  19. * } from "../../declarations/WebpackOptions"
  20. */
  21. /** @import Compiler from "../Compiler" */
  22. /** @import Parser from "../javascript/JavascriptParser" */
  23. const PLUGIN_NAME = "ImportMetaContextPlugin";
  24. /** @type {(parserOptions: JavascriptParserOptions) => boolean} */
  25. const isImportMetaContextEnabled = (parserOptions) => {
  26. const importMeta = parserOptions.importMeta;
  27. if (
  28. Boolean(importMeta) &&
  29. typeof importMeta === "object" &&
  30. Object.prototype.hasOwnProperty.call(importMeta, "webpackContext")
  31. ) {
  32. return isImportMetaFieldEnabled(importMeta, "webpackContext");
  33. }
  34. if (parserOptions.importMetaContext === false) {
  35. return false;
  36. }
  37. return isImportMetaFieldEnabled(importMeta, "webpackContext");
  38. };
  39. // Gated only by the `importMeta.glob` field — independent of the legacy
  40. // `importMetaContext` toggle, which controls `import.meta.webpackContext`.
  41. /** @type {(parserOptions: JavascriptParserOptions) => boolean} */
  42. const isImportMetaGlobEnabled = (parserOptions) =>
  43. isImportMetaFieldEnabled(parserOptions.importMeta, "glob");
  44. class ImportMetaContextPlugin {
  45. /**
  46. * Applies the plugin by registering its hooks on the compiler.
  47. * @param {Compiler} compiler the compiler instance
  48. * @returns {void}
  49. */
  50. apply(compiler) {
  51. compiler.hooks.compilation.tap(
  52. PLUGIN_NAME,
  53. (compilation, { contextModuleFactory, normalModuleFactory }) => {
  54. compilation.dependencyFactories.set(
  55. ImportMetaContextDependency,
  56. contextModuleFactory
  57. );
  58. compilation.dependencyTemplates.set(
  59. ImportMetaContextDependency,
  60. new ImportMetaContextDependency.Template()
  61. );
  62. compilation.dependencyFactories.set(
  63. ImportMetaGlobDependency,
  64. contextModuleFactory
  65. );
  66. compilation.dependencyTemplates.set(
  67. ImportMetaGlobDependency,
  68. new ImportMetaGlobDependency.Template()
  69. );
  70. compilation.dependencyFactories.set(
  71. ContextElementDependency,
  72. normalModuleFactory
  73. );
  74. /**
  75. * Handles the hook callback for this code path.
  76. * @param {Parser} parser parser parser
  77. * @param {JavascriptParserOptions} parserOptions parserOptions
  78. * @returns {void}
  79. */
  80. const handler = (parser, parserOptions) => {
  81. if (isImportMetaContextEnabled(parserOptions)) {
  82. new ImportMetaContextDependencyParserPlugin().apply(parser);
  83. }
  84. if (isImportMetaGlobEnabled(parserOptions)) {
  85. new ImportMetaGlobDependencyParserPlugin().apply(parser);
  86. }
  87. };
  88. normalModuleFactory.hooks.parser
  89. .for(JAVASCRIPT_MODULE_TYPE_AUTO)
  90. .tap(PLUGIN_NAME, handler);
  91. normalModuleFactory.hooks.parser
  92. .for(JAVASCRIPT_MODULE_TYPE_ESM)
  93. .tap(PLUGIN_NAME, handler);
  94. }
  95. );
  96. }
  97. }
  98. module.exports = ImportMetaContextPlugin;