@qzsy/vinext 0.1.7 → 0.1.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -731,6 +731,7 @@ function vinext(options = {}) {
731
731
  }
732
732
  defines["process.env.__VINEXT_IMAGE_DANGEROUSLY_ALLOW_SVG"] = JSON.stringify(String(nextConfig.images?.dangerouslyAllowSVG ?? false));
733
733
  defines["process.env.__VINEXT_IMAGE_DANGEROUSLY_ALLOW_LOCAL_IP"] = JSON.stringify(String(nextConfig.images?.dangerouslyAllowLocalIP ?? false));
734
+ defines["process.env.__VINEXT_IMAGE_LOADER_CONFIGURED"] = JSON.stringify(nextConfig.images?.loaderFile ? "true" : "false");
734
735
  defines["process.env.__VINEXT_BUILD_ID"] = JSON.stringify(nextConfig.buildId);
735
736
  defines["process.env.__VINEXT_RSC_COMPATIBILITY_ID"] = JSON.stringify(rscCompatibilityId);
736
737
  defines["process.env.__VINEXT_DEPLOYMENT_ID"] = JSON.stringify(nextConfig.deploymentId ?? "");
@@ -826,6 +827,9 @@ function vinext(options = {}) {
826
827
  overlay: false
827
828
  };
828
829
  const cssModulesOverride = config.css?.modules === false || typeof config.css?.modules === "object" && "Loader" in config.css.modules ? {} : { modules: { Loader: sassComposesLoader.Loader } };
830
+ const defaultImageLoaderShimPath = resolveShimModulePath(shimsDir, "default-image-loader");
831
+ const imageLoaderFile = nextConfig.images?.loaderFile;
832
+ const imageLoaderAlias = imageLoaderFile != null ? { [defaultImageLoaderShimPath]: imageLoaderFile } : {};
829
833
  const viteConfig = {
830
834
  appType: "custom",
831
835
  build: {
@@ -873,7 +877,8 @@ function vinext(options = {}) {
873
877
  alias: {
874
878
  ...tsconfigPathAliases,
875
879
  ...nextConfig.aliases,
876
- ...nextShimMap
880
+ ...nextShimMap,
881
+ ...imageLoaderAlias
877
882
  },
878
883
  dedupe: [
879
884
  "react",
@@ -920,6 +925,7 @@ function vinext(options = {}) {
920
925
  resolveId(id) {
921
926
  const shimBase = _reactServerShims.get(id);
922
927
  if (shimBase !== void 0) return resolveShimModulePath(shimsDir, shimBase);
928
+ if (imageLoaderFile != null && id === defaultImageLoaderShimPath) return imageLoaderFile;
923
929
  }
924
930
  };
925
931
  const depOptimizeNodeEnvOptions = getDepOptimizeNodeEnvOptions(viteMajorVersion, nodeEnvDefine);
@@ -17,11 +17,11 @@ import "./app-page-response.js";
17
17
  import { buildNextDataNotFoundResponse, normalizePagesDataRequest } from "./pages-data-route.js";
18
18
  import { matchPrerenderRouteParamsPayload, readTrustedPrerenderRouteParams, serializePrerenderRouteParamsHeader } from "./prerender-route-params.js";
19
19
  import { getRenderedConcreteUrlPathsForRoute } from "./pregenerated-concrete-paths.js";
20
- import { flattenErrorCauses } from "../utils/error-cause.js";
21
20
  import { pickRootParams, setRootParams } from "../shims/root-params.js";
22
21
  import { createServerActionNotFoundResponse, getServerActionNotFoundMessage } from "./server-action-not-found.js";
23
22
  import { buildPageCacheTags } from "./implicit-tags.js";
24
23
  import { buildPostMwRequestContext } from "./app-post-middleware-context.js";
24
+ import { flattenErrorCauses } from "../utils/error-cause.js";
25
25
  import { finalizeAppRscResponse } from "./app-rsc-response-finalizer.js";
26
26
  import { normalizeRscRequest } from "./app-rsc-request-normalization.js";
27
27
  import { runWithPrerenderWorkUnit } from "./prerender-work-unit-setup.js";
@@ -0,0 +1,12 @@
1
+ //#region src/shims/default-image-loader.d.ts
2
+ declare function defaultImageLoader({
3
+ src,
4
+ width,
5
+ quality
6
+ }: {
7
+ src: string;
8
+ width: number;
9
+ quality?: number;
10
+ }): string;
11
+ //#endregion
12
+ export { defaultImageLoader as default };
@@ -0,0 +1,13 @@
1
+ import { imageOptimizationUrl } from "./image-optimization-url.js";
2
+ //#region src/shims/default-image-loader.ts
3
+ /**
4
+ * Default image loader for next/image.
5
+ *
6
+ * When `images.loaderFile` is configured in next.config.js, vinext aliases
7
+ * this module to the user's custom loader at build time (mirroring Next.js).
8
+ */
9
+ function defaultImageLoader({ src, width, quality = 75 }) {
10
+ return imageOptimizationUrl(src, width, quality);
11
+ }
12
+ //#endregion
13
+ export { defaultImageLoader as default };
@@ -0,0 +1,10 @@
1
+ //#region src/shims/image-optimization-url.d.ts
2
+ /**
3
+ * Build a `/_next/image` optimization URL.
4
+ *
5
+ * Shared by the next/image shim and the default image loader module so
6
+ * `images.loaderFile` aliasing does not create a circular import.
7
+ */
8
+ declare function imageOptimizationUrl(src: string, width: number, quality?: number): string;
9
+ //#endregion
10
+ export { imageOptimizationUrl };
@@ -0,0 +1,12 @@
1
+ //#region src/shims/image-optimization-url.ts
2
+ /**
3
+ * Build a `/_next/image` optimization URL.
4
+ *
5
+ * Shared by the next/image shim and the default image loader module so
6
+ * `images.loaderFile` aliasing does not create a circular import.
7
+ */
8
+ function imageOptimizationUrl(src, width, quality = 75) {
9
+ return `/_next/image?url=${encodeURIComponent(src)}&w=${width}&q=${quality}`;
10
+ }
11
+ //#endregion
12
+ export { imageOptimizationUrl };
@@ -1,3 +1,4 @@
1
+ import { imageOptimizationUrl } from "./image-optimization-url.js";
1
2
  import React from "react";
2
3
 
3
4
  //#region src/shims/image.d.ts
@@ -35,14 +36,6 @@ type ImageProps = {
35
36
  overrideSrc?: string;
36
37
  loading?: "lazy" | "eager";
37
38
  };
38
- /**
39
- * Build a `/_next/image` optimization URL.
40
- *
41
- * In production (Cloudflare Workers), the worker intercepts this path and uses
42
- * the Images binding to resize/transcode on the fly. In dev, the Vite dev
43
- * server handles it as a passthrough (serves the original file).
44
- */
45
- declare function imageOptimizationUrl(src: string, width: number, quality?: number): string;
46
39
  declare const Image: React.ForwardRefExoticComponent<ImageProps & React.RefAttributes<HTMLImageElement>>;
47
40
  /**
48
41
  * getImageProps — for advanced use cases (picture elements, background images).
@@ -1,4 +1,6 @@
1
1
  "use client";
2
+ import { imageOptimizationUrl } from "./image-optimization-url.js";
3
+ import defaultImageLoader from "./default-image-loader.js";
2
4
  import { useMergedRef } from "./use-merged-ref.js";
3
5
  import { hasRemoteMatch, isPrivateIp } from "./image-config.js";
4
6
  import { forwardRef, useEffect, useLayoutEffect, useRef, useState } from "react";
@@ -68,6 +70,14 @@ const __dangerouslyAllowSVG = process.env.__VINEXT_IMAGE_DANGEROUSLY_ALLOW_SVG =
68
70
  * are blocked to mitigate SSRF risk.
69
71
  */
70
72
  const __dangerouslyAllowLocalIP = process.env.__VINEXT_IMAGE_DANGEROUSLY_ALLOW_LOCAL_IP === "true";
73
+ /** Set when next.config.js configures images.loaderFile. */
74
+ const __imageLoaderConfigured = process.env.__VINEXT_IMAGE_LOADER_CONFIGURED === "true";
75
+ function resolveEffectiveLoader(loader) {
76
+ if (loader) return loader;
77
+ if (!__imageLoaderConfigured) return void 0;
78
+ if (typeof defaultImageLoader !== "function") throw new Error("images.loaderFile detected but the file is missing default export.\nRead more: https://nextjs.org/docs/messages/invalid-images-config");
79
+ return defaultImageLoader;
80
+ }
71
81
  /**
72
82
  * Validate that a remote URL is allowed by the configured remote patterns.
73
83
  * Returns true if the URL is allowed, false otherwise.
@@ -211,16 +221,6 @@ function resolveImageSource(v) {
211
221
  * Configurable via `images.deviceSizes` in next.config.js.
212
222
  */
213
223
  const RESPONSIVE_WIDTHS = __imageDeviceSizes;
214
- /**
215
- * Build a `/_next/image` optimization URL.
216
- *
217
- * In production (Cloudflare Workers), the worker intercepts this path and uses
218
- * the Images binding to resize/transcode on the fly. In dev, the Vite dev
219
- * server handles it as a passthrough (serves the original file).
220
- */
221
- function imageOptimizationUrl(src, width, quality = 75) {
222
- return `/_next/image?url=${encodeURIComponent(src)}&w=${width}&q=${quality}`;
223
- }
224
224
  function preloadImageResource(input) {
225
225
  if (!input.shouldPreload) return;
226
226
  if (typeof ReactDOM.preload !== "function") return;
@@ -270,6 +270,7 @@ const Image = forwardRef(function Image({ src: srcProp, alt, width, height, fill
270
270
  const shouldPreload = preload === true || priority === true;
271
271
  const priorityFetchPriority = priority ? "high" : void 0;
272
272
  const imageLoading = priority ? "eager" : shouldPreload ? loading : loading ?? "lazy";
273
+ const effectiveLoader = resolveEffectiveLoader(loader);
273
274
  const [completedBlurSrc, setCompletedBlurSrc] = useState(void 0);
274
275
  const blurComplete = completedBlurSrc === src;
275
276
  const markBlurComplete = () => {
@@ -360,8 +361,8 @@ const Image = forwardRef(function Image({ src: srcProp, alt, width, height, fill
360
361
  ...rest
361
362
  });
362
363
  }
363
- if (loader) {
364
- const resolvedSrc = loader({
364
+ if (effectiveLoader) {
365
+ const resolvedSrc = effectiveLoader({
365
366
  src,
366
367
  width: imgWidth ?? 0,
367
368
  quality: quality ?? 75
@@ -508,6 +509,7 @@ function getImageProps(props) {
508
509
  blurDataURL: blurDataURLProp
509
510
  });
510
511
  const shouldPreload = _preload === true || priority === true;
512
+ const effectiveLoader = resolveEffectiveLoader(loader);
511
513
  if (_unoptimized === true) {
512
514
  const renderedSrc = overrideSrc || src;
513
515
  const sanitizedBlurURL = imgBlurDataURL ? sanitizeBlurDataURL(imgBlurDataURL) : void 0;
@@ -544,14 +546,14 @@ function getImageProps(props) {
544
546
  }
545
547
  }
546
548
  const imgQuality = _quality ?? 75;
547
- const resolvedSrc = blockedInProd ? "" : loader ? loader({
549
+ const resolvedSrc = blockedInProd ? "" : effectiveLoader ? effectiveLoader({
548
550
  src,
549
551
  width: imgWidth ?? 0,
550
552
  quality: imgQuality
551
553
  }) : src;
552
- const skipOpt = isSvgUrl(resolvedSrc) && !__dangerouslyAllowSVG || blockedInProd || !!loader || isRemoteUrl(resolvedSrc);
554
+ const skipOpt = isSvgUrl(resolvedSrc) && !__dangerouslyAllowSVG || blockedInProd || !!effectiveLoader || isRemoteUrl(resolvedSrc);
553
555
  const optimizedSrc = skipOpt ? resolvedSrc : imgWidth ? imageOptimizationUrl(resolvedSrc, imgWidth, imgQuality) : imageOptimizationUrl(resolvedSrc, RESPONSIVE_WIDTHS[0], imgQuality);
554
- const srcSet = imgWidth && !fill && !isRemoteUrl(resolvedSrc) && !loader && !skipOpt ? generateSrcSet(resolvedSrc, imgWidth, imgQuality) : void 0;
556
+ const srcSet = imgWidth && !fill && !isRemoteUrl(resolvedSrc) && !effectiveLoader && !skipOpt ? generateSrcSet(resolvedSrc, imgWidth, imgQuality) : void 0;
555
557
  const sanitizedBlurURL = imgBlurDataURL ? sanitizeBlurDataURL(imgBlurDataURL) : void 0;
556
558
  const blurStyle = placeholder === "blur" && sanitizedBlurURL ? {
557
559
  backgroundImage: `url(${sanitizedBlurURL})`,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qzsy/vinext",
3
- "version": "0.1.7",
3
+ "version": "0.1.9",
4
4
  "description": "Run Next.js apps on Vite. Drop-in replacement for the next CLI.",
5
5
  "license": "MIT",
6
6
  "repository": {