LoaderOptionsPlugin.js 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Tobias Koppers @sokra
  4. */
  5. "use strict";
  6. const ModuleFilenameHelpers = require("./ModuleFilenameHelpers");
  7. const NormalModule = require("./NormalModule");
  8. const createSchemaValidation = require("./util/create-schema-validation");
  9. /** @typedef {import("../declarations/plugins/LoaderOptionsPlugin").LoaderOptionsPluginOptions} LoaderOptionsPluginOptions */
  10. /** @typedef {import("./Compiler")} Compiler */
  11. /** @typedef {import("./ModuleFilenameHelpers").MatchObject} MatchObject */
  12. const validate = createSchemaValidation(
  13. require("../schemas/plugins/LoaderOptionsPlugin.check.js"),
  14. () => require("../schemas/plugins/LoaderOptionsPlugin.json"),
  15. {
  16. name: "Loader Options Plugin",
  17. baseDataPath: "options"
  18. }
  19. );
  20. class LoaderOptionsPlugin {
  21. /**
  22. * @param {LoaderOptionsPluginOptions & MatchObject} options options object
  23. */
  24. constructor(options = {}) {
  25. validate(options);
  26. // If no options are set then generate empty options object
  27. if (typeof options !== "object") options = {};
  28. if (!options.test) {
  29. // This is mocking a RegExp object which always returns true
  30. // TODO: Figure out how to do `as unknown as RegExp` for this line
  31. // in JSDoc equivalent
  32. /** @type {any} */
  33. const defaultTrueMockRegExp = {
  34. test: () => true
  35. };
  36. /** @type {RegExp} */
  37. options.test = defaultTrueMockRegExp;
  38. }
  39. this.options = options;
  40. }
  41. /**
  42. * Apply the plugin
  43. * @param {Compiler} compiler the compiler instance
  44. * @returns {void}
  45. */
  46. apply(compiler) {
  47. const options = this.options;
  48. compiler.hooks.compilation.tap("LoaderOptionsPlugin", compilation => {
  49. NormalModule.getCompilationHooks(compilation).loader.tap(
  50. "LoaderOptionsPlugin",
  51. (context, module) => {
  52. const resource = module.resource;
  53. if (!resource) return;
  54. const i = resource.indexOf("?");
  55. if (
  56. ModuleFilenameHelpers.matchObject(
  57. options,
  58. i < 0 ? resource : resource.slice(0, i)
  59. )
  60. ) {
  61. for (const key of Object.keys(options)) {
  62. if (key === "include" || key === "exclude" || key === "test") {
  63. continue;
  64. }
  65. context[key] = options[key];
  66. }
  67. }
  68. }
  69. );
  70. });
  71. }
  72. }
  73. module.exports = LoaderOptionsPlugin;