DataUriPlugin.js 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Tobias Koppers @sokra
  4. */
  5. "use strict";
  6. const NormalModule = require("../NormalModule");
  7. /** @typedef {import("../Compiler")} Compiler */
  8. // data URL scheme: "data:text/javascript;charset=utf-8;base64,some-string"
  9. // http://www.ietf.org/rfc/rfc2397.txt
  10. const URIRegEx = /^data:([^;,]+)?((?:;[^;,]+)*?)(?:;(base64))?,(.*)$/i;
  11. const decodeDataURI = uri => {
  12. const match = URIRegEx.exec(uri);
  13. if (!match) return null;
  14. const isBase64 = match[3];
  15. const body = match[4];
  16. return isBase64
  17. ? Buffer.from(body, "base64")
  18. : Buffer.from(decodeURIComponent(body), "ascii");
  19. };
  20. class DataUriPlugin {
  21. /**
  22. * Apply the plugin
  23. * @param {Compiler} compiler the compiler instance
  24. * @returns {void}
  25. */
  26. apply(compiler) {
  27. compiler.hooks.compilation.tap(
  28. "DataUriPlugin",
  29. (compilation, { normalModuleFactory }) => {
  30. normalModuleFactory.hooks.resolveForScheme
  31. .for("data")
  32. .tap("DataUriPlugin", resourceData => {
  33. const match = URIRegEx.exec(resourceData.resource);
  34. if (match) {
  35. resourceData.data.mimetype = match[1] || "";
  36. resourceData.data.parameters = match[2] || "";
  37. resourceData.data.encoding = match[3] || false;
  38. resourceData.data.encodedContent = match[4] || "";
  39. }
  40. });
  41. NormalModule.getCompilationHooks(compilation)
  42. .readResourceForScheme.for("data")
  43. .tap("DataUriPlugin", resource => decodeDataURI(resource));
  44. }
  45. );
  46. }
  47. }
  48. module.exports = DataUriPlugin;