提交学习笔记专用
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.

81 lines
2.2 KiB

  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. /**
  13. * @template T
  14. * @typedef {import("../declarations/LoaderContext").LoaderContext<T>} LoaderContext
  15. */
  16. const validate = createSchemaValidation(
  17. require("../schemas/plugins/LoaderOptionsPlugin.check"),
  18. () => require("../schemas/plugins/LoaderOptionsPlugin.json"),
  19. {
  20. name: "Loader Options Plugin",
  21. baseDataPath: "options"
  22. }
  23. );
  24. const PLUGIN_NAME = "LoaderOptionsPlugin";
  25. class LoaderOptionsPlugin {
  26. /**
  27. * @param {LoaderOptionsPluginOptions & MatchObject} options options object
  28. */
  29. constructor(options = {}) {
  30. validate(options);
  31. // If no options are set then generate empty options object
  32. if (typeof options !== "object") options = {};
  33. if (!options.test) {
  34. options.test = () => true;
  35. }
  36. this.options = options;
  37. }
  38. /**
  39. * Apply the plugin
  40. * @param {Compiler} compiler the compiler instance
  41. * @returns {void}
  42. */
  43. apply(compiler) {
  44. const options = this.options;
  45. compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
  46. NormalModule.getCompilationHooks(compilation).loader.tap(
  47. PLUGIN_NAME,
  48. (context, module) => {
  49. const resource = module.resource;
  50. if (!resource) return;
  51. const i = resource.indexOf("?");
  52. if (
  53. ModuleFilenameHelpers.matchObject(
  54. options,
  55. i < 0 ? resource : resource.slice(0, i)
  56. )
  57. ) {
  58. for (const key of Object.keys(options)) {
  59. if (key === "include" || key === "exclude" || key === "test") {
  60. continue;
  61. }
  62. /** @type {LoaderContext<EXPECTED_ANY> & Record<string, EXPECTED_ANY>} */
  63. (context)[key] = options[key];
  64. }
  65. }
  66. }
  67. );
  68. });
  69. }
  70. }
  71. module.exports = LoaderOptionsPlugin;