next-image-loader.js 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.default = exports.raw = void 0;
  6. var _loaderUtils3 = _interopRequireDefault(require("next/dist/compiled/loader-utils3"));
  7. var _imageOptimizer = require("../../../server/image-optimizer");
  8. function _interopRequireDefault(obj) {
  9. return obj && obj.__esModule ? obj : {
  10. default: obj
  11. };
  12. }
  13. const BLUR_IMG_SIZE = 8;
  14. const BLUR_QUALITY = 70;
  15. const VALID_BLUR_EXT = [
  16. "jpeg",
  17. "png",
  18. "webp",
  19. "avif"
  20. ] // should match next/client/image.tsx
  21. ;
  22. function nextImageLoader(content) {
  23. const imageLoaderSpan = this.currentTraceSpan.traceChild("next-image-loader");
  24. return imageLoaderSpan.traceAsyncFn(async ()=>{
  25. const { isServer , isDev , assetPrefix , basePath } = this.getOptions();
  26. const context = this.rootContext;
  27. const opts = {
  28. context,
  29. content
  30. };
  31. const interpolatedName = _loaderUtils3.default.interpolateName(this, "/static/media/[name].[hash:8].[ext]", opts);
  32. const outputPath = assetPrefix + "/_next" + interpolatedName;
  33. let extension = _loaderUtils3.default.interpolateName(this, "[ext]", opts);
  34. if (extension === "jpg") {
  35. extension = "jpeg";
  36. }
  37. const imageSizeSpan = imageLoaderSpan.traceChild("image-size-calculation");
  38. const imageSize = await imageSizeSpan.traceAsyncFn(()=>(0, _imageOptimizer).getImageSize(content, extension));
  39. let blurDataURL;
  40. let blurWidth;
  41. let blurHeight;
  42. if (VALID_BLUR_EXT.includes(extension)) {
  43. // Shrink the image's largest dimension
  44. if (imageSize.width >= imageSize.height) {
  45. blurWidth = BLUR_IMG_SIZE;
  46. blurHeight = Math.max(Math.round(imageSize.height / imageSize.width * BLUR_IMG_SIZE), 1);
  47. } else {
  48. blurWidth = Math.max(Math.round(imageSize.width / imageSize.height * BLUR_IMG_SIZE), 1);
  49. blurHeight = BLUR_IMG_SIZE;
  50. }
  51. if (isDev) {
  52. // During `next dev`, we don't want to generate blur placeholders with webpack
  53. // because it can delay starting the dev server. Instead, we inline a
  54. // special url to lazily generate the blur placeholder at request time.
  55. const prefix = "http://localhost";
  56. const url = new URL(`${basePath || ""}/_next/image`, prefix);
  57. url.searchParams.set("url", outputPath);
  58. url.searchParams.set("w", blurWidth);
  59. url.searchParams.set("q", BLUR_QUALITY);
  60. blurDataURL = url.href.slice(prefix.length);
  61. } else {
  62. const resizeImageSpan = imageLoaderSpan.traceChild("image-resize");
  63. const resizedImage = await resizeImageSpan.traceAsyncFn(()=>(0, _imageOptimizer).resizeImage(content, blurWidth, blurHeight, extension, BLUR_QUALITY));
  64. const blurDataURLSpan = imageLoaderSpan.traceChild("image-base64-tostring");
  65. blurDataURL = blurDataURLSpan.traceFn(()=>`data:image/${extension};base64,${resizedImage.toString("base64")}`);
  66. }
  67. }
  68. const stringifiedData = imageLoaderSpan.traceChild("image-data-stringify").traceFn(()=>JSON.stringify({
  69. src: outputPath,
  70. height: imageSize.height,
  71. width: imageSize.width,
  72. blurDataURL,
  73. blurWidth,
  74. blurHeight
  75. }));
  76. if (!isServer) {
  77. this.emitFile(interpolatedName, content, null);
  78. }
  79. return `export default ${stringifiedData};`;
  80. });
  81. }
  82. const raw = true;
  83. exports.raw = raw;
  84. var _default = nextImageLoader;
  85. exports.default = _default;
  86. //# sourceMappingURL=next-image-loader.js.map