vinext 0.0.25 → 0.0.27
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 +95 -86
- package/dist/build/static-export.d.ts.map +1 -1
- package/dist/build/static-export.js +3 -8
- package/dist/build/static-export.js.map +1 -1
- package/dist/check.d.ts.map +1 -1
- package/dist/check.js +154 -50
- package/dist/check.js.map +1 -1
- package/dist/cli.js +42 -12
- package/dist/cli.js.map +1 -1
- package/dist/client/entry.js.map +1 -1
- package/dist/client/vinext-next-data.d.ts +22 -0
- package/dist/client/vinext-next-data.d.ts.map +1 -0
- package/dist/client/vinext-next-data.js +2 -0
- package/dist/client/vinext-next-data.js.map +1 -0
- package/dist/cloudflare/kv-cache-handler.d.ts +32 -1
- package/dist/cloudflare/kv-cache-handler.d.ts.map +1 -1
- package/dist/cloudflare/kv-cache-handler.js +47 -21
- package/dist/cloudflare/kv-cache-handler.js.map +1 -1
- package/dist/cloudflare/tpr.d.ts.map +1 -1
- package/dist/cloudflare/tpr.js +15 -4
- package/dist/cloudflare/tpr.js.map +1 -1
- package/dist/config/config-matchers.d.ts +27 -0
- package/dist/config/config-matchers.d.ts.map +1 -1
- package/dist/config/config-matchers.js +312 -62
- package/dist/config/config-matchers.js.map +1 -1
- package/dist/config/dotenv.d.ts.map +1 -1
- package/dist/config/dotenv.js +1 -6
- package/dist/config/dotenv.js.map +1 -1
- package/dist/config/next-config.d.ts +38 -4
- package/dist/config/next-config.d.ts.map +1 -1
- package/dist/config/next-config.js +194 -31
- package/dist/config/next-config.js.map +1 -1
- package/dist/deploy.d.ts +11 -0
- package/dist/deploy.d.ts.map +1 -1
- package/dist/deploy.js +74 -39
- package/dist/deploy.js.map +1 -1
- package/dist/entries/app-browser-entry.d.ts +9 -0
- package/dist/entries/app-browser-entry.d.ts.map +1 -0
- package/dist/entries/app-browser-entry.js +340 -0
- package/dist/entries/app-browser-entry.js.map +1 -0
- package/dist/{server/app-dev-server.d.ts → entries/app-rsc-entry.d.ts} +4 -17
- package/dist/entries/app-rsc-entry.d.ts.map +1 -0
- package/dist/{server/app-dev-server.js → entries/app-rsc-entry.js} +438 -1232
- package/dist/entries/app-rsc-entry.js.map +1 -0
- package/dist/entries/app-ssr-entry.d.ts +8 -0
- package/dist/entries/app-ssr-entry.d.ts.map +1 -0
- package/dist/entries/app-ssr-entry.js +449 -0
- package/dist/entries/app-ssr-entry.js.map +1 -0
- package/dist/entries/pages-client-entry.d.ts +4 -0
- package/dist/entries/pages-client-entry.d.ts.map +1 -0
- package/dist/entries/pages-client-entry.js +96 -0
- package/dist/entries/pages-client-entry.js.map +1 -0
- package/dist/entries/pages-entry-helpers.d.ts +7 -0
- package/dist/entries/pages-entry-helpers.d.ts.map +1 -0
- package/dist/entries/pages-entry-helpers.js +18 -0
- package/dist/entries/pages-entry-helpers.js.map +1 -0
- package/dist/entries/pages-server-entry.d.ts +8 -0
- package/dist/entries/pages-server-entry.d.ts.map +1 -0
- package/dist/entries/pages-server-entry.js +1015 -0
- package/dist/entries/pages-server-entry.js.map +1 -0
- package/dist/index.d.ts +2 -26
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +407 -1357
- package/dist/index.js.map +1 -1
- package/dist/init.d.ts.map +1 -1
- package/dist/init.js +6 -5
- package/dist/init.js.map +1 -1
- package/dist/routing/app-router.d.ts +2 -0
- package/dist/routing/app-router.d.ts.map +1 -1
- package/dist/routing/app-router.js +10 -18
- package/dist/routing/app-router.js.map +1 -1
- package/dist/routing/file-matcher.d.ts.map +1 -1
- package/dist/routing/file-matcher.js.map +1 -1
- package/dist/routing/pages-router.d.ts +2 -0
- package/dist/routing/pages-router.d.ts.map +1 -1
- package/dist/routing/pages-router.js +8 -5
- package/dist/routing/pages-router.js.map +1 -1
- package/dist/routing/utils.d.ts.map +1 -1
- package/dist/routing/utils.js.map +1 -1
- package/dist/server/api-handler.d.ts.map +1 -1
- package/dist/server/api-handler.js +7 -2
- package/dist/server/api-handler.js.map +1 -1
- package/dist/server/app-router-entry.d.ts +3 -2
- package/dist/server/app-router-entry.d.ts.map +1 -1
- package/dist/server/app-router-entry.js +8 -4
- package/dist/server/app-router-entry.js.map +1 -1
- package/dist/server/dev-module-runner.d.ts.map +1 -1
- package/dist/server/dev-module-runner.js +1 -1
- package/dist/server/dev-module-runner.js.map +1 -1
- package/dist/server/dev-origin-check.d.ts.map +1 -1
- package/dist/server/dev-origin-check.js.map +1 -1
- package/dist/server/dev-server.d.ts.map +1 -1
- package/dist/server/dev-server.js +30 -18
- package/dist/server/dev-server.js.map +1 -1
- package/dist/server/image-optimization.d.ts.map +1 -1
- package/dist/server/image-optimization.js.map +1 -1
- package/dist/server/instrumentation.d.ts +1 -1
- package/dist/server/instrumentation.js +2 -2
- package/dist/server/instrumentation.js.map +1 -1
- package/dist/server/isr-cache.d.ts +13 -1
- package/dist/server/isr-cache.d.ts.map +1 -1
- package/dist/server/isr-cache.js +10 -1
- package/dist/server/isr-cache.js.map +1 -1
- package/dist/server/metadata-routes.d.ts.map +1 -1
- package/dist/server/metadata-routes.js +6 -18
- package/dist/server/metadata-routes.js.map +1 -1
- package/dist/server/middleware-codegen.d.ts +1 -1
- package/dist/server/middleware-codegen.d.ts.map +1 -1
- package/dist/server/middleware-codegen.js +13 -11
- package/dist/server/middleware-codegen.js.map +1 -1
- package/dist/server/middleware-request-headers.d.ts +9 -0
- package/dist/server/middleware-request-headers.d.ts.map +1 -0
- package/dist/server/middleware-request-headers.js +77 -0
- package/dist/server/middleware-request-headers.js.map +1 -0
- package/dist/server/middleware.d.ts.map +1 -1
- package/dist/server/middleware.js +38 -19
- package/dist/server/middleware.js.map +1 -1
- package/dist/server/normalize-path.js.map +1 -1
- package/dist/server/prod-server.d.ts +1 -1
- package/dist/server/prod-server.d.ts.map +1 -1
- package/dist/server/prod-server.js +71 -41
- package/dist/server/prod-server.js.map +1 -1
- package/dist/server/request-pipeline.d.ts +93 -0
- package/dist/server/request-pipeline.d.ts.map +1 -0
- package/dist/server/request-pipeline.js +200 -0
- package/dist/server/request-pipeline.js.map +1 -0
- package/dist/shims/cache-runtime.d.ts.map +1 -1
- package/dist/shims/cache-runtime.js +21 -16
- package/dist/shims/cache-runtime.js.map +1 -1
- package/dist/shims/cache.d.ts.map +1 -1
- package/dist/shims/cache.js +18 -17
- package/dist/shims/cache.js.map +1 -1
- package/dist/shims/constants.d.ts +120 -3
- package/dist/shims/constants.d.ts.map +1 -1
- package/dist/shims/constants.js +165 -3
- package/dist/shims/constants.js.map +1 -1
- package/dist/shims/dynamic.d.ts.map +1 -1
- package/dist/shims/dynamic.js +1 -1
- package/dist/shims/dynamic.js.map +1 -1
- package/dist/shims/error-boundary.d.ts.map +1 -1
- package/dist/shims/error-boundary.js +2 -3
- package/dist/shims/error-boundary.js.map +1 -1
- package/dist/shims/error.d.ts.map +1 -1
- package/dist/shims/error.js +1 -3
- package/dist/shims/error.js.map +1 -1
- package/dist/shims/fetch-cache.d.ts.map +1 -1
- package/dist/shims/fetch-cache.js +53 -29
- package/dist/shims/fetch-cache.js.map +1 -1
- package/dist/shims/font-google-base.d.ts.map +1 -1
- package/dist/shims/font-google-base.js +16 -4
- package/dist/shims/font-google-base.js.map +1 -1
- package/dist/shims/font-google.d.ts +1 -1
- package/dist/shims/font-google.d.ts.map +1 -1
- package/dist/shims/font-google.generated.d.ts.map +1 -1
- package/dist/shims/font-google.generated.js +412 -206
- package/dist/shims/font-google.generated.js.map +1 -1
- package/dist/shims/font-google.js +1 -1
- package/dist/shims/font-google.js.map +1 -1
- package/dist/shims/font-local.d.ts.map +1 -1
- package/dist/shims/font-local.js +13 -3
- package/dist/shims/font-local.js.map +1 -1
- package/dist/shims/form.d.ts.map +1 -1
- package/dist/shims/form.js +2 -2
- package/dist/shims/form.js.map +1 -1
- package/dist/shims/head.d.ts.map +1 -1
- package/dist/shims/head.js +10 -8
- package/dist/shims/head.js.map +1 -1
- package/dist/shims/headers.d.ts +23 -5
- package/dist/shims/headers.d.ts.map +1 -1
- package/dist/shims/headers.js +98 -37
- package/dist/shims/headers.js.map +1 -1
- package/dist/shims/image.d.ts.map +1 -1
- package/dist/shims/image.js +35 -8
- package/dist/shims/image.js.map +1 -1
- package/dist/shims/legacy-image.d.ts.map +1 -1
- package/dist/shims/legacy-image.js +1 -1
- package/dist/shims/legacy-image.js.map +1 -1
- package/dist/shims/link.d.ts.map +1 -1
- package/dist/shims/link.js +31 -17
- package/dist/shims/link.js.map +1 -1
- package/dist/shims/metadata.d.ts +19 -3
- package/dist/shims/metadata.d.ts.map +1 -1
- package/dist/shims/metadata.js +19 -11
- package/dist/shims/metadata.js.map +1 -1
- package/dist/shims/navigation-state.d.ts.map +1 -1
- package/dist/shims/navigation-state.js +3 -2
- package/dist/shims/navigation-state.js.map +1 -1
- package/dist/shims/navigation.d.ts.map +1 -1
- package/dist/shims/navigation.js +26 -19
- package/dist/shims/navigation.js.map +1 -1
- package/dist/shims/og.d.ts +6 -6
- package/dist/shims/og.js +6 -6
- package/dist/shims/og.js.map +1 -1
- package/dist/shims/request-context.d.ts +50 -0
- package/dist/shims/request-context.d.ts.map +1 -0
- package/dist/shims/request-context.js +59 -0
- package/dist/shims/request-context.js.map +1 -0
- package/dist/shims/router-state.d.ts.map +1 -1
- package/dist/shims/router-state.js +2 -1
- package/dist/shims/router-state.js.map +1 -1
- package/dist/shims/router.d.ts.map +1 -1
- package/dist/shims/router.js +18 -25
- package/dist/shims/router.js.map +1 -1
- package/dist/shims/script.d.ts.map +1 -1
- package/dist/shims/script.js.map +1 -1
- package/dist/shims/server.d.ts +13 -0
- package/dist/shims/server.d.ts.map +1 -1
- package/dist/shims/server.js +100 -34
- package/dist/shims/server.js.map +1 -1
- package/dist/shims/url-utils.d.ts.map +1 -1
- package/dist/shims/url-utils.js +1 -3
- package/dist/shims/url-utils.js.map +1 -1
- package/dist/utils/base-path.d.ts +17 -0
- package/dist/utils/base-path.d.ts.map +1 -0
- package/dist/utils/base-path.js +25 -0
- package/dist/utils/base-path.js.map +1 -0
- package/dist/utils/project.d.ts +15 -0
- package/dist/utils/project.d.ts.map +1 -1
- package/dist/utils/project.js +50 -4
- package/dist/utils/project.js.map +1 -1
- package/dist/utils/query.d.ts.map +1 -1
- package/dist/utils/query.js +3 -1
- package/dist/utils/query.js.map +1 -1
- package/package.json +47 -33
- package/dist/server/app-dev-server.d.ts.map +0 -1
- package/dist/server/app-dev-server.js.map +0 -1
package/README.md
CHANGED
|
@@ -52,15 +52,15 @@ Your existing `pages/`, `app/`, `next.config.js`, and `public/` directories work
|
|
|
52
52
|
|
|
53
53
|
### CLI reference
|
|
54
54
|
|
|
55
|
-
| Command
|
|
56
|
-
|
|
57
|
-
| `vinext dev`
|
|
58
|
-
| `vinext build`
|
|
59
|
-
| `vinext start`
|
|
60
|
-
| `vinext deploy` | Build and deploy to Cloudflare Workers
|
|
61
|
-
| `vinext init`
|
|
62
|
-
| `vinext check`
|
|
63
|
-
| `vinext lint`
|
|
55
|
+
| Command | Description |
|
|
56
|
+
| --------------- | ----------------------------------------------------------------------- |
|
|
57
|
+
| `vinext dev` | Start dev server with HMR |
|
|
58
|
+
| `vinext build` | Production build (multi-environment for App Router: RSC + SSR + client) |
|
|
59
|
+
| `vinext start` | Start local production server for testing |
|
|
60
|
+
| `vinext deploy` | Build and deploy to Cloudflare Workers |
|
|
61
|
+
| `vinext init` | Migrate a Next.js project to run under vinext |
|
|
62
|
+
| `vinext check` | Scan your Next.js app for compatibility issues before migrating |
|
|
63
|
+
| `vinext lint` | Delegate to eslint or oxlint |
|
|
64
64
|
|
|
65
65
|
Options: `-p / --port <port>`, `-H / --hostname <host>`, `--turbopack` (accepted, no-op).
|
|
66
66
|
|
|
@@ -72,7 +72,7 @@ Options: `-p / --port <port>`, `-H / --hostname <host>`, `--turbopack` (accepted
|
|
|
72
72
|
|
|
73
73
|
Run `npm create next-app@latest` to create a new Next.js project, and then follow these instructions to migrate it to vinext.
|
|
74
74
|
|
|
75
|
-
In the future, we will have a proper `npm create vinext` new project workflow.
|
|
75
|
+
In the future, we will have a proper `npm create vinext` new project workflow.
|
|
76
76
|
|
|
77
77
|
### Migrating an existing Next.js project
|
|
78
78
|
|
|
@@ -109,6 +109,7 @@ vinext is an experiment: can we reimplement the Next.js API surface on Vite, so
|
|
|
109
109
|
vinext works everywhere. It natively supports Cloudflare Workers (with `vinext deploy`, bindings, KV caching), and can be deployed to Vercel, Netlify, AWS, Deno Deploy, and more via the [Nitro](https://v3.nitro.build/) Vite plugin. Native support for additional platforms is [planned](https://github.com/cloudflare/vinext/issues/80).
|
|
110
110
|
|
|
111
111
|
**Alternatives worth knowing about:**
|
|
112
|
+
|
|
112
113
|
- **[OpenNext](https://opennext.js.org/)** — adapts `next build` output for AWS, Cloudflare, and other platforms. OpenNext has been around much longer than vinext, is more mature, and covers more of the Next.js API surface because it builds on top of Next.js's own output rather than reimplementing it. If you want the safer, more proven option, start there.
|
|
113
114
|
- **[Next.js self-hosting](https://nextjs.org/docs/app/building-your-application/deploying#self-hosting)** — Next.js can be deployed to any Node.js server, Docker container, or as a static export.
|
|
114
115
|
|
|
@@ -128,7 +129,7 @@ vinext is a Vite plugin that reimplements the public Next.js API — routing, se
|
|
|
128
129
|
No. vinext is an alternative implementation of the Next.js API surface built on Vite. It does import some Next.js types and utilities, but the core is written from scratch. The goal is not to create a competing framework or add features beyond what Next.js offers — it's an experiment in how far AI-driven development and Vite's toolchain can go in replicating an existing, well-defined API surface.
|
|
129
130
|
|
|
130
131
|
**How is this different from OpenNext?**
|
|
131
|
-
[OpenNext](https://opennext.js.org/) adapts the
|
|
132
|
+
[OpenNext](https://opennext.js.org/) adapts the _output_ of a standard `next build` to run on various platforms. Because it builds on Next.js's own output, it inherits broad API coverage and has been well-tested for much longer. vinext takes a different approach: it reimplements the Next.js APIs on Vite from scratch, which means faster builds and smaller bundles, but less coverage of the long tail of Next.js features. If you need a mature, well-tested way to run Next.js outside Vercel, OpenNext is the safer choice. If you're interested in experimenting with a lighter toolchain and don't need every Next.js API, vinext might be worth a look.
|
|
132
133
|
|
|
133
134
|
**Can I use this in production?**
|
|
134
135
|
You can, with caution. This is experimental software with known bugs. It works well enough for demos and exploration, but it hasn't been battle-tested with real production traffic.
|
|
@@ -197,6 +198,7 @@ vinext deploy --env staging
|
|
|
197
198
|
Use `--env <name>` to target `wrangler.jsonc` `env.<name>`. `--preview` is shorthand for `--env preview`.
|
|
198
199
|
|
|
199
200
|
The deploy command also auto-detects and fixes common migration issues:
|
|
201
|
+
|
|
200
202
|
- Adds `"type": "module"` to package.json if missing
|
|
201
203
|
- Resolves tsconfig.json path aliases automatically (via `vite-tsconfig-paths`)
|
|
202
204
|
- Detects MDX usage and configures `@mdx-js/rollup`
|
|
@@ -228,7 +230,7 @@ Define your bindings in `wrangler.jsonc` as usual:
|
|
|
228
230
|
"compatibility_date": "2026-02-12",
|
|
229
231
|
"compatibility_flags": ["nodejs_compat"],
|
|
230
232
|
"d1_databases": [{ "binding": "DB", "database_name": "my-db", "database_id": "..." }],
|
|
231
|
-
"kv_namespaces": [{ "binding": "CACHE", "id": "..." }]
|
|
233
|
+
"kv_namespaces": [{ "binding": "CACHE", "id": "..." }],
|
|
232
234
|
}
|
|
233
235
|
```
|
|
234
236
|
|
|
@@ -383,16 +385,16 @@ See the [Nitro deployment docs](https://v3.nitro.build/deploy) for the full list
|
|
|
383
385
|
|
|
384
386
|
These are deployed to Cloudflare Workers and updated on every push to `main`:
|
|
385
387
|
|
|
386
|
-
| Example
|
|
387
|
-
|
|
388
|
-
| App Router Playground
|
|
389
|
-
| Hacker News
|
|
390
|
-
| Nextra Docs
|
|
391
|
-
| App Router (minimal)
|
|
392
|
-
| Pages Router (minimal) | Minimal Pages Router on Workers
|
|
393
|
-
| RealWorld API
|
|
394
|
-
| Benchmarks Dashboard
|
|
395
|
-
| App Router + Nitro
|
|
388
|
+
| Example | Description | URL |
|
|
389
|
+
| ---------------------- | ---------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ |
|
|
390
|
+
| App Router Playground | [Vercel's Next.js App Router Playground](https://github.com/vercel/next-app-router-playground) running on vinext | [app-router-playground.vinext.workers.dev](https://app-router-playground.vinext.workers.dev) |
|
|
391
|
+
| Hacker News | HN clone (App Router, RSC) | [hackernews.vinext.workers.dev](https://hackernews.vinext.workers.dev) |
|
|
392
|
+
| Nextra Docs | Nextra docs site (MDX, App Router) | [nextra-docs-template.vinext.workers.dev](https://nextra-docs-template.vinext.workers.dev) |
|
|
393
|
+
| App Router (minimal) | Minimal App Router on Workers | [app-router-cloudflare.vinext.workers.dev](https://app-router-cloudflare.vinext.workers.dev) |
|
|
394
|
+
| Pages Router (minimal) | Minimal Pages Router on Workers | [pages-router-cloudflare.vinext.workers.dev](https://pages-router-cloudflare.vinext.workers.dev) |
|
|
395
|
+
| RealWorld API | REST API routes example | [realworld-api-rest.vinext.workers.dev](https://realworld-api-rest.vinext.workers.dev) |
|
|
396
|
+
| Benchmarks Dashboard | Build performance tracking over time (D1-backed) | [benchmarks.vinext.workers.dev](https://benchmarks.vinext.workers.dev) |
|
|
397
|
+
| App Router + Nitro | App Router deployed via Nitro (multi-platform) | [examples/app-router-nitro](examples/app-router-nitro) |
|
|
396
398
|
|
|
397
399
|
## API coverage
|
|
398
400
|
|
|
@@ -404,78 +406,78 @@ These are deployed to Cloudflare Workers and updated on every push to `main`:
|
|
|
404
406
|
|
|
405
407
|
Every `next/*` import is shimmed to a Vite-compatible implementation.
|
|
406
408
|
|
|
407
|
-
| Module
|
|
408
|
-
|
|
409
|
-
| `next/link`
|
|
410
|
-
| `next/image`
|
|
411
|
-
| `next/head`
|
|
412
|
-
| `next/router`
|
|
413
|
-
| `next/navigation`
|
|
414
|
-
| `next/server`
|
|
415
|
-
| `next/headers`
|
|
416
|
-
| `next/dynamic`
|
|
417
|
-
| `next/script`
|
|
418
|
-
| `next/font/google`
|
|
419
|
-
| `next/font/local`
|
|
420
|
-
| `next/og`
|
|
421
|
-
| `next/cache`
|
|
422
|
-
| `next/form`
|
|
423
|
-
| `next/legacy/image` | ✅
|
|
424
|
-
| `next/error`
|
|
425
|
-
| `next/config`
|
|
426
|
-
| `next/document`
|
|
427
|
-
| `next/constants`
|
|
428
|
-
| `next/amp`
|
|
429
|
-
| `next/web-vitals`
|
|
409
|
+
| Module | | Notes |
|
|
410
|
+
| ------------------- | --- | -------------------------------------------------------------------------------------------------------------------------------------- |
|
|
411
|
+
| `next/link` | ✅ | All props including `prefetch` (IntersectionObserver), `onNavigate`, scroll restoration, `basePath`, `locale` |
|
|
412
|
+
| `next/image` | 🟡 | Remote images via [@unpic/react](https://unpic.pics) (28 CDNs). Local images via `<img>` + srcSet. No build-time optimization/resizing |
|
|
413
|
+
| `next/head` | ✅ | SSR collection + client-side DOM manipulation |
|
|
414
|
+
| `next/router` | ✅ | `useRouter`, `Router` singleton, events, client-side navigation, SSR context, i18n |
|
|
415
|
+
| `next/navigation` | ✅ | `usePathname`, `useSearchParams`, `useParams`, `useRouter`, `redirect`, `notFound`, `forbidden`, `unauthorized` |
|
|
416
|
+
| `next/server` | ✅ | `NextRequest`, `NextResponse`, `NextURL`, cookies, `userAgent`, `after`, `connection`, `URLPattern` |
|
|
417
|
+
| `next/headers` | ✅ | Async `headers()`, `cookies()`, `draftMode()` |
|
|
418
|
+
| `next/dynamic` | ✅ | `ssr: true`, `ssr: false`, `loading` component |
|
|
419
|
+
| `next/script` | ✅ | All 4 strategies (`beforeInteractive`, `afterInteractive`, `lazyOnload`, `worker`) |
|
|
420
|
+
| `next/font/google` | 🟡 | Runtime CDN loading. No self-hosting, font subsetting, or fallback metrics |
|
|
421
|
+
| `next/font/local` | 🟡 | Runtime `@font-face` injection. Not extracted at build time |
|
|
422
|
+
| `next/og` | ✅ | OG image generation via `@vercel/og` (Satori + resvg) |
|
|
423
|
+
| `next/cache` | ✅ | `revalidateTag`, `revalidatePath`, `unstable_cache`, pluggable `CacheHandler`, `"use cache"` with `cacheLife()` and `cacheTag()` |
|
|
424
|
+
| `next/form` | ✅ | GET form interception + POST server action delegation |
|
|
425
|
+
| `next/legacy/image` | ✅ | Translates legacy props to modern Image |
|
|
426
|
+
| `next/error` | ✅ | Default error page component |
|
|
427
|
+
| `next/config` | ✅ | `getConfig` / `setConfig` |
|
|
428
|
+
| `next/document` | ✅ | `Html`, `Head`, `Main`, `NextScript` |
|
|
429
|
+
| `next/constants` | ✅ | All phase constants |
|
|
430
|
+
| `next/amp` | ⬜ | No-op (AMP is deprecated) |
|
|
431
|
+
| `next/web-vitals` | ⬜ | No-op (use the `web-vitals` library directly) |
|
|
430
432
|
|
|
431
433
|
### Routing
|
|
432
434
|
|
|
433
|
-
| Feature
|
|
434
|
-
|
|
435
|
-
| File-system routing (`pages/`)
|
|
436
|
-
| File-system routing (`app/`)
|
|
437
|
-
| Dynamic routes `[param]`
|
|
438
|
-
| Catch-all `[...slug]`
|
|
439
|
-
| Optional catch-all `[[...slug]]` | ✅
|
|
440
|
-
| Route groups `(group)`
|
|
441
|
-
| Parallel routes `@slot`
|
|
442
|
-
| Intercepting routes
|
|
443
|
-
| Route handlers (`route.ts`)
|
|
444
|
-
| Middleware
|
|
445
|
-
| i18n routing
|
|
446
|
-
| `basePath`
|
|
447
|
-
| `trailingSlash`
|
|
435
|
+
| Feature | | Notes |
|
|
436
|
+
| -------------------------------- | --- | ------------------------------------------------------------------------------------------------------------------ |
|
|
437
|
+
| File-system routing (`pages/`) | ✅ | Automatic scanning with hot-reload on file changes |
|
|
438
|
+
| File-system routing (`app/`) | ✅ | Pages, routes, layouts, templates, loading, error, not-found, forbidden, unauthorized |
|
|
439
|
+
| Dynamic routes `[param]` | ✅ | Both routers |
|
|
440
|
+
| Catch-all `[...slug]` | ✅ | Both routers |
|
|
441
|
+
| Optional catch-all `[[...slug]]` | ✅ | Both routers |
|
|
442
|
+
| Route groups `(group)` | ✅ | URL-transparent, layouts still apply |
|
|
443
|
+
| Parallel routes `@slot` | ✅ | Discovery, layout props, `default.tsx`, inherited slots |
|
|
444
|
+
| Intercepting routes | ✅ | `(.)`, `(..)`, `(..)(..)`, `(...)` conventions |
|
|
445
|
+
| Route handlers (`route.ts`) | ✅ | Named HTTP methods, auto OPTIONS/HEAD, cookie attachment |
|
|
446
|
+
| Middleware | ✅ | `middleware.ts` and `proxy.ts` (Next.js 16). Matcher patterns (string, array, regex, `:param`, `:path*`, `:path+`) |
|
|
447
|
+
| i18n routing | 🟡 | Pages Router locale prefix, Accept-Language detection, NEXT_LOCALE cookie. No domain-based routing |
|
|
448
|
+
| `basePath` | ✅ | Applied everywhere — URLs, Link, Router, navigation hooks |
|
|
449
|
+
| `trailingSlash` | ✅ | 308 redirects to canonical form |
|
|
448
450
|
|
|
449
451
|
### Server features
|
|
450
452
|
|
|
451
|
-
| Feature
|
|
452
|
-
|
|
453
|
-
| SSR (Pages Router)
|
|
454
|
-
| SSR (App Router)
|
|
455
|
-
| `getStaticProps`
|
|
456
|
-
| `getStaticPaths`
|
|
457
|
-
| `getServerSideProps`
|
|
458
|
-
| ISR
|
|
459
|
-
| Server Actions (`"use server"`)
|
|
460
|
-
| React Server Components
|
|
461
|
-
| Streaming SSR
|
|
462
|
-
| Metadata API
|
|
463
|
-
| `generateStaticParams`
|
|
464
|
-
| Metadata file routes
|
|
465
|
-
| Static export (`output: 'export'`) | ✅
|
|
466
|
-
| `connection()`
|
|
467
|
-
| `"use cache"` directive
|
|
468
|
-
| `instrumentation.ts`
|
|
469
|
-
| Route segment config
|
|
453
|
+
| Feature | | Notes |
|
|
454
|
+
| ---------------------------------- | --- | ------------------------------------------------------------------------------------------- |
|
|
455
|
+
| SSR (Pages Router) | ✅ | Streaming, `_app`/`_document`, `__NEXT_DATA__`, hydration |
|
|
456
|
+
| SSR (App Router) | ✅ | RSC pipeline, nested layouts, streaming, nav context for client components |
|
|
457
|
+
| `getStaticProps` | ✅ | Props, redirect, notFound, revalidate |
|
|
458
|
+
| `getStaticPaths` | ✅ | `fallback: false`, `true`, `"blocking"` |
|
|
459
|
+
| `getServerSideProps` | ✅ | Full context including locale |
|
|
460
|
+
| ISR | ✅ | Stale-while-revalidate, pluggable `CacheHandler`, background regeneration |
|
|
461
|
+
| Server Actions (`"use server"`) | ✅ | Action execution, FormData, re-render after mutation, `redirect()` in actions |
|
|
462
|
+
| React Server Components | ✅ | Via `@vitejs/plugin-rsc`. `"use client"` boundaries work correctly |
|
|
463
|
+
| Streaming SSR | ✅ | Both routers |
|
|
464
|
+
| Metadata API | ✅ | `metadata`, `generateMetadata`, `viewport`, `generateViewport`, title templates |
|
|
465
|
+
| `generateStaticParams` | ✅ | With `dynamicParams` enforcement |
|
|
466
|
+
| Metadata file routes | ✅ | sitemap.xml, robots.txt, manifest, favicon, OG images (static + dynamic) |
|
|
467
|
+
| Static export (`output: 'export'`) | ✅ | Generates static HTML/JSON for all routes |
|
|
468
|
+
| `connection()` | ✅ | Forces dynamic rendering |
|
|
469
|
+
| `"use cache"` directive | ✅ | File-level and function-level. `cacheLife()` profiles, `cacheTag()`, stale-while-revalidate |
|
|
470
|
+
| `instrumentation.ts` | ✅ | `register()` and `onRequestError()` callbacks |
|
|
471
|
+
| Route segment config | 🟡 | `revalidate`, `dynamic`, `dynamicParams`. `runtime` and `preferredRegion` are ignored |
|
|
470
472
|
|
|
471
473
|
### Configuration
|
|
472
474
|
|
|
473
|
-
| Feature
|
|
474
|
-
|
|
475
|
-
| `next.config.js` / `.ts` / `.mjs`
|
|
476
|
-
| `rewrites` / `redirects` / `headers`
|
|
477
|
-
| Environment variables (`.env*`, `NEXT_PUBLIC_*`) | ✅
|
|
478
|
-
| `images` config
|
|
475
|
+
| Feature | | Notes |
|
|
476
|
+
| ------------------------------------------------ | --- | ------------------------------------------------------------------- |
|
|
477
|
+
| `next.config.js` / `.ts` / `.mjs` | ✅ | Function configs, phase argument |
|
|
478
|
+
| `rewrites` / `redirects` / `headers` | ✅ | All phases, param interpolation |
|
|
479
|
+
| Environment variables (`.env*`, `NEXT_PUBLIC_*`) | ✅ | Auto-loads Next.js-style dotenv files; only public vars are inlined |
|
|
480
|
+
| `images` config | 🟡 | Parsed but not used for optimization |
|
|
479
481
|
|
|
480
482
|
### Environment variable loading (`.env*`)
|
|
481
483
|
|
|
@@ -609,9 +611,14 @@ packages/vinext/
|
|
|
609
611
|
routing/
|
|
610
612
|
pages-router.ts # Pages Router file-system scanner
|
|
611
613
|
app-router.ts # App Router file-system scanner
|
|
614
|
+
entries/
|
|
615
|
+
app-rsc-entry.ts # App Router RSC entry generator
|
|
616
|
+
app-ssr-entry.ts # App Router SSR entry generator
|
|
617
|
+
app-browser-entry.ts # App Router browser entry generator
|
|
618
|
+
pages-server-entry.ts # Pages Router SSR entry generator
|
|
619
|
+
pages-client-entry.ts # Pages Router client entry generator
|
|
612
620
|
server/
|
|
613
621
|
dev-server.ts # Pages Router SSR request handler
|
|
614
|
-
app-dev-server.ts # App Router RSC entry generator
|
|
615
622
|
prod-server.ts # Production server with compression
|
|
616
623
|
api-handler.ts # Pages Router API routes
|
|
617
624
|
isr-cache.ts # ISR cache layer
|
|
@@ -645,6 +652,8 @@ pnpm test # Vitest unit + integration tests
|
|
|
645
652
|
pnpm run test:e2e # Playwright E2E tests (5 projects)
|
|
646
653
|
pnpm run typecheck # TypeScript checking (tsgo)
|
|
647
654
|
pnpm run lint # Linting (oxlint)
|
|
655
|
+
pnpm run fmt # Formatting (oxfmt)
|
|
656
|
+
pnpm run fmt:check # Check formatting without writing
|
|
648
657
|
```
|
|
649
658
|
|
|
650
659
|
E2E tests cover Pages Router (dev + production), App Router (dev), and both routers on Cloudflare Workers via `wrangler dev`.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"static-export.d.ts","sourceRoot":"","sources":["../../src/build/static-export.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,MAAM,CAAC;AAC1C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,4BAA4B,CAAC;AACxD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAuBnE,MAAM,WAAW,mBAAmB;IAClC,+CAA+C;IAC/C,MAAM,EAAE,aAAa,CAAC;IACtB,mDAAmD;IACnD,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,4BAA4B;IAC5B,SAAS,EAAE,KAAK,EAAE,CAAC;IACnB,2BAA2B;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,wCAAwC;IACxC,MAAM,EAAE,MAAM,CAAC;IACf,8BAA8B;IAC9B,MAAM,EAAE,kBAAkB,CAAC;CAC5B;AAED,MAAM,WAAW,kBAAkB;IACjC,qCAAqC;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,gDAAgD;IAChD,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,2BAA2B;IAC3B,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,qDAAqD;IACrD,MAAM,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACjD;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,
|
|
1
|
+
{"version":3,"file":"static-export.d.ts","sourceRoot":"","sources":["../../src/build/static-export.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,MAAM,CAAC;AAC1C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,4BAA4B,CAAC;AACxD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAuBnE,MAAM,WAAW,mBAAmB;IAClC,+CAA+C;IAC/C,MAAM,EAAE,aAAa,CAAC;IACtB,mDAAmD;IACnD,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,4BAA4B;IAC5B,SAAS,EAAE,KAAK,EAAE,CAAC;IACnB,2BAA2B;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,wCAAwC;IACxC,MAAM,EAAE,MAAM,CAAC;IACf,8BAA8B;IAC9B,MAAM,EAAE,kBAAkB,CAAC;CAC5B;AAED,MAAM,WAAW,kBAAkB;IACjC,qCAAqC;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,gDAAgD;IAChD,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,2BAA2B;IAC3B,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,qDAAqD;IACrD,MAAM,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACjD;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAoKjG;AA0WD,MAAM,WAAW,sBAAsB;IACrC,sEAAsE;IACtE,OAAO,EAAE,MAAM,CAAC;IAChB,4BAA4B;IAC5B,MAAM,EAAE,QAAQ,EAAE,CAAC;IACnB,4EAA4E;IAC5E,MAAM,EAAE,MAAM,CAAC;IACf,iDAAiD;IACjD,MAAM,EAAE,aAAa,CAAC;IACtB,uBAAuB;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,8BAA8B;IAC9B,MAAM,EAAE,kBAAkB,CAAC;CAC5B;AAED;;;;;GAKG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,sBAAsB,GAC9B,OAAO,CAAC,kBAAkB,CAAC,CAgI7B"}
|
|
@@ -218,14 +218,13 @@ async function renderStaticPage(options) {
|
|
|
218
218
|
// Render page body
|
|
219
219
|
const bodyHtml = await renderToStringAsync(element);
|
|
220
220
|
// Collect head tags
|
|
221
|
-
const ssrHeadHTML = typeof headShim.getSSRHeadHTML === "function"
|
|
222
|
-
? headShim.getSSRHeadHTML()
|
|
223
|
-
: "";
|
|
221
|
+
const ssrHeadHTML = typeof headShim.getSSRHeadHTML === "function" ? headShim.getSSRHeadHTML() : "";
|
|
224
222
|
// __NEXT_DATA__ for client hydration
|
|
225
223
|
const nextDataScript = `<script>window.__NEXT_DATA__ = ${safeJsonStringify({
|
|
226
224
|
props: { pageProps },
|
|
227
225
|
page: route.pattern,
|
|
228
226
|
query: params,
|
|
227
|
+
buildId: _config.buildId,
|
|
229
228
|
})}</script>`;
|
|
230
229
|
// Build HTML shell
|
|
231
230
|
let html;
|
|
@@ -265,11 +264,7 @@ async function renderStaticPage(options) {
|
|
|
265
264
|
}
|
|
266
265
|
async function renderErrorPage(options) {
|
|
267
266
|
const { server, pagesDir, statusCode, AppComponent, DocumentComponent, headShim, fileMatcher } = options;
|
|
268
|
-
const candidates = statusCode === 404
|
|
269
|
-
? ["404", "_error"]
|
|
270
|
-
: statusCode === 500
|
|
271
|
-
? ["500", "_error"]
|
|
272
|
-
: ["_error"];
|
|
267
|
+
const candidates = statusCode === 404 ? ["404", "_error"] : statusCode === 500 ? ["500", "_error"] : ["_error"];
|
|
273
268
|
for (const candidate of candidates) {
|
|
274
269
|
const candidatePath = path.join(pagesDir, candidate);
|
|
275
270
|
if (!findFileWithExtensions(candidatePath, fileMatcher))
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"static-export.js","sourceRoot":"","sources":["../../src/build/static-export.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Static export for `output: 'export'`.\n *\n * Renders all pages to static HTML files at build time. Produces a directory\n * of HTML + client JS/CSS that can be deployed to any static file host\n * (S3, Cloudflare Pages, GitHub Pages, Nginx, etc.) with no server required.\n *\n * Pages Router:\n * - Static pages → render to HTML\n * - getStaticProps pages → call at build time, render with props\n * - Dynamic routes → call getStaticPaths (must be fallback: false), render each\n * - getServerSideProps → build error\n * - API routes → skipped with warning\n *\n * App Router:\n * - Static pages → run Server Components at build time, render to HTML\n * - Dynamic routes → call generateStaticParams(), render each\n * - Dynamic routes without generateStaticParams → build error\n */\nimport type { ViteDevServer } from \"vite\";\nimport type { Route } from \"../routing/pages-router.js\";\nimport type { AppRoute } from \"../routing/app-router.js\";\nimport type { ResolvedNextConfig } from \"../config/next-config.js\";\nimport { safeJsonStringify } from \"../server/html.js\";\nimport { escapeAttr } from \"../shims/head.js\";\nimport path from \"node:path\";\nimport fs from \"node:fs\";\nimport React from \"react\";\nimport { renderToReadableStream } from \"react-dom/server.edge\";\nimport { createValidFileMatcher, type ValidFileMatcher } from \"../routing/file-matcher.js\";\n\nfunction findFileWithExtensions(basePath: string, matcher: ValidFileMatcher): boolean {\n return matcher.dottedExtensions.some((ext) => fs.existsSync(basePath + ext));\n}\n\n/**\n * Render a React element to string using renderToReadableStream (Suspense support).\n * Uses Web Streams API — works in Node.js 18+ and Cloudflare Workers.\n */\nasync function renderToStringAsync(element: React.ReactElement): Promise<string> {\n const stream = await renderToReadableStream(element);\n await stream.allReady;\n return new Response(stream).text();\n}\n\nexport interface StaticExportOptions {\n /** Vite dev server (for SSR module loading) */\n server: ViteDevServer;\n /** Discovered page routes (excludes API routes) */\n routes: Route[];\n /** Discovered API routes */\n apiRoutes: Route[];\n /** Pages directory path */\n pagesDir: string;\n /** Output directory for static files */\n outDir: string;\n /** Resolved next.config.js */\n config: ResolvedNextConfig;\n}\n\nexport interface StaticExportResult {\n /** Number of HTML files generated */\n pageCount: number;\n /** Generated file paths (relative to outDir) */\n files: string[];\n /** Warnings encountered */\n warnings: string[];\n /** Errors encountered (non-fatal, specific pages) */\n errors: Array<{ route: string; error: string }>;\n}\n\n/**\n * Run static export for Pages Router.\n *\n * Creates a directory of static HTML files by rendering each route at build time.\n */\nexport async function staticExportPages(\n options: StaticExportOptions,\n): Promise<StaticExportResult> {\n const { server, routes, apiRoutes, pagesDir, outDir, config } = options;\n const fileMatcher = createValidFileMatcher(config.pageExtensions);\n const result: StaticExportResult = {\n pageCount: 0,\n files: [],\n warnings: [],\n errors: [],\n };\n\n // Ensure output directory exists\n fs.mkdirSync(outDir, { recursive: true });\n\n // Warn about API routes\n if (apiRoutes.length > 0) {\n result.warnings.push(\n `${apiRoutes.length} API route(s) skipped — API routes are not supported with output: 'export'`,\n );\n }\n\n // Gather all pages to render (expand dynamic routes via getStaticPaths)\n const pagesToRender: Array<{\n route: Route;\n urlPath: string;\n params: Record<string, string | string[]>;\n }> = [];\n\n for (const route of routes) {\n // Skip internal pages\n const routeName = path.basename(route.filePath, path.extname(route.filePath));\n if (routeName.startsWith(\"_\")) continue;\n\n const pageModule = await server.ssrLoadModule(route.filePath);\n\n // Validate: getServerSideProps is not allowed with static export\n if (typeof pageModule.getServerSideProps === \"function\") {\n result.errors.push({\n route: route.pattern,\n error: `Page uses getServerSideProps which is not supported with output: 'export'. Use getStaticProps instead.`,\n });\n continue;\n }\n\n if (route.isDynamic) {\n // Dynamic route — must have getStaticPaths\n if (typeof pageModule.getStaticPaths !== \"function\") {\n result.errors.push({\n route: route.pattern,\n error: `Dynamic route requires getStaticPaths with output: 'export'`,\n });\n continue;\n }\n\n const pathsResult = await pageModule.getStaticPaths({\n locales: [],\n defaultLocale: \"\",\n });\n const fallback = pathsResult?.fallback ?? false;\n\n if (fallback !== false) {\n result.errors.push({\n route: route.pattern,\n error: `getStaticPaths must return fallback: false with output: 'export' (got: ${JSON.stringify(fallback)})`,\n });\n continue;\n }\n\n const paths: Array<{ params: Record<string, string | string[]> }> =\n pathsResult?.paths ?? [];\n\n for (const { params } of paths) {\n // Build the URL path from the route pattern and params\n const urlPath = buildUrlFromParams(route.pattern, params);\n pagesToRender.push({ route, urlPath, params });\n }\n } else {\n // Static route — render directly\n pagesToRender.push({ route, urlPath: route.pattern, params: {} });\n }\n }\n\n // Load shared components (_app, _document, head shim, dynamic shim)\n let AppComponent: React.ComponentType<{\n Component: React.ComponentType;\n pageProps: Record<string, unknown>;\n }> | null = null;\n const appPath = path.join(pagesDir, \"_app\");\n if (findFileWithExtensions(appPath, fileMatcher)) {\n try {\n const appModule = await server.ssrLoadModule(appPath);\n AppComponent = appModule.default ?? null;\n } catch {\n // _app exists but failed to load\n }\n }\n\n let DocumentComponent: React.ComponentType | null = null;\n const docPath = path.join(pagesDir, \"_document\");\n if (findFileWithExtensions(docPath, fileMatcher)) {\n try {\n const docModule = await server.ssrLoadModule(docPath);\n DocumentComponent = docModule.default ?? null;\n } catch {\n // _document exists but failed to load\n }\n }\n\n const headShim = await server.ssrLoadModule(\"next/head\");\n const dynamicShim = await server.ssrLoadModule(\"next/dynamic\");\n const routerShim = await server.ssrLoadModule(\"next/router\");\n\n // Render each page\n for (const { route, urlPath, params } of pagesToRender) {\n try {\n const html = await renderStaticPage({\n server,\n route,\n urlPath,\n params,\n pagesDir,\n config,\n AppComponent,\n DocumentComponent,\n headShim,\n dynamicShim,\n routerShim,\n });\n\n const outputPath = getOutputPath(urlPath, config.trailingSlash);\n const fullPath = path.join(outDir, outputPath);\n fs.mkdirSync(path.dirname(fullPath), { recursive: true });\n fs.writeFileSync(fullPath, html, \"utf-8\");\n\n result.files.push(outputPath);\n result.pageCount++;\n } catch (e) {\n result.errors.push({\n route: urlPath,\n error: (e as Error).message,\n });\n }\n }\n\n // Render 404 page\n try {\n const html404 = await renderErrorPage({\n server,\n pagesDir,\n statusCode: 404,\n AppComponent,\n DocumentComponent,\n headShim,\n fileMatcher,\n });\n if (html404) {\n const fullPath = path.join(outDir, \"404.html\");\n fs.writeFileSync(fullPath, html404, \"utf-8\");\n result.files.push(\"404.html\");\n result.pageCount++;\n }\n } catch {\n // No custom 404, skip\n }\n\n return result;\n}\n\ninterface RenderStaticPageOptions {\n server: ViteDevServer;\n route: Route;\n urlPath: string;\n params: Record<string, string | string[]>;\n pagesDir: string;\n config: ResolvedNextConfig;\n AppComponent: React.ComponentType<{\n Component: React.ComponentType;\n pageProps: Record<string, unknown>;\n }> | null;\n DocumentComponent: React.ComponentType | null;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n headShim: any;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n dynamicShim: any;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n routerShim: any;\n}\n\nasync function renderStaticPage(options: RenderStaticPageOptions): Promise<string> {\n const {\n server,\n route,\n urlPath,\n params,\n config: _config,\n AppComponent,\n DocumentComponent,\n headShim,\n dynamicShim,\n routerShim,\n } = options;\n\n // Set SSR context for router shim\n if (typeof routerShim.setSSRContext === \"function\") {\n routerShim.setSSRContext({\n pathname: urlPath,\n query: params,\n asPath: urlPath,\n });\n }\n\n const pageModule = await server.ssrLoadModule(route.filePath);\n const PageComponent = pageModule.default;\n if (!PageComponent) {\n throw new Error(`Page ${route.filePath} has no default export`);\n }\n\n // Collect page props\n let pageProps: Record<string, unknown> = {};\n\n if (typeof pageModule.getStaticProps === \"function\") {\n const result = await pageModule.getStaticProps({ params });\n if (result && \"props\" in result) {\n pageProps = result.props as Record<string, unknown>;\n }\n if (result && \"redirect\" in result) {\n // Static export can't handle redirects — write a meta redirect\n const redirect = result.redirect as { destination: string };\n return `<!DOCTYPE html><html><head><meta http-equiv=\"refresh\" content=\"0;url=${escapeAttr(redirect.destination)}\" /></head><body></body></html>`;\n }\n if (result && \"notFound\" in result && result.notFound) {\n throw new Error(`Page ${urlPath} returned notFound: true`);\n }\n }\n\n // Build element\n const createElement = React.createElement;\n let element: React.ReactElement;\n\n if (AppComponent) {\n element = createElement(AppComponent, {\n Component: PageComponent,\n pageProps,\n });\n } else {\n element = createElement(PageComponent, pageProps);\n }\n\n // Reset head collector and flush dynamic preloads\n if (typeof headShim.resetSSRHead === \"function\") {\n headShim.resetSSRHead();\n }\n if (typeof dynamicShim.flushPreloads === \"function\") {\n await dynamicShim.flushPreloads();\n }\n\n // Render page body\n const bodyHtml = await renderToStringAsync(element);\n\n // Collect head tags\n const ssrHeadHTML =\n typeof headShim.getSSRHeadHTML === \"function\"\n ? headShim.getSSRHeadHTML()\n : \"\";\n\n // __NEXT_DATA__ for client hydration\n const nextDataScript = `<script>window.__NEXT_DATA__ = ${safeJsonStringify({\n props: { pageProps },\n page: route.pattern,\n query: params,\n })}</script>`;\n\n // Build HTML shell\n let html: string;\n\n if (DocumentComponent) {\n const docElement = createElement(DocumentComponent);\n // renderToReadableStream auto-prepends <!DOCTYPE html> when root is <html>\n let docHtml = await renderToStringAsync(docElement);\n docHtml = docHtml.replace(\"__NEXT_MAIN__\", bodyHtml);\n if (ssrHeadHTML) {\n docHtml = docHtml.replace(\"</head>\", ` ${ssrHeadHTML}\\n</head>`);\n }\n docHtml = docHtml.replace(\"<!-- __NEXT_SCRIPTS__ -->\", nextDataScript);\n if (!docHtml.includes(\"__NEXT_DATA__\")) {\n docHtml = docHtml.replace(\"</body>\", ` ${nextDataScript}\\n</body>`);\n }\n html = docHtml;\n } else {\n html = `<!DOCTYPE html>\n<html>\n<head>\n <meta charset=\"utf-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n ${ssrHeadHTML}\n</head>\n<body>\n <div id=\"__next\">${bodyHtml}</div>\n ${nextDataScript}\n</body>\n</html>`;\n }\n\n // Clear SSR context\n if (typeof routerShim.setSSRContext === \"function\") {\n routerShim.setSSRContext(null);\n }\n\n return html;\n}\n\ninterface RenderErrorPageOptions {\n server: ViteDevServer;\n pagesDir: string;\n statusCode: number;\n AppComponent: React.ComponentType<{\n Component: React.ComponentType;\n pageProps: Record<string, unknown>;\n }> | null;\n DocumentComponent: React.ComponentType | null;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n headShim: any;\n fileMatcher: ValidFileMatcher;\n}\n\nasync function renderErrorPage(\n options: RenderErrorPageOptions,\n): Promise<string | null> {\n const { server, pagesDir, statusCode, AppComponent, DocumentComponent, headShim, fileMatcher } =\n options;\n\n const candidates =\n statusCode === 404\n ? [\"404\", \"_error\"]\n : statusCode === 500\n ? [\"500\", \"_error\"]\n : [\"_error\"];\n\n for (const candidate of candidates) {\n const candidatePath = path.join(pagesDir, candidate);\n if (!findFileWithExtensions(candidatePath, fileMatcher)) continue;\n\n const errorModule = await server.ssrLoadModule(candidatePath);\n const ErrorComponent = errorModule.default;\n if (!ErrorComponent) continue;\n\n const createElement = React.createElement;\n const errorProps = { statusCode };\n\n let element: React.ReactElement;\n if (AppComponent) {\n element = createElement(AppComponent, {\n Component: ErrorComponent,\n pageProps: errorProps,\n });\n } else {\n element = createElement(ErrorComponent, errorProps);\n }\n\n if (typeof headShim.resetSSRHead === \"function\") {\n headShim.resetSSRHead();\n }\n\n const bodyHtml = await renderToStringAsync(element);\n\n let html: string;\n if (DocumentComponent) {\n const docElement = createElement(DocumentComponent);\n let docHtml = await renderToStringAsync(docElement);\n docHtml = docHtml.replace(\"__NEXT_MAIN__\", bodyHtml);\n docHtml = docHtml.replace(\"<!-- __NEXT_SCRIPTS__ -->\", \"\");\n html = docHtml;\n } else {\n html = `<!DOCTYPE html>\n<html>\n<head>\n <meta charset=\"utf-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n</head>\n<body>\n <div id=\"__next\">${bodyHtml}</div>\n</body>\n</html>`;\n }\n\n return html;\n }\n\n return null;\n}\n\n/**\n * Build a URL path from a route pattern and params.\n * E.g., \"/posts/:id\" + { id: \"42\" } → \"/posts/42\"\n * E.g., \"/docs/:slug+\" + { slug: [\"a\", \"b\"] } → \"/docs/a/b\"\n */\nfunction buildUrlFromParams(\n pattern: string,\n params: Record<string, string | string[]>,\n): string {\n const parts = pattern.split(\"/\").filter(Boolean);\n const result: string[] = [];\n\n for (const part of parts) {\n if (part.endsWith(\"+\") || part.endsWith(\"*\")) {\n // Catch-all: :slug+ or :slug*\n const paramName = part.slice(1, -1);\n const value = params[paramName];\n if (Array.isArray(value)) {\n result.push(...value);\n } else if (value) {\n result.push(String(value));\n }\n } else if (part.startsWith(\":\")) {\n // Dynamic segment: :id\n const paramName = part.slice(1);\n const value = params[paramName];\n result.push(String(value));\n } else {\n result.push(part);\n }\n }\n\n return \"/\" + result.join(\"/\");\n}\n\n/**\n * Determine the output file path for a given URL.\n * Respects trailingSlash config.\n */\nfunction getOutputPath(urlPath: string, trailingSlash: boolean): string {\n if (urlPath === \"/\") {\n return \"index.html\";\n }\n\n // Remove leading slash\n const clean = urlPath.replace(/^\\//, \"\");\n\n if (trailingSlash) {\n return `${clean}/index.html`;\n }\n return `${clean}.html`;\n}\n\n/**\n * Resolve parent dynamic segment params for a route.\n *\n * Implements Next.js's top-down params passing for generateStaticParams().\n * Walks up the route hierarchy to find parent dynamic segments that have their\n * own generateStaticParams. Collects parent params by calling each parent's\n * generateStaticParams in order, merging results top-down.\n *\n * Returns an array of parent param combinations. If empty, the child should\n * be called with `{ params: {} }` (bottom-up approach).\n */\nasync function resolveParentParams(\n childRoute: AppRoute,\n allRoutes: AppRoute[],\n server: ViteDevServer,\n): Promise<Record<string, string | string[]>[]> {\n // Extract the dynamic segment names from the pattern\n const patternParts = childRoute.pattern.split(\"/\").filter(Boolean);\n\n // Identify parent dynamic segments: each :param in the pattern except the last one(s)\n // that belong to the leaf page's directory.\n // Strategy: find ancestor routes (layout-level) that export generateStaticParams.\n // An ancestor route's pattern is a prefix of the child's pattern.\n\n // Collect parent segments with generateStaticParams by looking at page modules\n // along the ancestor path. We look for pages/layouts that define generateStaticParams\n // at each level of the path hierarchy.\n type ParentSegment = {\n params: string[];\n generateStaticParams: (opts: { params: Record<string, string | string[]> }) => Promise<Record<string, string | string[]>[]>;\n };\n\n const parentSegments: ParentSegment[] = [];\n\n // Walk pattern parts to find intermediate dynamic segments\n // For /products/:category/:id, we look for a route or layout at /products/:category\n // that has generateStaticParams\n for (let i = 0; i < patternParts.length; i++) {\n const part = patternParts[i];\n if (!part.startsWith(\":\")) continue;\n\n // Check if this is not the last dynamic param (i.e., it's a parent segment)\n const isLastDynamicPart = !patternParts.slice(i + 1).some((p) => p.startsWith(\":\"));\n if (isLastDynamicPart) break; // This is the child's own segment\n\n // Build the prefix pattern up to this segment\n const prefixPattern = \"/\" + patternParts.slice(0, i + 1).join(\"/\");\n\n // Find a route at this prefix that has generateStaticParams\n const parentRoute = allRoutes.find((r) => r.pattern === prefixPattern);\n if (parentRoute?.pagePath) {\n try {\n const parentModule = await server.ssrLoadModule(parentRoute.pagePath);\n if (typeof parentModule.generateStaticParams === \"function\") {\n const paramName = part.replace(/^:/, \"\").replace(/[+*]$/, \"\");\n parentSegments.push({\n params: [paramName],\n generateStaticParams: parentModule.generateStaticParams,\n });\n }\n } catch {\n // Skip — parent module couldn't be loaded\n }\n }\n }\n\n if (parentSegments.length === 0) return [];\n\n // Top-down resolution: call each parent's generateStaticParams in order,\n // accumulating params\n let currentParams: Record<string, string | string[]>[] = [{}];\n\n for (const segment of parentSegments) {\n const nextParams: Record<string, string | string[]>[] = [];\n for (const parentParams of currentParams) {\n const results = await segment.generateStaticParams({ params: parentParams });\n if (Array.isArray(results)) {\n for (const result of results) {\n nextParams.push({ ...parentParams, ...result });\n }\n }\n }\n currentParams = nextParams;\n }\n\n return currentParams;\n}\n\n// -------------------------------------------------------------------\n// App Router static export\n// -------------------------------------------------------------------\n\nexport interface AppStaticExportOptions {\n /** Base URL of a running dev server (e.g. \"http://localhost:5173\") */\n baseUrl: string;\n /** Discovered app routes */\n routes: AppRoute[];\n /** App directory path (for loading modules to call generateStaticParams) */\n appDir: string;\n /** Vite dev server (for loading page modules) */\n server: ViteDevServer;\n /** Output directory */\n outDir: string;\n /** Resolved next.config.js */\n config: ResolvedNextConfig;\n}\n\n/**\n * Run static export for App Router.\n *\n * Fetches each route from a running dev server and writes the HTML to disk.\n * For dynamic routes, calls generateStaticParams() to expand all paths.\n */\nexport async function staticExportApp(\n options: AppStaticExportOptions,\n): Promise<StaticExportResult> {\n const { baseUrl, routes, server, outDir, config } = options;\n const result: StaticExportResult = {\n pageCount: 0,\n files: [],\n warnings: [],\n errors: [],\n };\n\n fs.mkdirSync(outDir, { recursive: true });\n\n // Collect all URLs to render\n const urlsToRender: string[] = [];\n\n for (const route of routes) {\n // Skip API route handlers — not supported in static export\n if (route.routePath && !route.pagePath) {\n result.warnings.push(\n `Route handler ${route.pattern} skipped — API routes are not supported with output: 'export'`,\n );\n continue;\n }\n\n if (!route.pagePath) continue;\n\n if (route.isDynamic) {\n // Dynamic route — must have generateStaticParams\n try {\n const pageModule = await server.ssrLoadModule(route.pagePath);\n\n if (typeof pageModule.generateStaticParams !== \"function\") {\n result.errors.push({\n route: route.pattern,\n error: `Dynamic route requires generateStaticParams() with output: 'export'`,\n });\n continue;\n }\n\n // Resolve parent dynamic segments for top-down params passing.\n // Find all other routes whose patterns are prefixes of this route's pattern\n // and that have dynamic params, then collect their generateStaticParams.\n const parentParamSets = await resolveParentParams(route, routes, server);\n\n let paramSets: Record<string, string | string[]>[];\n if (parentParamSets.length > 0) {\n // Top-down: call child's generateStaticParams for each parent param set\n paramSets = [];\n for (const parentParams of parentParamSets) {\n const childResults = await pageModule.generateStaticParams({ params: parentParams });\n if (Array.isArray(childResults)) {\n for (const childParams of childResults) {\n paramSets.push({ ...parentParams, ...childParams });\n }\n }\n }\n } else {\n // Bottom-up: no parent params, call with empty params\n paramSets = await pageModule.generateStaticParams({ params: {} });\n }\n\n if (!Array.isArray(paramSets) || paramSets.length === 0) {\n result.warnings.push(\n `generateStaticParams() for ${route.pattern} returned empty array — no pages generated`,\n );\n continue;\n }\n\n for (const params of paramSets) {\n const urlPath = buildUrlFromParams(route.pattern, params);\n urlsToRender.push(urlPath);\n }\n } catch (e) {\n result.errors.push({\n route: route.pattern,\n error: `Failed to call generateStaticParams(): ${(e as Error).message}`,\n });\n }\n } else {\n // Static route\n urlsToRender.push(route.pattern);\n }\n }\n\n // Fetch each URL from the dev server and write HTML\n for (const urlPath of urlsToRender) {\n try {\n const res = await fetch(`${baseUrl}${urlPath}`);\n if (!res.ok) {\n result.errors.push({\n route: urlPath,\n error: `Server returned ${res.status}`,\n });\n continue;\n }\n\n const html = await res.text();\n const outputPath = getOutputPath(urlPath, config.trailingSlash);\n const fullPath = path.join(outDir, outputPath);\n fs.mkdirSync(path.dirname(fullPath), { recursive: true });\n fs.writeFileSync(fullPath, html, \"utf-8\");\n\n result.files.push(outputPath);\n result.pageCount++;\n } catch (e) {\n result.errors.push({\n route: urlPath,\n error: (e as Error).message,\n });\n }\n }\n\n // Render 404 page\n try {\n const res = await fetch(`${baseUrl}/__nonexistent_page_for_404__`);\n if (res.status === 404) {\n const html = await res.text();\n if (html.length > 0) {\n const fullPath = path.join(outDir, \"404.html\");\n fs.writeFileSync(fullPath, html, \"utf-8\");\n result.files.push(\"404.html\");\n result.pageCount++;\n }\n }\n } catch {\n // No custom 404, skip\n }\n\n return result;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"static-export.js","sourceRoot":"","sources":["../../src/build/static-export.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Static export for `output: 'export'`.\n *\n * Renders all pages to static HTML files at build time. Produces a directory\n * of HTML + client JS/CSS that can be deployed to any static file host\n * (S3, Cloudflare Pages, GitHub Pages, Nginx, etc.) with no server required.\n *\n * Pages Router:\n * - Static pages → render to HTML\n * - getStaticProps pages → call at build time, render with props\n * - Dynamic routes → call getStaticPaths (must be fallback: false), render each\n * - getServerSideProps → build error\n * - API routes → skipped with warning\n *\n * App Router:\n * - Static pages → run Server Components at build time, render to HTML\n * - Dynamic routes → call generateStaticParams(), render each\n * - Dynamic routes without generateStaticParams → build error\n */\nimport type { ViteDevServer } from \"vite\";\nimport type { Route } from \"../routing/pages-router.js\";\nimport type { AppRoute } from \"../routing/app-router.js\";\nimport type { ResolvedNextConfig } from \"../config/next-config.js\";\nimport { safeJsonStringify } from \"../server/html.js\";\nimport { escapeAttr } from \"../shims/head.js\";\nimport path from \"node:path\";\nimport fs from \"node:fs\";\nimport React from \"react\";\nimport { renderToReadableStream } from \"react-dom/server.edge\";\nimport { createValidFileMatcher, type ValidFileMatcher } from \"../routing/file-matcher.js\";\n\nfunction findFileWithExtensions(basePath: string, matcher: ValidFileMatcher): boolean {\n return matcher.dottedExtensions.some((ext) => fs.existsSync(basePath + ext));\n}\n\n/**\n * Render a React element to string using renderToReadableStream (Suspense support).\n * Uses Web Streams API — works in Node.js 18+ and Cloudflare Workers.\n */\nasync function renderToStringAsync(element: React.ReactElement): Promise<string> {\n const stream = await renderToReadableStream(element);\n await stream.allReady;\n return new Response(stream).text();\n}\n\nexport interface StaticExportOptions {\n /** Vite dev server (for SSR module loading) */\n server: ViteDevServer;\n /** Discovered page routes (excludes API routes) */\n routes: Route[];\n /** Discovered API routes */\n apiRoutes: Route[];\n /** Pages directory path */\n pagesDir: string;\n /** Output directory for static files */\n outDir: string;\n /** Resolved next.config.js */\n config: ResolvedNextConfig;\n}\n\nexport interface StaticExportResult {\n /** Number of HTML files generated */\n pageCount: number;\n /** Generated file paths (relative to outDir) */\n files: string[];\n /** Warnings encountered */\n warnings: string[];\n /** Errors encountered (non-fatal, specific pages) */\n errors: Array<{ route: string; error: string }>;\n}\n\n/**\n * Run static export for Pages Router.\n *\n * Creates a directory of static HTML files by rendering each route at build time.\n */\nexport async function staticExportPages(options: StaticExportOptions): Promise<StaticExportResult> {\n const { server, routes, apiRoutes, pagesDir, outDir, config } = options;\n const fileMatcher = createValidFileMatcher(config.pageExtensions);\n const result: StaticExportResult = {\n pageCount: 0,\n files: [],\n warnings: [],\n errors: [],\n };\n\n // Ensure output directory exists\n fs.mkdirSync(outDir, { recursive: true });\n\n // Warn about API routes\n if (apiRoutes.length > 0) {\n result.warnings.push(\n `${apiRoutes.length} API route(s) skipped — API routes are not supported with output: 'export'`,\n );\n }\n\n // Gather all pages to render (expand dynamic routes via getStaticPaths)\n const pagesToRender: Array<{\n route: Route;\n urlPath: string;\n params: Record<string, string | string[]>;\n }> = [];\n\n for (const route of routes) {\n // Skip internal pages\n const routeName = path.basename(route.filePath, path.extname(route.filePath));\n if (routeName.startsWith(\"_\")) continue;\n\n const pageModule = await server.ssrLoadModule(route.filePath);\n\n // Validate: getServerSideProps is not allowed with static export\n if (typeof pageModule.getServerSideProps === \"function\") {\n result.errors.push({\n route: route.pattern,\n error: `Page uses getServerSideProps which is not supported with output: 'export'. Use getStaticProps instead.`,\n });\n continue;\n }\n\n if (route.isDynamic) {\n // Dynamic route — must have getStaticPaths\n if (typeof pageModule.getStaticPaths !== \"function\") {\n result.errors.push({\n route: route.pattern,\n error: `Dynamic route requires getStaticPaths with output: 'export'`,\n });\n continue;\n }\n\n const pathsResult = await pageModule.getStaticPaths({\n locales: [],\n defaultLocale: \"\",\n });\n const fallback = pathsResult?.fallback ?? false;\n\n if (fallback !== false) {\n result.errors.push({\n route: route.pattern,\n error: `getStaticPaths must return fallback: false with output: 'export' (got: ${JSON.stringify(fallback)})`,\n });\n continue;\n }\n\n const paths: Array<{ params: Record<string, string | string[]> }> = pathsResult?.paths ?? [];\n\n for (const { params } of paths) {\n // Build the URL path from the route pattern and params\n const urlPath = buildUrlFromParams(route.pattern, params);\n pagesToRender.push({ route, urlPath, params });\n }\n } else {\n // Static route — render directly\n pagesToRender.push({ route, urlPath: route.pattern, params: {} });\n }\n }\n\n // Load shared components (_app, _document, head shim, dynamic shim)\n let AppComponent: React.ComponentType<{\n Component: React.ComponentType;\n pageProps: Record<string, unknown>;\n }> | null = null;\n const appPath = path.join(pagesDir, \"_app\");\n if (findFileWithExtensions(appPath, fileMatcher)) {\n try {\n const appModule = await server.ssrLoadModule(appPath);\n AppComponent = appModule.default ?? null;\n } catch {\n // _app exists but failed to load\n }\n }\n\n let DocumentComponent: React.ComponentType | null = null;\n const docPath = path.join(pagesDir, \"_document\");\n if (findFileWithExtensions(docPath, fileMatcher)) {\n try {\n const docModule = await server.ssrLoadModule(docPath);\n DocumentComponent = docModule.default ?? null;\n } catch {\n // _document exists but failed to load\n }\n }\n\n const headShim = await server.ssrLoadModule(\"next/head\");\n const dynamicShim = await server.ssrLoadModule(\"next/dynamic\");\n const routerShim = await server.ssrLoadModule(\"next/router\");\n\n // Render each page\n for (const { route, urlPath, params } of pagesToRender) {\n try {\n const html = await renderStaticPage({\n server,\n route,\n urlPath,\n params,\n pagesDir,\n config,\n AppComponent,\n DocumentComponent,\n headShim,\n dynamicShim,\n routerShim,\n });\n\n const outputPath = getOutputPath(urlPath, config.trailingSlash);\n const fullPath = path.join(outDir, outputPath);\n fs.mkdirSync(path.dirname(fullPath), { recursive: true });\n fs.writeFileSync(fullPath, html, \"utf-8\");\n\n result.files.push(outputPath);\n result.pageCount++;\n } catch (e) {\n result.errors.push({\n route: urlPath,\n error: (e as Error).message,\n });\n }\n }\n\n // Render 404 page\n try {\n const html404 = await renderErrorPage({\n server,\n pagesDir,\n statusCode: 404,\n AppComponent,\n DocumentComponent,\n headShim,\n fileMatcher,\n });\n if (html404) {\n const fullPath = path.join(outDir, \"404.html\");\n fs.writeFileSync(fullPath, html404, \"utf-8\");\n result.files.push(\"404.html\");\n result.pageCount++;\n }\n } catch {\n // No custom 404, skip\n }\n\n return result;\n}\n\ninterface RenderStaticPageOptions {\n server: ViteDevServer;\n route: Route;\n urlPath: string;\n params: Record<string, string | string[]>;\n pagesDir: string;\n config: ResolvedNextConfig;\n AppComponent: React.ComponentType<{\n Component: React.ComponentType;\n pageProps: Record<string, unknown>;\n }> | null;\n DocumentComponent: React.ComponentType | null;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n headShim: any;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n dynamicShim: any;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n routerShim: any;\n}\n\nasync function renderStaticPage(options: RenderStaticPageOptions): Promise<string> {\n const {\n server,\n route,\n urlPath,\n params,\n config: _config,\n AppComponent,\n DocumentComponent,\n headShim,\n dynamicShim,\n routerShim,\n } = options;\n\n // Set SSR context for router shim\n if (typeof routerShim.setSSRContext === \"function\") {\n routerShim.setSSRContext({\n pathname: urlPath,\n query: params,\n asPath: urlPath,\n });\n }\n\n const pageModule = await server.ssrLoadModule(route.filePath);\n const PageComponent = pageModule.default;\n if (!PageComponent) {\n throw new Error(`Page ${route.filePath} has no default export`);\n }\n\n // Collect page props\n let pageProps: Record<string, unknown> = {};\n\n if (typeof pageModule.getStaticProps === \"function\") {\n const result = await pageModule.getStaticProps({ params });\n if (result && \"props\" in result) {\n pageProps = result.props as Record<string, unknown>;\n }\n if (result && \"redirect\" in result) {\n // Static export can't handle redirects — write a meta redirect\n const redirect = result.redirect as { destination: string };\n return `<!DOCTYPE html><html><head><meta http-equiv=\"refresh\" content=\"0;url=${escapeAttr(redirect.destination)}\" /></head><body></body></html>`;\n }\n if (result && \"notFound\" in result && result.notFound) {\n throw new Error(`Page ${urlPath} returned notFound: true`);\n }\n }\n\n // Build element\n const createElement = React.createElement;\n let element: React.ReactElement;\n\n if (AppComponent) {\n element = createElement(AppComponent, {\n Component: PageComponent,\n pageProps,\n });\n } else {\n element = createElement(PageComponent, pageProps);\n }\n\n // Reset head collector and flush dynamic preloads\n if (typeof headShim.resetSSRHead === \"function\") {\n headShim.resetSSRHead();\n }\n if (typeof dynamicShim.flushPreloads === \"function\") {\n await dynamicShim.flushPreloads();\n }\n\n // Render page body\n const bodyHtml = await renderToStringAsync(element);\n\n // Collect head tags\n const ssrHeadHTML =\n typeof headShim.getSSRHeadHTML === \"function\" ? headShim.getSSRHeadHTML() : \"\";\n\n // __NEXT_DATA__ for client hydration\n const nextDataScript = `<script>window.__NEXT_DATA__ = ${safeJsonStringify({\n props: { pageProps },\n page: route.pattern,\n query: params,\n buildId: _config.buildId,\n })}</script>`;\n\n // Build HTML shell\n let html: string;\n\n if (DocumentComponent) {\n const docElement = createElement(DocumentComponent);\n // renderToReadableStream auto-prepends <!DOCTYPE html> when root is <html>\n let docHtml = await renderToStringAsync(docElement);\n docHtml = docHtml.replace(\"__NEXT_MAIN__\", bodyHtml);\n if (ssrHeadHTML) {\n docHtml = docHtml.replace(\"</head>\", ` ${ssrHeadHTML}\\n</head>`);\n }\n docHtml = docHtml.replace(\"<!-- __NEXT_SCRIPTS__ -->\", nextDataScript);\n if (!docHtml.includes(\"__NEXT_DATA__\")) {\n docHtml = docHtml.replace(\"</body>\", ` ${nextDataScript}\\n</body>`);\n }\n html = docHtml;\n } else {\n html = `<!DOCTYPE html>\n<html>\n<head>\n <meta charset=\"utf-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n ${ssrHeadHTML}\n</head>\n<body>\n <div id=\"__next\">${bodyHtml}</div>\n ${nextDataScript}\n</body>\n</html>`;\n }\n\n // Clear SSR context\n if (typeof routerShim.setSSRContext === \"function\") {\n routerShim.setSSRContext(null);\n }\n\n return html;\n}\n\ninterface RenderErrorPageOptions {\n server: ViteDevServer;\n pagesDir: string;\n statusCode: number;\n AppComponent: React.ComponentType<{\n Component: React.ComponentType;\n pageProps: Record<string, unknown>;\n }> | null;\n DocumentComponent: React.ComponentType | null;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n headShim: any;\n fileMatcher: ValidFileMatcher;\n}\n\nasync function renderErrorPage(options: RenderErrorPageOptions): Promise<string | null> {\n const { server, pagesDir, statusCode, AppComponent, DocumentComponent, headShim, fileMatcher } =\n options;\n\n const candidates =\n statusCode === 404 ? [\"404\", \"_error\"] : statusCode === 500 ? [\"500\", \"_error\"] : [\"_error\"];\n\n for (const candidate of candidates) {\n const candidatePath = path.join(pagesDir, candidate);\n if (!findFileWithExtensions(candidatePath, fileMatcher)) continue;\n\n const errorModule = await server.ssrLoadModule(candidatePath);\n const ErrorComponent = errorModule.default;\n if (!ErrorComponent) continue;\n\n const createElement = React.createElement;\n const errorProps = { statusCode };\n\n let element: React.ReactElement;\n if (AppComponent) {\n element = createElement(AppComponent, {\n Component: ErrorComponent,\n pageProps: errorProps,\n });\n } else {\n element = createElement(ErrorComponent, errorProps);\n }\n\n if (typeof headShim.resetSSRHead === \"function\") {\n headShim.resetSSRHead();\n }\n\n const bodyHtml = await renderToStringAsync(element);\n\n let html: string;\n if (DocumentComponent) {\n const docElement = createElement(DocumentComponent);\n let docHtml = await renderToStringAsync(docElement);\n docHtml = docHtml.replace(\"__NEXT_MAIN__\", bodyHtml);\n docHtml = docHtml.replace(\"<!-- __NEXT_SCRIPTS__ -->\", \"\");\n html = docHtml;\n } else {\n html = `<!DOCTYPE html>\n<html>\n<head>\n <meta charset=\"utf-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n</head>\n<body>\n <div id=\"__next\">${bodyHtml}</div>\n</body>\n</html>`;\n }\n\n return html;\n }\n\n return null;\n}\n\n/**\n * Build a URL path from a route pattern and params.\n * E.g., \"/posts/:id\" + { id: \"42\" } → \"/posts/42\"\n * E.g., \"/docs/:slug+\" + { slug: [\"a\", \"b\"] } → \"/docs/a/b\"\n */\nfunction buildUrlFromParams(pattern: string, params: Record<string, string | string[]>): string {\n const parts = pattern.split(\"/\").filter(Boolean);\n const result: string[] = [];\n\n for (const part of parts) {\n if (part.endsWith(\"+\") || part.endsWith(\"*\")) {\n // Catch-all: :slug+ or :slug*\n const paramName = part.slice(1, -1);\n const value = params[paramName];\n if (Array.isArray(value)) {\n result.push(...value);\n } else if (value) {\n result.push(String(value));\n }\n } else if (part.startsWith(\":\")) {\n // Dynamic segment: :id\n const paramName = part.slice(1);\n const value = params[paramName];\n result.push(String(value));\n } else {\n result.push(part);\n }\n }\n\n return \"/\" + result.join(\"/\");\n}\n\n/**\n * Determine the output file path for a given URL.\n * Respects trailingSlash config.\n */\nfunction getOutputPath(urlPath: string, trailingSlash: boolean): string {\n if (urlPath === \"/\") {\n return \"index.html\";\n }\n\n // Remove leading slash\n const clean = urlPath.replace(/^\\//, \"\");\n\n if (trailingSlash) {\n return `${clean}/index.html`;\n }\n return `${clean}.html`;\n}\n\n/**\n * Resolve parent dynamic segment params for a route.\n *\n * Implements Next.js's top-down params passing for generateStaticParams().\n * Walks up the route hierarchy to find parent dynamic segments that have their\n * own generateStaticParams. Collects parent params by calling each parent's\n * generateStaticParams in order, merging results top-down.\n *\n * Returns an array of parent param combinations. If empty, the child should\n * be called with `{ params: {} }` (bottom-up approach).\n */\nasync function resolveParentParams(\n childRoute: AppRoute,\n allRoutes: AppRoute[],\n server: ViteDevServer,\n): Promise<Record<string, string | string[]>[]> {\n // Extract the dynamic segment names from the pattern\n const patternParts = childRoute.pattern.split(\"/\").filter(Boolean);\n\n // Identify parent dynamic segments: each :param in the pattern except the last one(s)\n // that belong to the leaf page's directory.\n // Strategy: find ancestor routes (layout-level) that export generateStaticParams.\n // An ancestor route's pattern is a prefix of the child's pattern.\n\n // Collect parent segments with generateStaticParams by looking at page modules\n // along the ancestor path. We look for pages/layouts that define generateStaticParams\n // at each level of the path hierarchy.\n type ParentSegment = {\n params: string[];\n generateStaticParams: (opts: {\n params: Record<string, string | string[]>;\n }) => Promise<Record<string, string | string[]>[]>;\n };\n\n const parentSegments: ParentSegment[] = [];\n\n // Walk pattern parts to find intermediate dynamic segments\n // For /products/:category/:id, we look for a route or layout at /products/:category\n // that has generateStaticParams\n for (let i = 0; i < patternParts.length; i++) {\n const part = patternParts[i];\n if (!part.startsWith(\":\")) continue;\n\n // Check if this is not the last dynamic param (i.e., it's a parent segment)\n const isLastDynamicPart = !patternParts.slice(i + 1).some((p) => p.startsWith(\":\"));\n if (isLastDynamicPart) break; // This is the child's own segment\n\n // Build the prefix pattern up to this segment\n const prefixPattern = \"/\" + patternParts.slice(0, i + 1).join(\"/\");\n\n // Find a route at this prefix that has generateStaticParams\n const parentRoute = allRoutes.find((r) => r.pattern === prefixPattern);\n if (parentRoute?.pagePath) {\n try {\n const parentModule = await server.ssrLoadModule(parentRoute.pagePath);\n if (typeof parentModule.generateStaticParams === \"function\") {\n const paramName = part.replace(/^:/, \"\").replace(/[+*]$/, \"\");\n parentSegments.push({\n params: [paramName],\n generateStaticParams: parentModule.generateStaticParams,\n });\n }\n } catch {\n // Skip — parent module couldn't be loaded\n }\n }\n }\n\n if (parentSegments.length === 0) return [];\n\n // Top-down resolution: call each parent's generateStaticParams in order,\n // accumulating params\n let currentParams: Record<string, string | string[]>[] = [{}];\n\n for (const segment of parentSegments) {\n const nextParams: Record<string, string | string[]>[] = [];\n for (const parentParams of currentParams) {\n const results = await segment.generateStaticParams({ params: parentParams });\n if (Array.isArray(results)) {\n for (const result of results) {\n nextParams.push({ ...parentParams, ...result });\n }\n }\n }\n currentParams = nextParams;\n }\n\n return currentParams;\n}\n\n// -------------------------------------------------------------------\n// App Router static export\n// -------------------------------------------------------------------\n\nexport interface AppStaticExportOptions {\n /** Base URL of a running dev server (e.g. \"http://localhost:5173\") */\n baseUrl: string;\n /** Discovered app routes */\n routes: AppRoute[];\n /** App directory path (for loading modules to call generateStaticParams) */\n appDir: string;\n /** Vite dev server (for loading page modules) */\n server: ViteDevServer;\n /** Output directory */\n outDir: string;\n /** Resolved next.config.js */\n config: ResolvedNextConfig;\n}\n\n/**\n * Run static export for App Router.\n *\n * Fetches each route from a running dev server and writes the HTML to disk.\n * For dynamic routes, calls generateStaticParams() to expand all paths.\n */\nexport async function staticExportApp(\n options: AppStaticExportOptions,\n): Promise<StaticExportResult> {\n const { baseUrl, routes, server, outDir, config } = options;\n const result: StaticExportResult = {\n pageCount: 0,\n files: [],\n warnings: [],\n errors: [],\n };\n\n fs.mkdirSync(outDir, { recursive: true });\n\n // Collect all URLs to render\n const urlsToRender: string[] = [];\n\n for (const route of routes) {\n // Skip API route handlers — not supported in static export\n if (route.routePath && !route.pagePath) {\n result.warnings.push(\n `Route handler ${route.pattern} skipped — API routes are not supported with output: 'export'`,\n );\n continue;\n }\n\n if (!route.pagePath) continue;\n\n if (route.isDynamic) {\n // Dynamic route — must have generateStaticParams\n try {\n const pageModule = await server.ssrLoadModule(route.pagePath);\n\n if (typeof pageModule.generateStaticParams !== \"function\") {\n result.errors.push({\n route: route.pattern,\n error: `Dynamic route requires generateStaticParams() with output: 'export'`,\n });\n continue;\n }\n\n // Resolve parent dynamic segments for top-down params passing.\n // Find all other routes whose patterns are prefixes of this route's pattern\n // and that have dynamic params, then collect their generateStaticParams.\n const parentParamSets = await resolveParentParams(route, routes, server);\n\n let paramSets: Record<string, string | string[]>[];\n if (parentParamSets.length > 0) {\n // Top-down: call child's generateStaticParams for each parent param set\n paramSets = [];\n for (const parentParams of parentParamSets) {\n const childResults = await pageModule.generateStaticParams({ params: parentParams });\n if (Array.isArray(childResults)) {\n for (const childParams of childResults) {\n paramSets.push({ ...parentParams, ...childParams });\n }\n }\n }\n } else {\n // Bottom-up: no parent params, call with empty params\n paramSets = await pageModule.generateStaticParams({ params: {} });\n }\n\n if (!Array.isArray(paramSets) || paramSets.length === 0) {\n result.warnings.push(\n `generateStaticParams() for ${route.pattern} returned empty array — no pages generated`,\n );\n continue;\n }\n\n for (const params of paramSets) {\n const urlPath = buildUrlFromParams(route.pattern, params);\n urlsToRender.push(urlPath);\n }\n } catch (e) {\n result.errors.push({\n route: route.pattern,\n error: `Failed to call generateStaticParams(): ${(e as Error).message}`,\n });\n }\n } else {\n // Static route\n urlsToRender.push(route.pattern);\n }\n }\n\n // Fetch each URL from the dev server and write HTML\n for (const urlPath of urlsToRender) {\n try {\n const res = await fetch(`${baseUrl}${urlPath}`);\n if (!res.ok) {\n result.errors.push({\n route: urlPath,\n error: `Server returned ${res.status}`,\n });\n continue;\n }\n\n const html = await res.text();\n const outputPath = getOutputPath(urlPath, config.trailingSlash);\n const fullPath = path.join(outDir, outputPath);\n fs.mkdirSync(path.dirname(fullPath), { recursive: true });\n fs.writeFileSync(fullPath, html, \"utf-8\");\n\n result.files.push(outputPath);\n result.pageCount++;\n } catch (e) {\n result.errors.push({\n route: urlPath,\n error: (e as Error).message,\n });\n }\n }\n\n // Render 404 page\n try {\n const res = await fetch(`${baseUrl}/__nonexistent_page_for_404__`);\n if (res.status === 404) {\n const html = await res.text();\n if (html.length > 0) {\n const fullPath = path.join(outDir, \"404.html\");\n fs.writeFileSync(fullPath, html, \"utf-8\");\n result.files.push(\"404.html\");\n result.pageCount++;\n }\n }\n } catch {\n // No custom 404, skip\n }\n\n return result;\n}\n"]}
|
package/dist/check.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../src/check.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAQH,KAAK,MAAM,GAAG,WAAW,GAAG,SAAS,GAAG,aAAa,CAAC;AAEtD,UAAU,SAAS;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,SAAS,EAAE,CAAC;IACrB,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,SAAS,EAAE,SAAS,EAAE,CAAC;IACvB,WAAW,EAAE,SAAS,EAAE,CAAC;IACzB,OAAO,EAAE;QACP,SAAS,EAAE,MAAM,CAAC;QAClB,OAAO,EAAE,MAAM,CAAC;QAChB,WAAW,EAAE,MAAM,CAAC;QACpB,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;CACH;
|
|
1
|
+
{"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../src/check.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAQH,KAAK,MAAM,GAAG,WAAW,GAAG,SAAS,GAAG,aAAa,CAAC;AAEtD,UAAU,SAAS;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,SAAS,EAAE,CAAC;IACrB,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,SAAS,EAAE,SAAS,EAAE,CAAC;IACvB,WAAW,EAAE,SAAS,EAAE,CAAC;IACzB,OAAO,EAAE;QACP,SAAS,EAAE,MAAM,CAAC;QAClB,OAAO,EAAE,MAAM,CAAC;QAChB,WAAW,EAAE,MAAM,CAAC;QACpB,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;CACH;AAuJD;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,CA8DrD;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,CAsFvD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,CAyBxD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,CA0K1D;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAqBlD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,WAAW,EAAE,IAAI,CAAC,EAAE;IAAE,cAAc,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,MAAM,CAyH7F"}
|