vinext 1.2.1 → 1.3.0
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/README.md +12 -9
- package/dist/build/client-build-config.d.ts +64 -3
- package/dist/build/client-build-config.js +131 -4
- package/dist/build/client-reference-groups.d.ts +163 -0
- package/dist/build/client-reference-groups.js +534 -0
- package/dist/build/module-dependency-cache.d.ts +31 -0
- package/dist/build/module-dependency-cache.js +51 -1
- package/dist/build/next-client-runtime-manifests.d.ts +10 -1
- package/dist/build/next-client-runtime-manifests.js +19 -4
- package/dist/build/nitro-public-files.d.ts +24 -0
- package/dist/build/nitro-public-files.js +60 -0
- package/dist/build/pages-client-assets-module.js +1 -1
- package/dist/build/prerender-paths.js +5 -2
- package/dist/build/server-actions-encryption-key.d.ts +23 -0
- package/dist/build/server-actions-encryption-key.js +101 -0
- package/dist/build/ssr-manifest.d.ts +3 -0
- package/dist/build/ssr-manifest.js +10 -1
- package/dist/client/client-rewrite-params.d.ts +9 -0
- package/dist/client/client-rewrite-params.js +20 -0
- package/dist/client/dev-error-overlay.js +2 -1
- package/dist/client/navigation-runtime.d.ts +25 -2
- package/dist/client/navigation-runtime.js +42 -11
- package/dist/client/vinext-next-data.d.ts +0 -1
- package/dist/config/config-matchers.d.ts +15 -40
- package/dist/config/config-matchers.js +183 -255
- package/dist/config/config-source.d.ts +34 -0
- package/dist/config/config-source.js +141 -0
- package/dist/config/header-params.d.ts +29 -0
- package/dist/config/header-params.js +106 -0
- package/dist/config/next-config.d.ts +7 -5
- package/dist/config/next-config.js +120 -7
- package/dist/entries/app-browser-entry.d.ts +14 -1
- package/dist/entries/app-browser-entry.js +26 -36
- package/dist/entries/app-rsc-entry.d.ts +2 -0
- package/dist/entries/app-rsc-entry.js +92 -57
- package/dist/entries/app-rsc-manifest.d.ts +10 -0
- package/dist/entries/app-rsc-manifest.js +20 -1
- package/dist/entries/app-ssr-entry.d.ts +4 -1
- package/dist/entries/app-ssr-entry.js +9 -2
- package/dist/entries/pages-client-entry.d.ts +1 -0
- package/dist/entries/pages-client-entry.js +6 -6
- package/dist/entries/pages-server-entry.js +17 -14
- package/dist/index.d.ts +11 -0
- package/dist/index.js +239 -83
- package/dist/init.js +17 -0
- package/dist/plugins/optimize-imports.d.ts +25 -2
- package/dist/plugins/optimize-imports.js +106 -20
- package/dist/plugins/rsc-client-reference-loaders.d.ts +45 -1
- package/dist/plugins/rsc-client-reference-loaders.js +336 -18
- package/dist/plugins/use-cache-callable.d.ts +5 -0
- package/dist/plugins/use-cache-callable.js +30 -8
- package/dist/plugins/worker-image-imports.d.ts +1 -0
- package/dist/plugins/worker-image-imports.js +1 -1
- package/dist/routing/app-route-graph.d.ts +1 -1
- package/dist/routing/browser-route-manifest.d.ts +43 -0
- package/dist/routing/browser-route-manifest.js +195 -0
- package/dist/routing/hashed-route-patterns.d.ts +4 -0
- package/dist/routing/hashed-route-patterns.js +22 -0
- package/dist/routing/optimistic-route-trie.d.ts +27 -0
- package/dist/routing/optimistic-route-trie.js +102 -0
- package/dist/routing/route-validation.d.ts +6 -1
- package/dist/routing/route-validation.js +26 -10
- package/dist/server/app-action-forwarding.d.ts +8 -0
- package/dist/server/app-action-forwarding.js +15 -1
- package/dist/server/app-browser-entry.js +147 -60
- package/dist/server/app-browser-error.d.ts +3 -1
- package/dist/server/app-browser-error.js +7 -2
- package/dist/server/app-browser-interception-context.d.ts +2 -2
- package/dist/server/app-browser-mpa-navigation.d.ts +1 -0
- package/dist/server/app-browser-mpa-navigation.js +6 -5
- package/dist/server/app-browser-navigation-controller.d.ts +17 -6
- package/dist/server/app-browser-navigation-controller.js +88 -26
- package/dist/server/app-browser-state.d.ts +2 -2
- package/dist/server/app-browser-visible-commit.d.ts +4 -4
- package/dist/server/app-client-reference-preloader.d.ts +23 -0
- package/dist/server/app-client-reference-preloader.js +30 -7
- package/dist/server/app-fallback-renderer.js +2 -1
- package/dist/server/app-middleware.d.ts +6 -0
- package/dist/server/app-middleware.js +8 -10
- package/dist/server/app-optimistic-routing.d.ts +8 -10
- package/dist/server/app-optimistic-routing.js +4 -95
- package/dist/server/app-page-boundary-render.js +8 -1
- package/dist/server/app-page-cache-render.js +1 -0
- package/dist/server/app-page-dispatch.js +2 -0
- package/dist/server/app-page-render.js +3 -1
- package/dist/server/app-page-rsc-render-status.d.ts +1 -0
- package/dist/server/app-page-rsc-render-status.js +1 -0
- package/dist/server/app-page-search-params-observation.d.ts +1 -4
- package/dist/server/app-page-search-params-observation.js +8 -10
- package/dist/server/app-page-stream.d.ts +7 -0
- package/dist/server/app-page-stream.js +1 -0
- package/dist/server/app-pages-bridge.d.ts +2 -1
- package/dist/server/app-pages-bridge.js +11 -7
- package/dist/server/app-prerender-static-params.js +3 -2
- package/dist/server/app-render-dependency.js +42 -2
- package/dist/server/app-request-stage-independent-entry.js +2 -2
- package/dist/server/app-response-stage-entry.js +3 -3
- package/dist/server/app-route-handler-dispatch.js +3 -1
- package/dist/server/app-route-handler-execution.d.ts +2 -0
- package/dist/server/app-route-handler-execution.js +9 -2
- package/dist/server/app-route-handler-middleware-context.d.ts +2 -1
- package/dist/server/app-route-handler-middleware-context.js +3 -3
- package/dist/server/app-route-handler-response.d.ts +2 -1
- package/dist/server/app-route-handler-response.js +2 -2
- package/dist/server/app-route-handler-runtime.d.ts +2 -0
- package/dist/server/app-route-handler-runtime.js +20 -3
- package/dist/server/app-route-module-loader.js +7 -6
- package/dist/server/app-route-tree.d.ts +20 -0
- package/dist/server/app-route-tree.js +18 -0
- package/dist/server/app-router-entry.js +2 -2
- package/dist/server/app-rsc-combined-handler.js +8 -1
- package/dist/server/app-rsc-errors.d.ts +7 -0
- package/dist/server/app-rsc-errors.js +9 -2
- package/dist/server/app-rsc-handler.d.ts +4 -1
- package/dist/server/app-rsc-handler.js +146 -130
- package/dist/server/app-rsc-response-finalizer.d.ts +5 -0
- package/dist/server/app-rsc-response-finalizer.js +4 -1
- package/dist/server/app-rsc-response-stage.js +3 -1
- package/dist/server/app-rsc-route-matching.d.ts +1 -0
- package/dist/server/app-rsc-route-matching.js +1 -1
- package/dist/server/app-server-action-execution.d.ts +23 -6
- package/dist/server/app-server-action-execution.js +50 -56
- package/dist/server/app-ssr-entry.d.ts +6 -0
- package/dist/server/app-ssr-entry.js +16 -7
- package/dist/server/app-ssr-stream.d.ts +7 -0
- package/dist/server/app-ssr-stream.js +13 -1
- package/dist/server/config-headers.js +12 -3
- package/dist/server/isolate-shared-promise.d.ts +10 -0
- package/dist/server/isolate-shared-promise.js +33 -0
- package/dist/server/isr-cache.js +3 -2
- package/dist/server/middleware-matcher-pattern.d.ts +0 -1
- package/dist/server/middleware-matcher-pattern.js +11 -140
- package/dist/server/middleware-matcher.js +5 -6
- package/dist/server/middleware-response-headers.d.ts +31 -0
- package/dist/server/middleware-response-headers.js +57 -1
- package/dist/server/middleware-runtime.js +26 -13
- package/dist/server/navigation-planner.d.ts +2 -2
- package/dist/server/nitro-public-files-plugin.d.ts +38 -0
- package/dist/server/nitro-public-files-plugin.js +106 -0
- package/dist/server/nitro-public-files.d.ts +21 -0
- package/dist/server/nitro-public-files.js +39 -0
- package/dist/server/pages-asset-tags.d.ts +5 -0
- package/dist/server/pages-asset-tags.js +9 -2
- package/dist/server/pages-client-assets.d.ts +4 -1
- package/dist/server/pages-i18n.d.ts +18 -0
- package/dist/server/pages-i18n.js +18 -2
- package/dist/server/pages-node-compat.d.ts +5 -3
- package/dist/server/pages-node-compat.js +35 -16
- package/dist/server/pages-request-pipeline.d.ts +6 -1
- package/dist/server/pages-request-pipeline.js +31 -35
- package/dist/server/pages-request-stage-entry.js +16 -6
- package/dist/server/pages-response-stage-entry.js +1 -1
- package/dist/server/pages-revalidate.js +1 -0
- package/dist/server/pages-router-entry.js +1 -1
- package/dist/server/prod-server.d.ts +2 -2
- package/dist/server/prod-server.js +71 -33
- package/dist/server/proxy-trust.d.ts +6 -0
- package/dist/server/proxy-trust.js +12 -6
- package/dist/server/request-pipeline.d.ts +5 -0
- package/dist/server/request-pipeline.js +12 -1
- package/dist/server/server-reference-loader.js +10 -1
- package/dist/server/static-file-cache.js +15 -3
- package/dist/server/worker-utils.js +1 -1
- package/dist/shims/cache-handler.js +3 -2
- package/dist/shims/cache-request-state.d.ts +40 -3
- package/dist/shims/cache-request-state.js +70 -5
- package/dist/shims/cache-runtime.js +47 -19
- package/dist/shims/cache.d.ts +2 -2
- package/dist/shims/cache.js +17 -8
- package/dist/shims/cdn-purge-routes.d.ts +24 -0
- package/dist/shims/cdn-purge-routes.js +77 -0
- package/dist/shims/dynamic.js +17 -4
- package/dist/shims/form.js +8 -3
- package/dist/shims/image-props.d.ts +93 -0
- package/dist/shims/image-props.js +323 -0
- package/dist/shims/image.d.ts +4 -18
- package/dist/shims/image.js +4 -319
- package/dist/shims/internal/headers-state.d.ts +7 -0
- package/dist/shims/internal/headers-state.js +14 -2
- package/dist/shims/internal/hybrid-client-route-owner-direct.d.ts +4 -1
- package/dist/shims/internal/hybrid-client-route-owner-direct.js +31 -14
- package/dist/shims/internal/hybrid-client-route-owner.js +8 -8
- package/dist/shims/link.js +5 -3
- package/dist/shims/navigation.d.ts +1 -1
- package/dist/shims/navigation.js +17 -5
- package/dist/shims/og.js +35 -10
- package/dist/shims/request-context.d.ts +13 -0
- package/dist/shims/router.js +19 -40
- package/dist/shims/server.d.ts +31 -4
- package/dist/shims/server.js +58 -10
- package/dist/shims/thenable-params.d.ts +6 -1
- package/dist/shims/thenable-params.js +11 -2
- package/dist/shims/unified-request-context.d.ts +5 -0
- package/dist/shims/unified-request-context.js +2 -0
- package/dist/utils/asset-prefix.d.ts +7 -0
- package/dist/utils/asset-prefix.js +10 -1
- package/dist/utils/client-build-manifest.js +12 -5
- package/dist/utils/client-runtime-metadata.d.ts +1 -0
- package/dist/utils/client-runtime-metadata.js +15 -2
- package/dist/utils/lazy-chunks.d.ts +4 -0
- package/dist/utils/manifest-paths.d.ts +14 -0
- package/dist/utils/manifest-paths.js +22 -1
- package/dist/utils/path-to-regexp.d.ts +21 -0
- package/dist/{server/middleware-path-to-regexp.js → utils/path-to-regexp.js} +14 -11
- package/dist/utils/plugin-react-version.d.ts +15 -0
- package/dist/utils/plugin-react-version.js +64 -0
- package/dist/utils/public-routes.d.ts +2 -0
- package/dist/utils/public-routes.js +18 -7
- package/package.json +1 -1
- package/dist/server/middleware-path-to-regexp.d.ts +0 -13
- package/dist/utils/regex-safety.d.ts +0 -17
- package/dist/utils/regex-safety.js +0 -789
package/dist/init.js
CHANGED
|
@@ -2,6 +2,7 @@ import path, { toSlash } from "./deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/
|
|
|
2
2
|
import { detectPackageManager, detectPackageManagerName, detectProject, ensureESModule, findViteConfigPath, hasViteConfig, renameCJSConfigs } from "./utils/project.js";
|
|
3
3
|
import { compactResourceName, cssModulesConfigSource, findConfigKeepingWorkerName, setupCloudflarePlatform, updateViteConfigForCssModules, usesCommonJsViteConfig, validateCloudflarePlatformSetup } from "./init-cloudflare.js";
|
|
4
4
|
import { getReactUpgradeDeps } from "./utils/react-version.js";
|
|
5
|
+
import { getPluginReactUpgradeDeps } from "./utils/plugin-react-version.js";
|
|
5
6
|
import fs from "node:fs";
|
|
6
7
|
import { spawn, spawnSync } from "node:child_process";
|
|
7
8
|
//#region src/init.ts
|
|
@@ -598,6 +599,22 @@ async function init(options) {
|
|
|
598
599
|
}
|
|
599
600
|
}
|
|
600
601
|
}
|
|
602
|
+
const pluginReactUpgrade = getPluginReactUpgradeDeps(root);
|
|
603
|
+
if (pluginReactUpgrade.length > 0) {
|
|
604
|
+
console.log(` ${terminalStyle.cyan(terminalStyle.bold("Upgrading devDependencies:"))}`);
|
|
605
|
+
console.log(formatList(pluginReactUpgrade.map((dep) => dep.replace(/@latest$/, "")), " "));
|
|
606
|
+
try {
|
|
607
|
+
if (shouldInstall) {
|
|
608
|
+
if (isApproveBuildsError(await installDeps(root, pluginReactUpgrade, exec))) dependencyInstallNeedsApproval = true;
|
|
609
|
+
} else {
|
|
610
|
+
const added = addDependencyEntries(root, pluginReactUpgrade, { dev: true });
|
|
611
|
+
devDependencyEntriesAdded.push(...added);
|
|
612
|
+
}
|
|
613
|
+
} catch (error) {
|
|
614
|
+
if (pmName !== "pnpm" || !isApproveBuildsError(error)) throw error;
|
|
615
|
+
dependencyInstallNeedsApproval = true;
|
|
616
|
+
}
|
|
617
|
+
}
|
|
601
618
|
if (missingDependencies.length > 0) {
|
|
602
619
|
console.log(` ${terminalStyle.cyan(terminalStyle.bold("Installing dependencies:"))}`);
|
|
603
620
|
console.log(formatList(missingDependencies, " "));
|
|
@@ -5,16 +5,39 @@ type BarrelExportEntry = {
|
|
|
5
5
|
source: string;
|
|
6
6
|
isNamespace: boolean;
|
|
7
7
|
originalName?: string;
|
|
8
|
+
/**
|
|
9
|
+
* The outermost module on the way to `source` that RSC replaces with
|
|
10
|
+
* references or wrappers because of its directive. RSC must import the name
|
|
11
|
+
* from it instead.
|
|
12
|
+
*/
|
|
13
|
+
rscBoundary?: string;
|
|
14
|
+
/**
|
|
15
|
+
* The same for SSR, where only "use server" and "use cache" modules are
|
|
16
|
+
* replaced with references.
|
|
17
|
+
*/
|
|
18
|
+
ssrBoundary?: string;
|
|
8
19
|
};
|
|
9
20
|
type BarrelExportMap = Map<string, BarrelExportEntry>;
|
|
10
21
|
/**
|
|
11
22
|
* Packages whose barrel imports are automatically optimized.
|
|
12
23
|
* Matches Next.js's built-in optimizePackageImports defaults plus vinext-specific
|
|
13
|
-
* compatibility entries for radix-ui
|
|
24
|
+
* compatibility entries for radix-ui, @chakra-ui/react, and @heroui/react.
|
|
14
25
|
* @see https://github.com/vercel/next.js/blob/9c31bbdaa/packages/next/src/server/config.ts#L1301
|
|
15
26
|
*/
|
|
16
27
|
export declare const DEFAULT_OPTIMIZE_PACKAGES: string[];
|
|
17
|
-
|
|
28
|
+
/**
|
|
29
|
+
* Packages whose subpath imports (`pkg/Sub`) are also optimized, in the RSC
|
|
30
|
+
* environment only. Their subpath entries are themselves barrels: heroui's
|
|
31
|
+
* Toast imports `UNSTABLE_ToastQueue` from "react-aria-components/Toast", whose
|
|
32
|
+
* other exports call createContext() at module scope and import "client-only"
|
|
33
|
+
* (https://github.com/cloudflare/vinext/issues/4007). Like Next.js's default
|
|
34
|
+
* Turbopack build, this drops the side-effect-free entry's "client-only"
|
|
35
|
+
* import: server-safe exports work, and client components still fail when
|
|
36
|
+
* their own modules are evaluated. SSR and the client keep the package's own
|
|
37
|
+
* module graph, so context modules are never instantiated twice there.
|
|
38
|
+
*/
|
|
39
|
+
export declare const SUBPATH_OPTIMIZE_PACKAGES: string[];
|
|
40
|
+
export declare function createOptimizedImportSourceMatcher(packages: Iterable<string>, subpathPackages?: Iterable<string>): (code: string) => boolean;
|
|
18
41
|
/**
|
|
19
42
|
* Build a map of exported names → source sub-module for a barrel package.
|
|
20
43
|
*
|
|
@@ -21,7 +21,7 @@ async function readFileSafe(filepath) {
|
|
|
21
21
|
/**
|
|
22
22
|
* Packages whose barrel imports are automatically optimized.
|
|
23
23
|
* Matches Next.js's built-in optimizePackageImports defaults plus vinext-specific
|
|
24
|
-
* compatibility entries for radix-ui
|
|
24
|
+
* compatibility entries for radix-ui, @chakra-ui/react, and @heroui/react.
|
|
25
25
|
* @see https://github.com/vercel/next.js/blob/9c31bbdaa/packages/next/src/server/config.ts#L1301
|
|
26
26
|
*/
|
|
27
27
|
const DEFAULT_OPTIMIZE_PACKAGES = [
|
|
@@ -101,10 +101,40 @@ const DEFAULT_OPTIMIZE_PACKAGES = [
|
|
|
101
101
|
"react-icons/ti",
|
|
102
102
|
"react-icons/vsc",
|
|
103
103
|
"react-icons/wi",
|
|
104
|
-
"radix-ui"
|
|
104
|
+
"radix-ui",
|
|
105
|
+
"@heroui/react"
|
|
105
106
|
];
|
|
106
|
-
|
|
107
|
-
|
|
107
|
+
/**
|
|
108
|
+
* Packages whose subpath imports (`pkg/Sub`) are also optimized, in the RSC
|
|
109
|
+
* environment only. Their subpath entries are themselves barrels: heroui's
|
|
110
|
+
* Toast imports `UNSTABLE_ToastQueue` from "react-aria-components/Toast", whose
|
|
111
|
+
* other exports call createContext() at module scope and import "client-only"
|
|
112
|
+
* (https://github.com/cloudflare/vinext/issues/4007). Like Next.js's default
|
|
113
|
+
* Turbopack build, this drops the side-effect-free entry's "client-only"
|
|
114
|
+
* import: server-safe exports work, and client components still fail when
|
|
115
|
+
* their own modules are evaluated. SSR and the client keep the package's own
|
|
116
|
+
* module graph, so context modules are never instantiated twice there.
|
|
117
|
+
*/
|
|
118
|
+
const SUBPATH_OPTIMIZE_PACKAGES = ["react-aria-components"];
|
|
119
|
+
function isOptimizedSubpath(source, subpathPackages) {
|
|
120
|
+
for (const pkg of subpathPackages) if (source.length > pkg.length + 1 && source.startsWith(`${pkg}/`)) return true;
|
|
121
|
+
return false;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Return the directive that marks a module as an RSC boundary, if any.
|
|
125
|
+
* Re-exports must not be followed through such a module: importing its leaves
|
|
126
|
+
* directly would bypass the client reference, server reference, or cache wrapper.
|
|
127
|
+
*/
|
|
128
|
+
function findBoundaryDirective(ast) {
|
|
129
|
+
for (const statement of ast.body) {
|
|
130
|
+
if (statement.type !== "ExpressionStatement" || typeof statement.directive !== "string") return null;
|
|
131
|
+
const directive = statement.directive;
|
|
132
|
+
if (directive === "use client" || directive === "use server" || directive.startsWith("use cache")) return directive;
|
|
133
|
+
}
|
|
134
|
+
return null;
|
|
135
|
+
}
|
|
136
|
+
function createOptimizedImportSourceMatcher(packages, subpathPackages = []) {
|
|
137
|
+
const pattern = [...[...packages].map(escapeRegExp), ...[...subpathPackages].map((pkg) => String.raw`${escapeRegExp(pkg)}/[^"'\s]+`)].join("|");
|
|
108
138
|
if (!pattern) return () => false;
|
|
109
139
|
const importFromPattern = new RegExp(String.raw`(?:^|[;}\n\r])\s*import(?!\s*\()(?:(?!\bfrom\b)[\s\S])*?\bfrom\s*["'](?:${pattern})["']`, "m");
|
|
110
140
|
const quotedSourcePattern = new RegExp(String.raw`["'](?:${pattern})["']`);
|
|
@@ -238,6 +268,7 @@ async function buildExportMapFromFile(filePath, readFile, cache, visited, initia
|
|
|
238
268
|
return /* @__PURE__ */ new Map();
|
|
239
269
|
}
|
|
240
270
|
const exportMap = /* @__PURE__ */ new Map();
|
|
271
|
+
const boundaryDirective = findBoundaryDirective(ast);
|
|
241
272
|
const importBindings = /* @__PURE__ */ new Map();
|
|
242
273
|
const localDeclarations = /* @__PURE__ */ new Set();
|
|
243
274
|
const fileDir = path.dirname(filePath);
|
|
@@ -379,6 +410,14 @@ async function buildExportMapFromFile(filePath, readFile, cache, visited, initia
|
|
|
379
410
|
break;
|
|
380
411
|
}
|
|
381
412
|
}
|
|
413
|
+
if (boundaryDirective) {
|
|
414
|
+
const isSsrBoundary = boundaryDirective !== "use client";
|
|
415
|
+
for (const [name, entry] of exportMap) exportMap.set(name, {
|
|
416
|
+
...entry,
|
|
417
|
+
rscBoundary: filePath,
|
|
418
|
+
ssrBoundary: isSsrBoundary ? filePath : entry.ssrBoundary
|
|
419
|
+
});
|
|
420
|
+
}
|
|
382
421
|
cache.set(filePath, exportMap);
|
|
383
422
|
return exportMap;
|
|
384
423
|
}
|
|
@@ -407,6 +446,15 @@ async function buildBarrelExportMap(entryPath, readFile, cache) {
|
|
|
407
446
|
return await buildExportMapFromFile(entryPath, readFile, exportMapCache, /* @__PURE__ */ new Set(), content);
|
|
408
447
|
}
|
|
409
448
|
/**
|
|
449
|
+
* Resolve a specifier with Vite's resolver, returning the id only when it is a
|
|
450
|
+
* file in the module graph (not external or virtual).
|
|
451
|
+
*/
|
|
452
|
+
async function resolveFileId(ctx, source, importer) {
|
|
453
|
+
const resolved = await ctx.resolve(source, importer, { skipSelf: true });
|
|
454
|
+
if (!resolved || resolved.external || !path.isAbsolute(resolved.id)) return null;
|
|
455
|
+
return resolved.id;
|
|
456
|
+
}
|
|
457
|
+
/**
|
|
410
458
|
* Creates the vinext:optimize-imports Vite plugin.
|
|
411
459
|
*
|
|
412
460
|
* @param nextConfig - Resolved Next.js config (may be undefined before config hook runs).
|
|
@@ -420,6 +468,7 @@ function createOptimizeImportsPlugin(getNextConfig, getRoot) {
|
|
|
420
468
|
const entryPathCache = /* @__PURE__ */ new Map();
|
|
421
469
|
let optimizedPackages = /* @__PURE__ */ new Set();
|
|
422
470
|
let hasOptimizedImportSource = () => false;
|
|
471
|
+
let hasOptimizedRscImportSource = () => false;
|
|
423
472
|
const registeredBarrels = /* @__PURE__ */ new Set();
|
|
424
473
|
return {
|
|
425
474
|
name: "vinext:optimize-imports",
|
|
@@ -427,6 +476,7 @@ function createOptimizeImportsPlugin(getNextConfig, getRoot) {
|
|
|
427
476
|
const nextConfig = getNextConfig();
|
|
428
477
|
optimizedPackages = /* @__PURE__ */ new Set([...DEFAULT_OPTIMIZE_PACKAGES, ...nextConfig?.optimizePackageImports ?? []]);
|
|
429
478
|
hasOptimizedImportSource = createOptimizedImportSourceMatcher(optimizedPackages);
|
|
479
|
+
hasOptimizedRscImportSource = createOptimizedImportSourceMatcher(optimizedPackages, SUBPATH_OPTIMIZE_PACKAGES);
|
|
430
480
|
entryPathCache.clear();
|
|
431
481
|
barrelCaches.exportMapCache.clear();
|
|
432
482
|
barrelCaches.subpkgOrigin.clear();
|
|
@@ -434,56 +484,77 @@ function createOptimizeImportsPlugin(getNextConfig, getRoot) {
|
|
|
434
484
|
},
|
|
435
485
|
async resolveId(source) {
|
|
436
486
|
if (this.environment?.name === "client") return;
|
|
437
|
-
const
|
|
438
|
-
const barrelEntry = barrelCaches.subpkgOrigin.get(
|
|
487
|
+
const envKey = this.environment?.name === "rsc" ? "rsc" : "ssr";
|
|
488
|
+
const barrelEntry = barrelCaches.subpkgOrigin.get(envKey)?.get(source);
|
|
439
489
|
if (!barrelEntry) return;
|
|
440
490
|
return await this.resolve(source, barrelEntry, { skipSelf: true }) ?? void 0;
|
|
441
491
|
},
|
|
442
492
|
transform: {
|
|
443
493
|
filter: {
|
|
444
494
|
id: {
|
|
445
|
-
include: /\.(tsx?|jsx?|mjs)
|
|
495
|
+
include: /\.(tsx?|jsx?|mjs)(?:\?v=\w+)?$/,
|
|
446
496
|
exclude: VIRTUAL_MODULE_ID_RE
|
|
447
497
|
},
|
|
448
498
|
code: /\bimport\b[\s\S]*\bfrom\b/
|
|
449
499
|
},
|
|
450
|
-
async handler(code) {
|
|
500
|
+
async handler(code, id) {
|
|
451
501
|
const env = this.environment;
|
|
452
502
|
if (env?.name === "client") return null;
|
|
453
503
|
const preferReactServer = env?.name === "rsc";
|
|
454
504
|
const packages = optimizedPackages;
|
|
455
|
-
if (!hasOptimizedImportSource(code)) return null;
|
|
505
|
+
if (!(preferReactServer ? hasOptimizedRscImportSource : hasOptimizedImportSource)(code)) return null;
|
|
456
506
|
let ast;
|
|
457
507
|
try {
|
|
458
508
|
ast = parseProgram(code);
|
|
459
509
|
} catch {
|
|
460
510
|
return null;
|
|
461
511
|
}
|
|
512
|
+
if (preferReactServer && findBoundaryDirective(ast) === "use client") return null;
|
|
462
513
|
const s = new MagicString(code);
|
|
463
514
|
let hasChanges = false;
|
|
464
515
|
const root = getRoot();
|
|
465
516
|
for (const node of ast.body) {
|
|
466
517
|
if (node.type !== "ImportDeclaration") continue;
|
|
467
518
|
const importSource = typeof node.source?.value === "string" ? node.source.value : null;
|
|
468
|
-
if (!importSource
|
|
469
|
-
const
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
519
|
+
if (!importSource) continue;
|
|
520
|
+
const isSubpath = !packages.has(importSource) && preferReactServer && isOptimizedSubpath(importSource, SUBPATH_OPTIMIZE_PACKAGES);
|
|
521
|
+
if (!isSubpath && !packages.has(importSource)) continue;
|
|
522
|
+
let barrelEntry;
|
|
523
|
+
if (isSubpath) {
|
|
524
|
+
barrelEntry = await resolveFileId(this, importSource, id);
|
|
525
|
+
if (barrelEntry) barrelEntry = barrelEntry.replace(/\?.*$/, "");
|
|
526
|
+
} else {
|
|
527
|
+
const cacheKey = `${preferReactServer ? "rsc" : "ssr"}:${importSource}`;
|
|
528
|
+
barrelEntry = entryPathCache.get(cacheKey);
|
|
529
|
+
if (barrelEntry === void 0) {
|
|
530
|
+
barrelEntry = await resolvePackageEntry(importSource, root, preferReactServer);
|
|
531
|
+
entryPathCache.set(cacheKey, barrelEntry ?? null);
|
|
532
|
+
}
|
|
474
533
|
}
|
|
475
534
|
const exportMap = await buildBarrelExportMap(barrelEntry, readFileSafe, barrelCaches.exportMapCache);
|
|
476
535
|
if (!exportMap || !barrelEntry) continue;
|
|
536
|
+
const getEntry = (name) => {
|
|
537
|
+
const entry = exportMap.get(name);
|
|
538
|
+
const boundary = preferReactServer ? entry?.rscBoundary : entry?.ssrBoundary;
|
|
539
|
+
return boundary ? {
|
|
540
|
+
source: boundary,
|
|
541
|
+
isNamespace: false,
|
|
542
|
+
originalName: name
|
|
543
|
+
} : entry;
|
|
544
|
+
};
|
|
477
545
|
const envKey = preferReactServer ? "rsc" : "ssr";
|
|
478
546
|
const registeredKey = `${envKey}:${barrelEntry}`;
|
|
479
|
-
if (!registeredBarrels.has(registeredKey)) {
|
|
547
|
+
if (!isSubpath && !registeredBarrels.has(registeredKey)) {
|
|
480
548
|
registeredBarrels.add(registeredKey);
|
|
481
549
|
let envOriginMap = barrelCaches.subpkgOrigin.get(envKey);
|
|
482
550
|
if (!envOriginMap) {
|
|
483
551
|
envOriginMap = /* @__PURE__ */ new Map();
|
|
484
552
|
barrelCaches.subpkgOrigin.set(envKey, envOriginMap);
|
|
485
553
|
}
|
|
486
|
-
for (const
|
|
554
|
+
for (const name of exportMap.keys()) {
|
|
555
|
+
const source = getEntry(name).source;
|
|
556
|
+
if (!source.startsWith("/") && !source.startsWith(".") && !envOriginMap.has(source)) envOriginMap.set(source, barrelEntry);
|
|
557
|
+
}
|
|
487
558
|
}
|
|
488
559
|
const specifiers = [];
|
|
489
560
|
let allResolved = true;
|
|
@@ -528,11 +599,26 @@ function createOptimizeImportsPlugin(getNextConfig, getRoot) {
|
|
|
528
599
|
}
|
|
529
600
|
continue;
|
|
530
601
|
}
|
|
602
|
+
if (isSubpath && specifiers.every(({ imported }) => getEntry(imported)?.source === barrelEntry)) continue;
|
|
603
|
+
const resolvedPackageSources = /* @__PURE__ */ new Map();
|
|
604
|
+
if (isSubpath) {
|
|
605
|
+
for (const { imported } of specifiers) {
|
|
606
|
+
const source = getEntry(imported)?.source;
|
|
607
|
+
if (!source || path.isAbsolute(source) || resolvedPackageSources.has(source)) continue;
|
|
608
|
+
const resolvedId = await resolveFileId(this, source, barrelEntry);
|
|
609
|
+
if (!resolvedId) {
|
|
610
|
+
allResolved = false;
|
|
611
|
+
break;
|
|
612
|
+
}
|
|
613
|
+
resolvedPackageSources.set(source, resolvedId);
|
|
614
|
+
}
|
|
615
|
+
if (!allResolved) continue;
|
|
616
|
+
}
|
|
531
617
|
const bySource = /* @__PURE__ */ new Map();
|
|
532
618
|
for (const { local, imported } of specifiers) {
|
|
533
|
-
const entry =
|
|
619
|
+
const entry = getEntry(imported);
|
|
534
620
|
if (!entry) continue;
|
|
535
|
-
const resolvedSource = entry.source;
|
|
621
|
+
const resolvedSource = resolvedPackageSources.get(entry.source) ?? entry.source;
|
|
536
622
|
const key = `${resolvedSource}::${entry.isNamespace}`;
|
|
537
623
|
let group = bySource.get(key);
|
|
538
624
|
if (!group) {
|
|
@@ -569,4 +655,4 @@ function createOptimizeImportsPlugin(getNextConfig, getRoot) {
|
|
|
569
655
|
};
|
|
570
656
|
}
|
|
571
657
|
//#endregion
|
|
572
|
-
export { DEFAULT_OPTIMIZE_PACKAGES, buildBarrelExportMap, createOptimizeImportsPlugin, createOptimizedImportSourceMatcher };
|
|
658
|
+
export { DEFAULT_OPTIMIZE_PACKAGES, SUBPATH_OPTIMIZE_PACKAGES, buildBarrelExportMap, createOptimizeImportsPlugin, createOptimizedImportSourceMatcher };
|
|
@@ -1,4 +1,48 @@
|
|
|
1
|
+
import { AppRoute } from "../routing/app-route-graph.js";
|
|
1
2
|
import { Plugin } from "vite";
|
|
2
3
|
//#region src/plugins/rsc-client-reference-loaders.d.ts
|
|
3
|
-
export
|
|
4
|
+
export type RscClientReferenceRouteOptions = {
|
|
5
|
+
/** Maps route file paths to the module ids used by the RSC module graph. */
|
|
6
|
+
canonicalizeModuleId: (id: string) => string;
|
|
7
|
+
/** App Router routes of the current build, or null outside App Router builds. */
|
|
8
|
+
getRoutes: () => readonly AppRoute[] | null;
|
|
9
|
+
/**
|
|
10
|
+
* Files any route's render can show: global-error, and the root boundaries
|
|
11
|
+
* that routes without their own not-found, forbidden or unauthorized use.
|
|
12
|
+
*/
|
|
13
|
+
getAlwaysRenderedFiles: () => readonly string[];
|
|
14
|
+
/**
|
|
15
|
+
* The files a render without a route (a route-miss 404) shows: the root
|
|
16
|
+
* layouts and boundaries, and global-not-found.
|
|
17
|
+
*/
|
|
18
|
+
getRoutelessFiles: () => readonly string[];
|
|
19
|
+
/** Route-independent roots such as global-error and global-not-found. */
|
|
20
|
+
getSharedRoots: () => readonly string[];
|
|
21
|
+
};
|
|
22
|
+
export type RscClientReferenceGroupingOptions = {
|
|
23
|
+
/** Modules that live in chunks every page loads anyway (React, vinext runtime). */
|
|
24
|
+
isAlwaysLoadedClientModule: (id: string) => boolean;
|
|
25
|
+
/** vinext's own client chunk groups. Any other chunk group disables grouping. */
|
|
26
|
+
ownClientChunkGroups: ReadonlySet<unknown>;
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Replaces @vitejs/plugin-rsc's client-reference facades with per-reference
|
|
30
|
+
* loaders. With `routes`, the SSR build also exports the client references
|
|
31
|
+
* each App Router route preloads. With `grouping`, production client builds
|
|
32
|
+
* additionally load references that the same App Router routes reach through
|
|
33
|
+
* one shared route group module (see build/client-reference-groups.ts), so a
|
|
34
|
+
* page fetches one chunk per route group instead of one per `"use client"`
|
|
35
|
+
* module.
|
|
36
|
+
*/
|
|
37
|
+
export declare function createRscClientReferenceLoadersPlugin(options?: {
|
|
38
|
+
routes?: RscClientReferenceRouteOptions;
|
|
39
|
+
grouping?: RscClientReferenceGroupingOptions;
|
|
40
|
+
}): Plugin;
|
|
41
|
+
/**
|
|
42
|
+
* Exports a null preload plan from the client-references virtual module when
|
|
43
|
+
* the app registers @vitejs/plugin-rsc itself (`rsc: false`), where vinext
|
|
44
|
+
* doesn't add the loaders plugin above. The App Router SSR entry imports the
|
|
45
|
+
* plan, and null makes it preload every client reference.
|
|
46
|
+
*/
|
|
47
|
+
export declare function createRouteClientReferencesFallbackPlugin(): Plugin;
|
|
4
48
|
//#endregion
|