vinext 0.1.6 → 0.1.8
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/build/client-build-config.d.ts +4 -6
- package/dist/build/client-build-config.js +27 -7
- package/dist/build/prerender.js +1 -2
- package/dist/check.d.ts +18 -0
- package/dist/check.js +37 -17
- package/dist/cli.js +2 -2
- package/dist/config/next-config.d.ts +2 -1
- package/dist/config/next-config.js +3 -0
- package/dist/config/server-external-packages.d.ts +4 -0
- package/dist/config/server-external-packages.js +91 -0
- package/dist/deploy.d.ts +7 -0
- package/dist/deploy.js +25 -18
- package/dist/entries/app-rsc-entry.d.ts +2 -1
- package/dist/entries/app-rsc-entry.js +89 -20
- package/dist/entries/app-rsc-manifest.js +8 -0
- package/dist/entries/pages-client-entry.js +1 -0
- package/dist/entries/pages-server-entry.js +1 -0
- package/dist/index.js +87 -34
- package/dist/init.js +2 -1
- package/dist/plugins/middleware-server-only.d.ts +8 -6
- package/dist/plugins/middleware-server-only.js +8 -7
- package/dist/plugins/og-assets.js +6 -6
- package/dist/plugins/optimize-imports.js +1 -1
- package/dist/plugins/remove-console.js +1 -1
- package/dist/plugins/strip-server-exports.js +2 -1
- package/dist/routing/app-route-graph.d.ts +6 -2
- package/dist/routing/app-route-graph.js +61 -13
- package/dist/routing/app-router.d.ts +5 -0
- package/dist/routing/app-router.js +5 -0
- package/dist/routing/file-matcher.d.ts +5 -0
- package/dist/routing/file-matcher.js +7 -1
- package/dist/server/app-action-request.d.ts +4 -0
- package/dist/server/app-action-request.js +9 -0
- package/dist/server/app-bfcache-identity.d.ts +12 -2
- package/dist/server/app-bfcache-identity.js +52 -23
- package/dist/server/app-browser-entry.js +42 -147
- package/dist/server/app-browser-history-controller.d.ts +2 -1
- package/dist/server/app-browser-history-controller.js +6 -2
- package/dist/server/app-browser-server-action-client.d.ts +32 -0
- package/dist/server/app-browser-server-action-client.js +128 -0
- package/dist/server/app-fallback-renderer.d.ts +3 -1
- package/dist/server/app-fallback-renderer.js +6 -2
- package/dist/server/app-history-state.d.ts +1 -2
- package/dist/server/app-history-state.js +1 -1
- package/dist/server/app-page-boundary-render.d.ts +3 -0
- package/dist/server/app-page-boundary-render.js +14 -3
- package/dist/server/app-page-cache-finalizer.d.ts +1 -0
- package/dist/server/app-page-cache-finalizer.js +8 -2
- package/dist/server/app-page-dispatch.d.ts +33 -4
- package/dist/server/app-page-dispatch.js +62 -90
- package/dist/server/app-page-element-builder.d.ts +7 -1
- package/dist/server/app-page-element-builder.js +56 -19
- package/dist/server/app-page-head.d.ts +16 -1
- package/dist/server/app-page-head.js +44 -22
- package/dist/server/app-page-method.js +1 -1
- package/dist/server/app-page-params.d.ts +2 -1
- package/dist/server/app-page-params.js +8 -1
- package/dist/server/app-page-ppr-runtime.d.ts +7 -0
- package/dist/server/app-page-ppr-runtime.js +70 -0
- package/dist/server/app-page-probe.d.ts +1 -0
- package/dist/server/app-page-probe.js +1 -1
- package/dist/server/app-page-render.d.ts +4 -1
- package/dist/server/app-page-render.js +8 -3
- package/dist/server/app-page-request.d.ts +8 -1
- package/dist/server/app-page-request.js +23 -11
- package/dist/server/app-page-route-wiring.d.ts +6 -1
- package/dist/server/app-page-route-wiring.js +30 -8
- package/dist/server/app-page-search-params-observation.d.ts +4 -2
- package/dist/server/app-page-search-params-observation.js +11 -7
- package/dist/server/app-page-stream.js +2 -1
- package/dist/server/app-ppr-fallback-shell-render.d.ts +4 -3
- package/dist/server/app-route-handler-cache.js +1 -1
- package/dist/server/app-route-handler-dispatch.js +3 -2
- package/dist/server/app-route-handler-execution.js +5 -3
- package/dist/server/app-route-handler-policy.d.ts +1 -1
- package/dist/server/app-route-handler-policy.js +1 -6
- package/dist/server/app-route-module-loader.d.ts +2 -0
- package/dist/server/app-route-module-loader.js +1 -0
- package/dist/server/app-router-entry.js +7 -6
- package/dist/server/app-rsc-errors.d.ts +12 -1
- package/dist/server/app-rsc-errors.js +29 -3
- package/dist/server/app-rsc-handler.d.ts +15 -13
- package/dist/server/app-rsc-handler.js +28 -33
- package/dist/server/app-rsc-response-finalizer.js +5 -1
- package/dist/server/app-rsc-route-matching.d.ts +7 -0
- package/dist/server/app-rsc-route-matching.js +36 -3
- package/dist/server/app-segment-config.d.ts +1 -0
- package/dist/server/app-segment-config.js +32 -2
- package/dist/server/app-server-action-execution.d.ts +4 -0
- package/dist/server/app-server-action-execution.js +42 -11
- package/dist/server/app-ssr-entry.js +11 -6
- package/dist/server/app-static-generation.d.ts +1 -0
- package/dist/server/app-static-generation.js +1 -0
- package/dist/server/headers.d.ts +3 -1
- package/dist/server/headers.js +3 -1
- package/dist/server/metadata-route-response.d.ts +1 -1
- package/dist/server/prod-server.js +15 -6
- package/dist/server/worker-utils.d.ts +2 -1
- package/dist/server/worker-utils.js +7 -1
- package/dist/shims/dynamic.js +1 -1
- package/dist/shims/error-boundary.d.ts +19 -1
- package/dist/shims/error-boundary.js +11 -1
- package/dist/shims/headers.d.ts +3 -1
- package/dist/shims/headers.js +16 -5
- package/dist/shims/link.js +16 -12
- package/dist/shims/metadata.d.ts +3 -2
- package/dist/shims/metadata.js +8 -4
- package/dist/shims/router.js +13 -2
- package/dist/typegen.js +6 -5
- package/dist/utils/path.d.ts +2 -1
- package/dist/utils/path.js +1 -1
- package/dist/utils/project.d.ts +4 -0
- package/dist/utils/project.js +5 -1
- package/package.json +7 -3
|
@@ -26,12 +26,10 @@ declare function createClientAssetFileNames(assetsDir: string): (assetInfo: Clie
|
|
|
26
26
|
*
|
|
27
27
|
* Splits the client bundle into:
|
|
28
28
|
* - "framework" — React, ReactDOM, and scheduler (loaded on every page)
|
|
29
|
-
* - "vinext" — vinext shims
|
|
29
|
+
* - "vinext" — shared vinext runtime shims
|
|
30
30
|
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
* common chunks based on the import graph — no manual intervention
|
|
34
|
-
* needed.
|
|
31
|
+
* Route-owned client shims and all other vendor code are left to the bundler's
|
|
32
|
+
* graph-based chunking so they stay behind their client-reference boundaries.
|
|
35
33
|
*
|
|
36
34
|
* Why not split every npm package into its own chunk?
|
|
37
35
|
* - Per-package splitting (`vendor-X`) creates 50-200+ chunks for a
|
|
@@ -48,7 +46,7 @@ declare function createClientAssetFileNames(assetsDir: string): (assetInfo: Clie
|
|
|
48
46
|
* well: shared dependencies between routes get their own chunks,
|
|
49
47
|
* and route-specific code stays in route chunks.
|
|
50
48
|
*/
|
|
51
|
-
declare function createClientManualChunks(shimsDir: string): (id: string) => string | undefined;
|
|
49
|
+
declare function createClientManualChunks(shimsDir: string, preserveRouteBoundaries?: boolean): (id: string) => string | undefined;
|
|
52
50
|
/**
|
|
53
51
|
* Rollup output config with manualChunks for client code-splitting.
|
|
54
52
|
* Used by both CLI builds and multi-environment builds.
|
|
@@ -1,4 +1,18 @@
|
|
|
1
1
|
//#region src/build/client-build-config.ts
|
|
2
|
+
const ROUTE_OWNED_CLIENT_SHIMS = new Set([
|
|
3
|
+
"compat-router",
|
|
4
|
+
"dynamic",
|
|
5
|
+
"dynamic-preload-chunks",
|
|
6
|
+
"form",
|
|
7
|
+
"image",
|
|
8
|
+
"layout-segment-context",
|
|
9
|
+
"legacy-image",
|
|
10
|
+
"link",
|
|
11
|
+
"offline",
|
|
12
|
+
"router",
|
|
13
|
+
"script",
|
|
14
|
+
"web-vitals"
|
|
15
|
+
]);
|
|
2
16
|
const NEXT_CLIENT_CSS_ASSET_FILE_NAMES = "css/[name].[hash:8][extname]";
|
|
3
17
|
const NEXT_CLIENT_STATIC_MEDIA_FILE_NAMES = "media/[name].[hash:8][extname]";
|
|
4
18
|
function joinAssetFileNamePattern(assetsDir, pattern) {
|
|
@@ -48,12 +62,10 @@ function getPackageName(id) {
|
|
|
48
62
|
*
|
|
49
63
|
* Splits the client bundle into:
|
|
50
64
|
* - "framework" — React, ReactDOM, and scheduler (loaded on every page)
|
|
51
|
-
* - "vinext" — vinext shims
|
|
65
|
+
* - "vinext" — shared vinext runtime shims
|
|
52
66
|
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
* common chunks based on the import graph — no manual intervention
|
|
56
|
-
* needed.
|
|
67
|
+
* Route-owned client shims and all other vendor code are left to the bundler's
|
|
68
|
+
* graph-based chunking so they stay behind their client-reference boundaries.
|
|
57
69
|
*
|
|
58
70
|
* Why not split every npm package into its own chunk?
|
|
59
71
|
* - Per-package splitting (`vendor-X`) creates 50-200+ chunks for a
|
|
@@ -70,7 +82,7 @@ function getPackageName(id) {
|
|
|
70
82
|
* well: shared dependencies between routes get their own chunks,
|
|
71
83
|
* and route-specific code stays in route chunks.
|
|
72
84
|
*/
|
|
73
|
-
function createClientManualChunks(shimsDir) {
|
|
85
|
+
function createClientManualChunks(shimsDir, preserveRouteBoundaries = false) {
|
|
74
86
|
return function clientManualChunks(id) {
|
|
75
87
|
if (id.includes("node_modules")) {
|
|
76
88
|
const pkg = getPackageName(id);
|
|
@@ -78,7 +90,15 @@ function createClientManualChunks(shimsDir) {
|
|
|
78
90
|
if (pkg === "react" || pkg === "react-dom" || pkg === "scheduler") return "framework";
|
|
79
91
|
return;
|
|
80
92
|
}
|
|
81
|
-
if (id.startsWith(shimsDir))
|
|
93
|
+
if (id.startsWith(shimsDir)) {
|
|
94
|
+
if (preserveRouteBoundaries) {
|
|
95
|
+
const relativeId = id.slice(shimsDir.length).split("?", 1)[0] ?? "";
|
|
96
|
+
const extensionIndex = relativeId.lastIndexOf(".");
|
|
97
|
+
const shimName = extensionIndex === -1 ? relativeId : relativeId.slice(0, extensionIndex);
|
|
98
|
+
if (ROUTE_OWNED_CLIENT_SHIMS.has(shimName)) return void 0;
|
|
99
|
+
}
|
|
100
|
+
return "vinext";
|
|
101
|
+
}
|
|
82
102
|
};
|
|
83
103
|
}
|
|
84
104
|
/**
|
package/dist/build/prerender.js
CHANGED
|
@@ -306,7 +306,6 @@ async function prerenderPages({ routes, apiRoutes, pagesDir, outDir, config, mod
|
|
|
306
306
|
for (const route of bundlePageRoutes) {
|
|
307
307
|
if (BLOCKED_PAGES.includes(route.pattern)) continue;
|
|
308
308
|
if (route.pattern === "/404") continue;
|
|
309
|
-
if (!routes.find((r) => r.filePath === route.filePath || r.pattern === route.pattern)) continue;
|
|
310
309
|
const { type, revalidate: classifiedRevalidate } = classifyPagesRoute(route.filePath);
|
|
311
310
|
if (type === "ssr") {
|
|
312
311
|
if (mode === "export") results.push({
|
|
@@ -648,7 +647,7 @@ async function prerenderApp({ routes, metadataRoutes = [], outDir, config, mode,
|
|
|
648
647
|
});
|
|
649
648
|
continue;
|
|
650
649
|
}
|
|
651
|
-
if (
|
|
650
|
+
if (paramSets.length === 0) {
|
|
652
651
|
results.push({
|
|
653
652
|
route: route.pattern,
|
|
654
653
|
status: "skipped",
|
package/dist/check.d.ts
CHANGED
|
@@ -59,22 +59,40 @@ type CheckResult = {
|
|
|
59
59
|
declare function hasFreeCjsGlobal(content: string): boolean;
|
|
60
60
|
/**
|
|
61
61
|
* Scan source files for `import ... from 'next/...'` statements.
|
|
62
|
+
*
|
|
63
|
+
* `root` must be forward-slash: it is passed to `findSourceFiles` (which
|
|
64
|
+
* requires it) and used as the base of `path.posix.relative`, which only yields
|
|
65
|
+
* a canonical relative path when both operands are forward-slash.
|
|
62
66
|
*/
|
|
63
67
|
declare function scanImports(root: string): CheckItem[];
|
|
64
68
|
/**
|
|
65
69
|
* Analyze next.config.js/mjs/ts for supported and unsupported options.
|
|
70
|
+
*
|
|
71
|
+
* `root` must be forward-slash — joined with `path.posix.join`. Only called
|
|
72
|
+
* from `runCheck`, which normalizes it.
|
|
66
73
|
*/
|
|
67
74
|
declare function analyzeConfig(root: string): CheckItem[];
|
|
68
75
|
/**
|
|
69
76
|
* Check package.json dependencies for known libraries.
|
|
77
|
+
*
|
|
78
|
+
* `root` must be forward-slash — joined with `path.posix.join`. Only called
|
|
79
|
+
* from `runCheck`, which normalizes it.
|
|
70
80
|
*/
|
|
71
81
|
declare function checkLibraries(root: string): CheckItem[];
|
|
72
82
|
/**
|
|
73
83
|
* Check file conventions (pages, app directory, middleware, etc.)
|
|
84
|
+
*
|
|
85
|
+
* `root` must be forward-slash — joined with `path.posix.join`, passed to
|
|
86
|
+
* `findDir`, and used as the base of `path.posix.relative`. Only called from
|
|
87
|
+
* `runCheck`, which normalizes it.
|
|
74
88
|
*/
|
|
75
89
|
declare function checkConventions(root: string): CheckItem[];
|
|
76
90
|
/**
|
|
77
91
|
* Run the full compatibility check.
|
|
92
|
+
*
|
|
93
|
+
* `root` must be forward-slash — callers normalize it at the CLI entry, and it
|
|
94
|
+
* is forwarded to `scanImports` / `checkConventions` / `findDir`, which build
|
|
95
|
+
* paths with `path.posix.*`.
|
|
78
96
|
*/
|
|
79
97
|
declare function runCheck(root: string): CheckResult;
|
|
80
98
|
/**
|
package/dist/check.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { detectPackageManager, findDir } from "./utils/project.js";
|
|
2
|
-
import { normalizePathSeparators } from "./utils/path.js";
|
|
3
2
|
import fs from "node:fs";
|
|
4
3
|
import path from "node:path";
|
|
5
4
|
import { parseAst } from "vite";
|
|
@@ -331,6 +330,11 @@ const LIBRARY_SUPPORT = {
|
|
|
331
330
|
};
|
|
332
331
|
/**
|
|
333
332
|
* Recursively find all source files in a directory.
|
|
333
|
+
*
|
|
334
|
+
* `dir` must be forward-slash, and the returned paths are forward-slash too:
|
|
335
|
+
* each entry is joined with `path.posix.join`, which only stays canonical when
|
|
336
|
+
* the base already is. This keeps downstream substring checks (e.g.
|
|
337
|
+
* `f.includes("/api/")`) and reported paths consistent across platforms.
|
|
334
338
|
*/
|
|
335
339
|
function findSourceFiles(dir, extensions = [
|
|
336
340
|
".ts",
|
|
@@ -343,7 +347,7 @@ function findSourceFiles(dir, extensions = [
|
|
|
343
347
|
if (!fs.existsSync(dir)) return results;
|
|
344
348
|
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
345
349
|
for (const entry of entries) {
|
|
346
|
-
const fullPath =
|
|
350
|
+
const fullPath = path.posix.join(dir, entry.name);
|
|
347
351
|
if (entry.isDirectory()) {
|
|
348
352
|
if (entry.name === "node_modules" || entry.name === ".next" || entry.name === "dist" || entry.name === ".git") continue;
|
|
349
353
|
results.push(...findSourceFiles(fullPath, extensions));
|
|
@@ -547,6 +551,10 @@ function hasFreeCjsGlobal(content) {
|
|
|
547
551
|
}
|
|
548
552
|
/**
|
|
549
553
|
* Scan source files for `import ... from 'next/...'` statements.
|
|
554
|
+
*
|
|
555
|
+
* `root` must be forward-slash: it is passed to `findSourceFiles` (which
|
|
556
|
+
* requires it) and used as the base of `path.posix.relative`, which only yields
|
|
557
|
+
* a canonical relative path when both operands are forward-slash.
|
|
550
558
|
*/
|
|
551
559
|
function scanImports(root) {
|
|
552
560
|
const files = findSourceFiles(root);
|
|
@@ -564,7 +572,7 @@ function scanImports(root) {
|
|
|
564
572
|
if (mod.startsWith("next/") || mod === "next" || mod === "server-only" || mod === "client-only") {
|
|
565
573
|
const normalized = mod === "next" ? "next" : mod;
|
|
566
574
|
if (!importUsage.has(normalized)) importUsage.set(normalized, []);
|
|
567
|
-
const relFile =
|
|
575
|
+
const relFile = path.posix.relative(root, file);
|
|
568
576
|
const usedInFiles = importUsage.get(normalized) ?? [];
|
|
569
577
|
if (!usedInFiles.includes(relFile)) usedInFiles.push(relFile);
|
|
570
578
|
}
|
|
@@ -691,6 +699,9 @@ function collectConfigKeys(source) {
|
|
|
691
699
|
}
|
|
692
700
|
/**
|
|
693
701
|
* Analyze next.config.js/mjs/ts for supported and unsupported options.
|
|
702
|
+
*
|
|
703
|
+
* `root` must be forward-slash — joined with `path.posix.join`. Only called
|
|
704
|
+
* from `runCheck`, which normalizes it.
|
|
694
705
|
*/
|
|
695
706
|
function analyzeConfig(root) {
|
|
696
707
|
const configFiles = [
|
|
@@ -702,7 +713,7 @@ function analyzeConfig(root) {
|
|
|
702
713
|
];
|
|
703
714
|
let configPath = null;
|
|
704
715
|
for (const f of configFiles) {
|
|
705
|
-
const p = path.join(root, f);
|
|
716
|
+
const p = path.posix.join(root, f);
|
|
706
717
|
if (fs.existsSync(p)) {
|
|
707
718
|
configPath = p;
|
|
708
719
|
break;
|
|
@@ -757,9 +768,12 @@ function analyzeConfig(root) {
|
|
|
757
768
|
}
|
|
758
769
|
/**
|
|
759
770
|
* Check package.json dependencies for known libraries.
|
|
771
|
+
*
|
|
772
|
+
* `root` must be forward-slash — joined with `path.posix.join`. Only called
|
|
773
|
+
* from `runCheck`, which normalizes it.
|
|
760
774
|
*/
|
|
761
775
|
function checkLibraries(root) {
|
|
762
|
-
const pkgPath = path.join(root, "package.json");
|
|
776
|
+
const pkgPath = path.posix.join(root, "package.json");
|
|
763
777
|
if (!fs.existsSync(pkgPath)) return [];
|
|
764
778
|
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
|
|
765
779
|
const allDeps = {
|
|
@@ -777,17 +791,19 @@ function checkLibraries(root) {
|
|
|
777
791
|
}
|
|
778
792
|
/**
|
|
779
793
|
* Check file conventions (pages, app directory, middleware, etc.)
|
|
794
|
+
*
|
|
795
|
+
* `root` must be forward-slash — joined with `path.posix.join`, passed to
|
|
796
|
+
* `findDir`, and used as the base of `path.posix.relative`. Only called from
|
|
797
|
+
* `runCheck`, which normalizes it.
|
|
780
798
|
*/
|
|
781
799
|
function checkConventions(root) {
|
|
782
800
|
const items = [];
|
|
783
|
-
const pagesDir = findDir(root, "pages",
|
|
784
|
-
const appDirPath = findDir(root, "app",
|
|
785
|
-
const
|
|
786
|
-
const
|
|
787
|
-
const hasProxy = fs.existsSync(path.join(root, "proxy.ts")) || fs.existsSync(path.join(root, "proxy.js"));
|
|
788
|
-
const hasMiddleware = fs.existsSync(path.join(root, "middleware.ts")) || fs.existsSync(path.join(root, "middleware.js"));
|
|
801
|
+
const pagesDir = findDir(root, "pages", "src/pages");
|
|
802
|
+
const appDirPath = findDir(root, "app", "src/app");
|
|
803
|
+
const hasProxy = fs.existsSync(path.posix.join(root, "proxy.ts")) || fs.existsSync(path.posix.join(root, "proxy.js"));
|
|
804
|
+
const hasMiddleware = fs.existsSync(path.posix.join(root, "middleware.ts")) || fs.existsSync(path.posix.join(root, "middleware.js"));
|
|
789
805
|
if (pagesDir !== null) {
|
|
790
|
-
const isSrc = pagesDir.includes(
|
|
806
|
+
const isSrc = pagesDir.includes("src/pages");
|
|
791
807
|
items.push({
|
|
792
808
|
name: isSrc ? "Pages Router (src/pages/)" : "Pages Router (pages/)",
|
|
793
809
|
status: "supported"
|
|
@@ -813,7 +829,7 @@ function checkConventions(root) {
|
|
|
813
829
|
});
|
|
814
830
|
}
|
|
815
831
|
if (appDirPath !== null) {
|
|
816
|
-
const isSrc = appDirPath.includes(
|
|
832
|
+
const isSrc = appDirPath.includes("src/app");
|
|
817
833
|
items.push({
|
|
818
834
|
name: isSrc ? "App Router (src/app/)" : "App Router (app/)",
|
|
819
835
|
status: "supported"
|
|
@@ -858,12 +874,12 @@ function checkConventions(root) {
|
|
|
858
874
|
name: "middleware.ts (deprecated in Next.js 16)",
|
|
859
875
|
status: "supported"
|
|
860
876
|
});
|
|
861
|
-
if (
|
|
877
|
+
if (pagesDir === null && appDirPath === null) items.push({
|
|
862
878
|
name: "No pages/ or app/ directory found",
|
|
863
879
|
status: "unsupported",
|
|
864
880
|
detail: "vinext requires a pages/ or app/ directory"
|
|
865
881
|
});
|
|
866
|
-
const pkgPath = path.join(root, "package.json");
|
|
882
|
+
const pkgPath = path.posix.join(root, "package.json");
|
|
867
883
|
if (fs.existsSync(pkgPath)) {
|
|
868
884
|
if (JSON.parse(fs.readFileSync(pkgPath, "utf-8")).type !== "module") items.push({
|
|
869
885
|
name: "Missing \"type\": \"module\" in package.json",
|
|
@@ -877,7 +893,7 @@ function checkConventions(root) {
|
|
|
877
893
|
const cjsGlobalFiles = [];
|
|
878
894
|
for (const file of allSourceFiles) {
|
|
879
895
|
const content = fs.readFileSync(file, "utf-8");
|
|
880
|
-
const rel =
|
|
896
|
+
const rel = path.posix.relative(root, file);
|
|
881
897
|
if (viewTransitionRegex.test(content)) viewTransitionFiles.push(rel);
|
|
882
898
|
if (hasFreeCjsGlobal(content)) cjsGlobalFiles.push(rel);
|
|
883
899
|
}
|
|
@@ -892,7 +908,7 @@ function checkConventions(root) {
|
|
|
892
908
|
"postcss.config.js",
|
|
893
909
|
"postcss.config.cjs"
|
|
894
910
|
]) {
|
|
895
|
-
const configPath = path.join(root, configFile);
|
|
911
|
+
const configPath = path.posix.join(root, configFile);
|
|
896
912
|
if (fs.existsSync(configPath)) {
|
|
897
913
|
const content = fs.readFileSync(configPath, "utf-8");
|
|
898
914
|
if (/plugins\s*:\s*\[\s*['"]/.test(content)) items.push({
|
|
@@ -913,6 +929,10 @@ function checkConventions(root) {
|
|
|
913
929
|
}
|
|
914
930
|
/**
|
|
915
931
|
* Run the full compatibility check.
|
|
932
|
+
*
|
|
933
|
+
* `root` must be forward-slash — callers normalize it at the CLI entry, and it
|
|
934
|
+
* is forwarded to `scanImports` / `checkConventions` / `findDir`, which build
|
|
935
|
+
* paths with `path.posix.*`.
|
|
916
936
|
*/
|
|
917
937
|
function runCheck(root) {
|
|
918
938
|
const imports = scanImports(root);
|
package/dist/cli.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { detectPackageManager, ensureViteConfigCompatibility, hasAppDir, hasViteConfig } from "./utils/project.js";
|
|
3
3
|
import { formatReport, runCheck } from "./check.js";
|
|
4
4
|
import { parseArgs } from "./cli-args.js";
|
|
5
|
+
import { normalizePathSeparators } from "./utils/path.js";
|
|
5
6
|
import { PHASE_PRODUCTION_BUILD } from "./shims/constants.js";
|
|
6
7
|
import { createRscCompatibilityId, loadNextConfig, resolveNextConfig } from "./config/next-config.js";
|
|
7
8
|
import { generateRouteTypes } from "./typegen.js";
|
|
@@ -440,10 +441,9 @@ async function deployCommand() {
|
|
|
440
441
|
}
|
|
441
442
|
async function check() {
|
|
442
443
|
if (parseArgs(rawArgs).help) return printHelp("check");
|
|
443
|
-
const root = process.cwd();
|
|
444
444
|
console.log(`\n vinext check\n`);
|
|
445
445
|
console.log(" Scanning project...\n");
|
|
446
|
-
const result = runCheck(
|
|
446
|
+
const result = runCheck(normalizePathSeparators(process.cwd()));
|
|
447
447
|
console.log(formatReport(result));
|
|
448
448
|
}
|
|
449
449
|
async function typegen() {
|
|
@@ -272,7 +272,8 @@ type ResolvedNextConfig = {
|
|
|
272
272
|
aliases: Record<string, string>; /** Extra allowed origins for dev server access (from allowedDevOrigins). */
|
|
273
273
|
allowedDevOrigins: string[]; /** Extra allowed origins for server action CSRF validation (from experimental.serverActions.allowedOrigins). */
|
|
274
274
|
serverActionsAllowedOrigins: string[]; /** Packages whose barrel imports should be optimized (from experimental.optimizePackageImports). */
|
|
275
|
-
optimizePackageImports: string[]; /**
|
|
275
|
+
optimizePackageImports: string[]; /** Packages explicitly requested for server/client transpilation. */
|
|
276
|
+
transpilePackages: string[]; /** Inline app CSS into production HTML (from experimental.inlineCss). */
|
|
276
277
|
inlineCss: boolean; /** Parsed body size limit for server actions in bytes (from experimental.serverActions.bodySizeLimit). Defaults to 1MB. */
|
|
277
278
|
serverActionsBodySizeLimit: number; /** Verbatim body size limit config value (e.g. "2mb") for the "Body exceeded {limit} limit" error. Defaults to "1 MB". */
|
|
278
279
|
serverActionsBodySizeLimitLabel: string; /** Route-level expire fallback in seconds for ISR entries with numeric revalidate. */
|
|
@@ -569,6 +569,7 @@ async function resolveNextConfig(config, root = process.cwd(), options = {}) {
|
|
|
569
569
|
allowedDevOrigins: [],
|
|
570
570
|
serverActionsAllowedOrigins: [],
|
|
571
571
|
optimizePackageImports: [],
|
|
572
|
+
transpilePackages: [],
|
|
572
573
|
inlineCss: false,
|
|
573
574
|
serverActionsBodySizeLimit: 1 * 1024 * 1024,
|
|
574
575
|
serverActionsBodySizeLimitLabel: "1 MB",
|
|
@@ -666,6 +667,7 @@ async function resolveNextConfig(config, root = process.cwd(), options = {}) {
|
|
|
666
667
|
const topLevelServerExternalPackages = Array.isArray(config.serverExternalPackages) ? readStringArray(config.serverExternalPackages) : void 0;
|
|
667
668
|
const legacyServerComponentsExternal = readStringArray(experimental?.serverComponentsExternalPackages);
|
|
668
669
|
const serverExternalPackages = topLevelServerExternalPackages ?? legacyServerComponentsExternal;
|
|
670
|
+
const transpilePackages = readStringArray(config.transpilePackages);
|
|
669
671
|
if (experimental?.swcEnvOptions !== void 0) console.warn("[vinext] next.config option \"experimental.swcEnvOptions\" is not applicable and will be ignored (vinext uses Vite, not SWC). A Vite-compatible polyfill solution may be explored in the future.");
|
|
670
672
|
if (experimental?.rootParams !== void 0) console.warn("[vinext] `experimental.rootParams` is no longer needed, because `next/root-params` is available by default. You can remove it from next.config.(js|mjs|ts).");
|
|
671
673
|
const useLightningcss = experimental?.useLightningcss === true;
|
|
@@ -728,6 +730,7 @@ async function resolveNextConfig(config, root = process.cwd(), options = {}) {
|
|
|
728
730
|
allowedDevOrigins,
|
|
729
731
|
serverActionsAllowedOrigins,
|
|
730
732
|
optimizePackageImports,
|
|
733
|
+
transpilePackages,
|
|
731
734
|
inlineCss,
|
|
732
735
|
serverActionsBodySizeLimit,
|
|
733
736
|
serverActionsBodySizeLimitLabel,
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
//#region src/config/server-external-packages.ts
|
|
2
|
+
const DEFAULT_SERVER_EXTERNAL_PACKAGES = [
|
|
3
|
+
"@alinea/generated",
|
|
4
|
+
"@appsignal/nodejs",
|
|
5
|
+
"@aws-sdk/client-s3",
|
|
6
|
+
"@aws-sdk/s3-presigned-post",
|
|
7
|
+
"@blockfrost/blockfrost-js",
|
|
8
|
+
"@highlight-run/node",
|
|
9
|
+
"@huggingface/transformers",
|
|
10
|
+
"@jpg-store/lucid-cardano",
|
|
11
|
+
"@libsql/client",
|
|
12
|
+
"@mikro-orm/core",
|
|
13
|
+
"@mikro-orm/knex",
|
|
14
|
+
"@node-rs/argon2",
|
|
15
|
+
"@node-rs/bcrypt",
|
|
16
|
+
"@prisma/client",
|
|
17
|
+
"@react-pdf/renderer",
|
|
18
|
+
"@sentry/profiling-node",
|
|
19
|
+
"@sparticuz/chromium",
|
|
20
|
+
"@sparticuz/chromium-min",
|
|
21
|
+
"@statsig/statsig-node-core",
|
|
22
|
+
"@swc/core",
|
|
23
|
+
"@xenova/transformers",
|
|
24
|
+
"@zenstackhq/runtime",
|
|
25
|
+
"argon2",
|
|
26
|
+
"autoprefixer",
|
|
27
|
+
"aws-crt",
|
|
28
|
+
"bcrypt",
|
|
29
|
+
"better-sqlite3",
|
|
30
|
+
"canvas",
|
|
31
|
+
"chromadb-default-embed",
|
|
32
|
+
"config",
|
|
33
|
+
"cpu-features",
|
|
34
|
+
"cypress",
|
|
35
|
+
"dd-trace",
|
|
36
|
+
"eslint",
|
|
37
|
+
"express",
|
|
38
|
+
"firebase-admin",
|
|
39
|
+
"htmlrewriter",
|
|
40
|
+
"import-in-the-middle",
|
|
41
|
+
"isolated-vm",
|
|
42
|
+
"jest",
|
|
43
|
+
"jsdom",
|
|
44
|
+
"keyv",
|
|
45
|
+
"libsql",
|
|
46
|
+
"mdx-bundler",
|
|
47
|
+
"mongodb",
|
|
48
|
+
"mongoose",
|
|
49
|
+
"newrelic",
|
|
50
|
+
"next-mdx-remote",
|
|
51
|
+
"next-seo",
|
|
52
|
+
"node-cron",
|
|
53
|
+
"node-pty",
|
|
54
|
+
"node-web-audio-api",
|
|
55
|
+
"onnxruntime-node",
|
|
56
|
+
"oslo",
|
|
57
|
+
"pg",
|
|
58
|
+
"pino",
|
|
59
|
+
"pino-pretty",
|
|
60
|
+
"pino-roll",
|
|
61
|
+
"playwright",
|
|
62
|
+
"playwright-core",
|
|
63
|
+
"postcss",
|
|
64
|
+
"prettier",
|
|
65
|
+
"prisma",
|
|
66
|
+
"puppeteer",
|
|
67
|
+
"puppeteer-core",
|
|
68
|
+
"ravendb",
|
|
69
|
+
"require-in-the-middle",
|
|
70
|
+
"rimraf",
|
|
71
|
+
"sharp",
|
|
72
|
+
"shiki",
|
|
73
|
+
"sqlite3",
|
|
74
|
+
"thread-stream",
|
|
75
|
+
"ts-morph",
|
|
76
|
+
"ts-node",
|
|
77
|
+
"typescript",
|
|
78
|
+
"vscode-oniguruma",
|
|
79
|
+
"webpack",
|
|
80
|
+
"websocket",
|
|
81
|
+
"zeromq"
|
|
82
|
+
];
|
|
83
|
+
function mergeServerExternalPackages(userPackages = [], transpilePackages = []) {
|
|
84
|
+
const transpiled = new Set(transpilePackages);
|
|
85
|
+
const conflicts = userPackages.filter((name) => transpiled.has(name));
|
|
86
|
+
if (conflicts.length > 0) throw new Error(`The packages specified in the 'transpilePackages' conflict with the 'serverExternalPackages': ${conflicts.join(", ")}`);
|
|
87
|
+
const defaults = DEFAULT_SERVER_EXTERNAL_PACKAGES.filter((name) => !transpiled.has(name));
|
|
88
|
+
return [...new Set([...defaults, ...userPackages])];
|
|
89
|
+
}
|
|
90
|
+
//#endregion
|
|
91
|
+
export { mergeServerExternalPackages };
|
package/dist/deploy.d.ts
CHANGED
|
@@ -58,6 +58,13 @@ declare function formatMissingCloudflarePluginError(options: {
|
|
|
58
58
|
isAppRouter: boolean;
|
|
59
59
|
configFile?: string;
|
|
60
60
|
}): string;
|
|
61
|
+
/**
|
|
62
|
+
* Detect the project structure (router, config, worker entry, package name).
|
|
63
|
+
*
|
|
64
|
+
* `root` must be forward-slash — it is joined with `path.posix.*`, passed to
|
|
65
|
+
* `findDir` / `hasAppDir`, and used as the base of `path.posix.basename`.
|
|
66
|
+
* Callers normalize it at the deploy entry.
|
|
67
|
+
*/
|
|
61
68
|
declare function detectProject(root: string): ProjectInfo;
|
|
62
69
|
/** @see {@link _ensureESModule} */
|
|
63
70
|
declare const ensureESModule: typeof ensureESModule$1;
|
package/dist/deploy.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { detectPackageManager as detectPackageManager$1, ensureESModule as ensureESModule$1, findDir, findInNodeModules, hasAppDir, renameCJSConfigs as renameCJSConfigs$1 } from "./utils/project.js";
|
|
2
2
|
import { parsePositiveIntegerArg } from "./cli-args.js";
|
|
3
3
|
import { escapeRegExp } from "./utils/regex.js";
|
|
4
|
+
import { normalizePathSeparators } from "./utils/path.js";
|
|
4
5
|
import { loadNextConfig, resolveNextConfig } from "./config/next-config.js";
|
|
5
6
|
import { getReactUpgradeDeps } from "./init.js";
|
|
6
7
|
import { runTPR } from "./cloudflare/tpr.js";
|
|
@@ -107,23 +108,30 @@ function formatMissingCloudflarePluginError(options) {
|
|
|
107
108
|
const configRef = options.configFile ? options.configFile : "your Vite config";
|
|
108
109
|
return `[vinext] Missing @cloudflare/vite-plugin in ${configRef}.\n\n Cloudflare Workers builds require the cloudflare() plugin.\n Add it to ${configRef}:\n\n import { cloudflare } from "@cloudflare/vite-plugin";\n\n export default defineConfig({\n plugins: [\n vinext(),\n cloudflare(${cfArg}),\n ],\n });\n\n Or delete ${configRef} and re-run \`vinext deploy\` to auto-generate it.`;
|
|
109
110
|
}
|
|
111
|
+
/**
|
|
112
|
+
* Detect the project structure (router, config, worker entry, package name).
|
|
113
|
+
*
|
|
114
|
+
* `root` must be forward-slash — it is joined with `path.posix.*`, passed to
|
|
115
|
+
* `findDir` / `hasAppDir`, and used as the base of `path.posix.basename`.
|
|
116
|
+
* Callers normalize it at the deploy entry.
|
|
117
|
+
*/
|
|
110
118
|
function detectProject(root) {
|
|
111
119
|
const hasApp = hasAppDir(root);
|
|
112
|
-
const hasPages = findDir(root, "pages",
|
|
120
|
+
const hasPages = findDir(root, "pages", "src/pages") !== null;
|
|
113
121
|
const isAppRouter = hasApp;
|
|
114
122
|
const isPagesRouter = !hasApp && hasPages;
|
|
115
|
-
const hasViteConfig = fs.existsSync(path.join(root, "vite.config.ts")) || fs.existsSync(path.join(root, "vite.config.js")) || fs.existsSync(path.join(root, "vite.config.mjs"));
|
|
123
|
+
const hasViteConfig = fs.existsSync(path.posix.join(root, "vite.config.ts")) || fs.existsSync(path.posix.join(root, "vite.config.js")) || fs.existsSync(path.posix.join(root, "vite.config.mjs"));
|
|
116
124
|
const wranglerConfigExists = hasWranglerConfig(root);
|
|
117
|
-
const hasWorkerEntry = fs.existsSync(path.join(root, "worker", "index.ts")) || fs.existsSync(path.join(root, "worker", "index.js"));
|
|
125
|
+
const hasWorkerEntry = fs.existsSync(path.posix.join(root, "worker", "index.ts")) || fs.existsSync(path.posix.join(root, "worker", "index.js"));
|
|
118
126
|
const hasCloudflarePlugin = findInNodeModules(root, "@cloudflare/vite-plugin") !== null;
|
|
119
127
|
const hasRscPlugin = findInNodeModules(root, "@vitejs/plugin-rsc") !== null;
|
|
120
128
|
const hasWrangler = findInNodeModules(root, ".bin/wrangler") !== null;
|
|
121
|
-
const pkgPath = path.join(root, "package.json");
|
|
129
|
+
const pkgPath = path.posix.join(root, "package.json");
|
|
122
130
|
let pkg = null;
|
|
123
131
|
if (fs.existsSync(pkgPath)) try {
|
|
124
132
|
pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
|
|
125
133
|
} catch {}
|
|
126
|
-
let projectName = path.basename(root);
|
|
134
|
+
let projectName = path.posix.basename(root);
|
|
127
135
|
if (pkg?.name && typeof pkg.name === "string") projectName = pkg.name.replace(/^@[^/]+\//, "").toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
|
|
128
136
|
const hasTypeModule = pkg?.type === "module";
|
|
129
137
|
let hasISR = false;
|
|
@@ -380,6 +388,7 @@ import { handleImageOptimization, DEFAULT_DEVICE_SIZES, DEFAULT_IMAGE_SIZES, isI
|
|
|
380
388
|
import type { ImageConfig } from "vinext/server/image-optimization";
|
|
381
389
|
import { cloneRequestWithHeaders, cloneRequestWithUrl, filterInternalHeaders, isOpenRedirectShaped } from "vinext/server/request-pipeline";
|
|
382
390
|
import { notFoundStaticAssetResponse } from "vinext/server/http-error-responses";
|
|
391
|
+
import { finalizeMissingStaticAssetResponse } from "vinext/server/worker-utils";
|
|
383
392
|
import { assetPrefixPathname, isNextStaticPath } from "vinext/utils/asset-prefix";
|
|
384
393
|
import { hasBasePath, stripBasePath } from "vinext/utils/base-path";
|
|
385
394
|
|
|
@@ -438,15 +447,11 @@ export default {
|
|
|
438
447
|
return new Response("This page could not be found", { status: 404 });
|
|
439
448
|
}
|
|
440
449
|
|
|
441
|
-
//
|
|
442
|
-
//
|
|
443
|
-
//
|
|
444
|
-
//
|
|
445
|
-
|
|
446
|
-
// packages/next/src/server/lib/router-server.ts
|
|
447
|
-
if (isNextStaticPath(pathname, basePath, assetPathPrefix)) {
|
|
448
|
-
return notFoundStaticAssetResponse();
|
|
449
|
-
}
|
|
450
|
+
// Valid assets are served by Cloudflare's ASSETS binding before the
|
|
451
|
+
// worker runs. Missing asset-shaped requests still need to reach
|
|
452
|
+
// middleware so it can rewrite or respond; a final 404 is converted
|
|
453
|
+
// back to Next.js's canonical plain-text static-file response below.
|
|
454
|
+
const missingBuildAsset = isNextStaticPath(pathname, basePath, assetPathPrefix);
|
|
450
455
|
|
|
451
456
|
// Strip internal headers from inbound requests so they cannot be
|
|
452
457
|
// forged to influence routing or impersonate internal state.
|
|
@@ -538,10 +543,12 @@ export default {
|
|
|
538
543
|
|
|
539
544
|
const result = await runPagesRequest(request, deps);
|
|
540
545
|
if (result.type === "response") {
|
|
541
|
-
return result.response;
|
|
546
|
+
return finalizeMissingStaticAssetResponse(result.response, missingBuildAsset);
|
|
542
547
|
}
|
|
543
548
|
// Should not reach here for prod/worker (all callbacks supplied).
|
|
544
|
-
return
|
|
549
|
+
return missingBuildAsset
|
|
550
|
+
? notFoundStaticAssetResponse()
|
|
551
|
+
: new Response("This page could not be found", { status: 404 });
|
|
545
552
|
|
|
546
553
|
} catch (error) {
|
|
547
554
|
console.error("[vinext] Worker error:", error);
|
|
@@ -945,7 +952,7 @@ async function deploy(options) {
|
|
|
945
952
|
mode: "production"
|
|
946
953
|
});
|
|
947
954
|
console.log("\n vinext deploy\n");
|
|
948
|
-
const info = detectProject(root);
|
|
955
|
+
const info = detectProject(normalizePathSeparators(root));
|
|
949
956
|
if (!info.isAppRouter && !info.isPagesRouter) {
|
|
950
957
|
console.error(" Error: No app/ or pages/ directory found.");
|
|
951
958
|
console.error(" vinext deploy requires a Next.js project with an app/ or pages/ directory");
|
|
@@ -973,7 +980,7 @@ async function deploy(options) {
|
|
|
973
980
|
console.log();
|
|
974
981
|
installDeps(root, missingDeps);
|
|
975
982
|
const nameOverride = options.name ? info.projectName : void 0;
|
|
976
|
-
Object.assign(info, detectProject(root));
|
|
983
|
+
Object.assign(info, detectProject(normalizePathSeparators(root)));
|
|
977
984
|
if (nameOverride) info.projectName = nameOverride;
|
|
978
985
|
}
|
|
979
986
|
if (!info.hasTypeModule) {
|
|
@@ -44,7 +44,8 @@ type AppRouterConfig = {
|
|
|
44
44
|
reactMaxHeadersLength?: number; /** Maximum in-memory cache size in bytes. 0 disables the default memory cache. */
|
|
45
45
|
cacheMaxMemorySize?: number; /** Inline app CSS into production HTML (from experimental.inlineCss). */
|
|
46
46
|
inlineCss?: boolean; /** Enables Next.js Cache Components semantics for App Router document HTML. */
|
|
47
|
-
cacheComponents?: boolean; /**
|
|
47
|
+
cacheComponents?: boolean; /** Whether the RSC build discovered any server references. Defaults to true. */
|
|
48
|
+
hasServerActions?: boolean; /** Internationalization routing config for middleware matcher locale handling. */
|
|
48
49
|
i18n?: NextI18nConfig | null;
|
|
49
50
|
imageConfig?: ImageConfig;
|
|
50
51
|
/**
|