vinext 0.2.0 → 1.0.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +50 -29
- package/dist/build/client-build-config.d.ts +13 -92
- package/dist/build/client-build-config.js +17 -95
- package/dist/build/css-url-assets.d.ts +3 -1
- package/dist/build/css-url-assets.js +18 -1
- package/dist/build/inject-pregenerated-paths.d.ts +3 -0
- package/dist/build/inject-pregenerated-paths.js +4 -1
- package/dist/build/prerender-paths.d.ts +23 -0
- package/dist/build/prerender-paths.js +296 -0
- package/dist/build/prerender-server-entry.d.ts +1 -0
- package/dist/build/prerender-server-entry.js +49 -0
- package/dist/build/prerender-server-pool.d.ts +44 -0
- package/dist/build/prerender-server-pool.js +194 -0
- package/dist/build/prerender.d.ts +12 -1
- package/dist/build/prerender.js +87 -23
- package/dist/build/run-prerender.js +2 -1
- package/dist/cache/cache-adapters-virtual.d.ts +7 -1
- package/dist/cache/cache-adapters-virtual.js +26 -2
- package/dist/check.d.ts +4 -6
- package/dist/check.js +13 -9
- package/dist/cli.js +34 -54
- package/dist/client/vinext-next-data.d.ts +4 -1
- package/dist/config/config-matchers.js +33 -11
- package/dist/config/next-config.d.ts +36 -6
- package/dist/config/next-config.js +17 -4
- package/dist/config/prerender.d.ts +11 -1
- package/dist/config/prerender.js +19 -1
- package/dist/config/tsconfig-paths.js +5 -1
- package/dist/entries/app-browser-entry.js +5 -1
- package/dist/entries/app-rsc-entry.d.ts +3 -2
- package/dist/entries/app-rsc-entry.js +4 -0
- package/dist/entries/pages-client-entry.js +14 -3
- package/dist/entries/pages-server-entry.js +18 -4
- package/dist/image/image-adapters-virtual.js +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +549 -152
- package/dist/init-cloudflare.js +12 -3
- package/dist/init-platform.d.ts +10 -1
- package/dist/init-platform.js +78 -12
- package/dist/init.d.ts +11 -3
- package/dist/init.js +129 -31
- package/dist/plugins/fonts.js +1 -1
- package/dist/plugins/ignore-dynamic-requests.js +1 -1
- package/dist/plugins/og-assets.js +2 -1
- package/dist/plugins/optimize-imports.js +1 -1
- package/dist/plugins/rsc-reference-validation-normalizer.d.ts +12 -0
- package/dist/plugins/rsc-reference-validation-normalizer.js +48 -0
- package/dist/plugins/sass.d.ts +17 -1
- package/dist/plugins/sass.js +74 -1
- package/dist/plugins/styled-jsx.d.ts +16 -0
- package/dist/plugins/styled-jsx.js +149 -0
- package/dist/routing/app-route-graph.js +22 -16
- package/dist/routing/file-matcher.d.ts +8 -1
- package/dist/routing/file-matcher.js +15 -3
- package/dist/server/app-browser-entry.js +44 -14
- package/dist/server/app-browser-navigation-controller.js +5 -2
- package/dist/server/app-browser-server-action-client.js +5 -3
- package/dist/server/app-browser-state.d.ts +1 -0
- package/dist/server/app-browser-state.js +1 -1
- package/dist/server/app-layout-param-observation.d.ts +1 -1
- package/dist/server/app-page-boundary.js +2 -1
- package/dist/server/app-page-cache-finalizer.d.ts +1 -0
- package/dist/server/app-page-cache-finalizer.js +3 -3
- package/dist/server/app-page-cache-render.d.ts +1 -1
- package/dist/server/app-page-cache.js +23 -6
- package/dist/server/app-page-dispatch.d.ts +2 -1
- package/dist/server/app-page-dispatch.js +27 -10
- package/dist/server/app-page-element-builder.js +1 -0
- package/dist/server/app-page-execution.js +2 -1
- package/dist/server/app-page-render-identity.d.ts +1 -0
- package/dist/server/app-page-render-identity.js +2 -1
- package/dist/server/app-page-render.d.ts +3 -1
- package/dist/server/app-page-render.js +67 -16
- package/dist/server/app-page-response.d.ts +7 -0
- package/dist/server/app-page-response.js +16 -4
- package/dist/server/app-page-route-wiring.js +3 -3
- package/dist/server/app-page-stream.d.ts +2 -1
- package/dist/server/app-page-stream.js +1 -1
- package/dist/server/app-route-handler-execution.d.ts +1 -1
- package/dist/server/app-route-tree-prefetch.d.ts +43 -0
- package/dist/server/app-route-tree-prefetch.js +187 -0
- package/dist/server/app-router-entry.js +1 -1
- package/dist/server/app-rsc-cache-busting.d.ts +2 -1
- package/dist/server/app-rsc-cache-busting.js +9 -5
- package/dist/server/app-rsc-handler.d.ts +6 -0
- package/dist/server/app-rsc-handler.js +88 -10
- package/dist/server/app-rsc-render-mode.d.ts +3 -5
- package/dist/server/app-rsc-render-mode.js +5 -12
- package/dist/server/app-rsc-request-normalization.d.ts +3 -4
- package/dist/server/app-rsc-request-normalization.js +4 -5
- package/dist/server/app-server-action-execution.js +6 -5
- package/dist/server/app-ssr-entry.js +1 -1
- package/dist/server/cache-control.d.ts +3 -1
- package/dist/server/cache-control.js +13 -1
- package/dist/server/dev-module-runner.js +1 -1
- package/dist/server/dev-origin-check.d.ts +2 -2
- package/dist/server/dev-origin-check.js +2 -2
- package/dist/server/dev-server.d.ts +11 -1
- package/dist/server/dev-server.js +82 -24
- package/dist/server/headers.d.ts +6 -2
- package/dist/server/headers.js +11 -5
- package/dist/server/image-optimization.d.ts +12 -1
- package/dist/server/image-optimization.js +13 -1
- package/dist/server/isr-cache.d.ts +13 -4
- package/dist/server/isr-cache.js +8 -4
- package/dist/server/pages-data-route.d.ts +4 -2
- package/dist/server/pages-data-route.js +18 -4
- package/dist/server/pages-dev-module-url.d.ts +2 -1
- package/dist/server/pages-dev-module-url.js +6 -3
- package/dist/server/pages-node-compat.d.ts +12 -1
- package/dist/server/pages-node-compat.js +50 -1
- package/dist/server/pages-page-data.d.ts +9 -0
- package/dist/server/pages-page-data.js +18 -10
- package/dist/server/pages-page-handler.js +19 -7
- package/dist/server/pages-page-response.d.ts +1 -0
- package/dist/server/pages-page-response.js +5 -4
- package/dist/server/pages-request-pipeline.d.ts +8 -6
- package/dist/server/pages-request-pipeline.js +31 -7
- package/dist/server/pages-router-entry.js +1 -1
- package/dist/server/prerender-manifest.d.ts +15 -1
- package/dist/server/prerender-manifest.js +29 -1
- package/dist/server/prod-server.d.ts +10 -7
- package/dist/server/prod-server.js +43 -28
- package/dist/server/request-pipeline.js +1 -1
- package/dist/server/static-file-cache.js +1 -1
- package/dist/shims/cache-handler.js +8 -1
- package/dist/shims/cache.d.ts +1 -1
- package/dist/shims/cache.js +3 -0
- package/dist/shims/cdn-cache.d.ts +2 -7
- package/dist/shims/cdn-cache.js +2 -14
- package/dist/shims/fetch-cache.d.ts +3 -1
- package/dist/shims/fetch-cache.js +77 -52
- package/dist/shims/internal/app-prefetch-fetch-queue.d.ts +10 -0
- package/dist/shims/internal/app-prefetch-fetch-queue.js +61 -0
- package/dist/shims/internal/hybrid-client-route-owner.d.ts +2 -1
- package/dist/shims/internal/hybrid-client-route-owner.js +34 -1
- package/dist/shims/internal/pages-data-fetch-dedup.d.ts +2 -1
- package/dist/shims/internal/pages-data-fetch-dedup.js +13 -2
- package/dist/shims/internal/pages-data-target.d.ts +8 -3
- package/dist/shims/internal/pages-data-target.js +9 -4
- package/dist/shims/link.d.ts +1 -1
- package/dist/shims/link.js +179 -42
- package/dist/shims/navigation.d.ts +15 -3
- package/dist/shims/navigation.js +202 -39
- package/dist/shims/request-context.js +18 -0
- package/dist/shims/request-state-types.d.ts +2 -2
- package/dist/shims/router.js +31 -15
- package/dist/shims/unified-request-context.d.ts +1 -1
- package/dist/shims/unified-request-context.js +1 -0
- package/dist/typegen.js +1 -1
- package/dist/utils/middleware-request-headers.js +1 -1
- package/dist/utils/project.d.ts +1 -1
- package/dist/utils/protocol-headers.d.ts +7 -1
- package/dist/utils/protocol-headers.js +7 -1
- package/dist/utils/vite-version.d.ts +4 -12
- package/dist/utils/vite-version.js +39 -21
- package/package.json +31 -13
- package/dist/cloudflare/index.d.ts +0 -3
- package/dist/cloudflare/index.js +0 -3
- package/dist/packages/cloudflare/src/cache/cdn-adapter.runtime.js +0 -102
- package/dist/packages/cloudflare/src/cache/kv-data-adapter.runtime.d.ts +0 -126
- package/dist/packages/cloudflare/src/cache/kv-data-adapter.runtime.js +0 -435
- package/dist/packages/cloudflare/src/deploy-config.js +0 -150
- package/dist/packages/cloudflare/src/deploy-help.js +0 -55
- package/dist/packages/cloudflare/src/deploy.js +0 -276
- package/dist/packages/cloudflare/src/tpr.d.ts +0 -45
- package/dist/packages/cloudflare/src/tpr.js +0 -561
- package/dist/packages/cloudflare/src/utils/cache-control-metadata.js +0 -20
package/README.md
CHANGED
|
@@ -1,10 +1,34 @@
|
|
|
1
1
|
# vinext
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Run Next.js applications on Vite, with Cloudflare Workers as the primary deployment target.
|
|
4
4
|
|
|
5
5
|
> **Read the announcement:** [How we rebuilt Next.js with AI in one week](https://blog.cloudflare.com/vinext/)
|
|
6
6
|
|
|
7
|
-
>
|
|
7
|
+
> **Under active development.** vinext supports substantial Next.js applications today, but it is not yet a drop-in replacement for every application or production workload. Expect compatibility gaps, especially in newer App Router features, and evaluate it against your own application before adopting it.
|
|
8
|
+
|
|
9
|
+
vinext reimplements the Next.js API surface on Vite rather than consuming `next build` output. It supports both the App Router and Pages Router, React Server Components, Server Actions, middleware, route handlers, ISR, static export, and the most commonly used `next/*` modules. Cloudflare Workers has the deepest integration; Node.js and other platforms are available with different levels of support.
|
|
10
|
+
|
|
11
|
+
## Project status
|
|
12
|
+
|
|
13
|
+
### What works today
|
|
14
|
+
|
|
15
|
+
- **App Router and Pages Router** in development and production builds
|
|
16
|
+
- **React Server Components, Server Actions, route handlers, and middleware**
|
|
17
|
+
- **Static generation, ISR, `output: "export"`, and standalone Node.js output**
|
|
18
|
+
- **Core Next.js APIs and modules**, including `next/link`, `next/image`, `next/navigation`, `next/headers`, `next/cache`, and the Metadata API
|
|
19
|
+
- **Cloudflare Workers deployment** with bindings, cache adapters, and image optimization support
|
|
20
|
+
- **Migration tooling** through `vinext check`, `vinext init`, and the vinext Agent Skill
|
|
21
|
+
|
|
22
|
+
### Known gaps we're working on
|
|
23
|
+
|
|
24
|
+
These are active compatibility areas, not permanent exclusions:
|
|
25
|
+
|
|
26
|
+
- **Cache Components and Partial Prerendering:** `"use cache"` is partially implemented, but full `cacheComponents` behavior is still incomplete. Cache profiles, tags, partial shells, resume behavior, prefetching, and some dev/build cache semantics do not yet match Next.js in every case.
|
|
27
|
+
- **Build-time image and font optimization:** images can be optimized at request time on Cloudflare, but vinext does not yet reproduce Next.js's complete build-time image pipeline. Google Fonts are loaded from the CDN, and local font CSS is injected at runtime rather than extracted during the build.
|
|
28
|
+
- **Native modules in App Router development:** packages such as `sharp`, `resvg`, `satori`, `lightningcss`, and `@napi-rs/canvas` can fail in Vite's RSC development environment. Production builds support more of these cases than development mode.
|
|
29
|
+
- **Platform-specific and advanced Next.js behavior:** `runtime` and `preferredRegion` route config are currently ignored, and some recently introduced or undocumented Next.js behavior may not yet be reproduced.
|
|
30
|
+
|
|
31
|
+
Run `vinext check` against an existing application before migrating. If a gap is not listed here, check the [open issues](https://github.com/cloudflare/vinext/issues) or file a focused reproduction.
|
|
8
32
|
|
|
9
33
|
## Quick start
|
|
10
34
|
|
|
@@ -25,13 +49,15 @@ The skill handles compatibility checking, dependency installation, config genera
|
|
|
25
49
|
### Or do it manually
|
|
26
50
|
|
|
27
51
|
```bash
|
|
28
|
-
npm install
|
|
52
|
+
npm install vinext
|
|
53
|
+
npm install -D vite @vitejs/plugin-react
|
|
29
54
|
```
|
|
30
55
|
|
|
31
56
|
If you're using the App Router, also install:
|
|
32
57
|
|
|
33
58
|
```bash
|
|
34
|
-
npm install
|
|
59
|
+
npm install react-server-dom-webpack
|
|
60
|
+
npm install -D @vitejs/plugin-rsc
|
|
35
61
|
```
|
|
36
62
|
|
|
37
63
|
Replace `next` with `vinext` in your scripts:
|
|
@@ -93,9 +119,15 @@ Environment variables: `PORT` (default `3000`), `HOST` (default `0.0.0.0`).
|
|
|
93
119
|
|
|
94
120
|
### Starting a new vinext project
|
|
95
121
|
|
|
96
|
-
|
|
122
|
+
Use `create-vinext-app` for new projects. It creates a TypeScript App Router project
|
|
123
|
+
with Tailwind CSS and then runs the same vinext init setup used for existing apps:
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
pnpm create vinext-app@latest my-app
|
|
127
|
+
```
|
|
97
128
|
|
|
98
|
-
|
|
129
|
+
The generated project is Cloudflare Workers-ready by default. Pass
|
|
130
|
+
`--platform=node` if you want the Node target instead.
|
|
99
131
|
|
|
100
132
|
### Migrating an existing Next.js project
|
|
101
133
|
|
|
@@ -108,7 +140,7 @@ npx vinext init
|
|
|
108
140
|
This will:
|
|
109
141
|
|
|
110
142
|
1. Run `vinext check` to scan for compatibility issues
|
|
111
|
-
2. Install
|
|
143
|
+
2. Install vinext runtime packages as dependencies and Vite/plugin tooling as devDependencies
|
|
112
144
|
3. Rename CJS config files (e.g. `postcss.config.js` -> `.cjs`) to avoid ESM conflicts
|
|
113
145
|
4. Add `"type": "module"` to `package.json`
|
|
114
146
|
5. Add `dev:vinext`, `build:vinext`, and `start:vinext` scripts to `package.json`
|
|
@@ -136,7 +168,7 @@ the compatibility report.
|
|
|
136
168
|
|
|
137
169
|
Vite has become the default build tool for modern web frameworks — fast HMR, a clean plugin API, native ESM, and a growing ecosystem. With [`@vitejs/plugin-rsc`](https://github.com/vitejs/vite-plugin-react/tree/main/packages/plugin-rsc) adding React Server Components support, it's now possible to build a full RSC framework on Vite.
|
|
138
170
|
|
|
139
|
-
vinext
|
|
171
|
+
vinext reimplements the Next.js API surface on Vite so existing Next.js applications can run on a different toolchain. The answer, so far, is that substantial applications can.
|
|
140
172
|
|
|
141
173
|
vinext works everywhere. It natively supports Cloudflare Workers (with `npx @vinext/cloudflare deploy` or `vp exec vinext-cloudflare 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).
|
|
142
174
|
|
|
@@ -158,13 +190,13 @@ vinext works everywhere. It natively supports Cloudflare Workers (with `npx @vin
|
|
|
158
190
|
vinext is a Vite plugin that reimplements the public Next.js API — routing, server rendering, `next/*` module imports, the CLI — so you can run Next.js applications on Vite instead of the Next.js compiler toolchain. It can be deployed anywhere: Cloudflare Workers is the first natively supported target, with other platforms available via Nitro. Native adapters for more platforms are [planned](https://github.com/cloudflare/vinext/issues/80).
|
|
159
191
|
|
|
160
192
|
**Is this a fork of Next.js?**
|
|
161
|
-
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
|
|
193
|
+
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 is to provide the same well-defined API surface on Vite's toolchain.
|
|
162
194
|
|
|
163
195
|
**How is this different from OpenNext?**
|
|
164
|
-
[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
|
|
196
|
+
[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 want a lighter Vite-based toolchain and do not need every Next.js API, vinext may be a good fit.
|
|
165
197
|
|
|
166
198
|
**Can I use this in production?**
|
|
167
|
-
You can, with caution.
|
|
199
|
+
You can, with caution. vinext has known compatibility gaps and has not yet been battle-tested across the full range of production Next.js workloads. Evaluate the features and deployment target your application relies on before adopting it.
|
|
168
200
|
|
|
169
201
|
**Can I just self-host Next.js?**
|
|
170
202
|
Yes. Next.js supports [self-hosting](https://nextjs.org/docs/app/building-your-application/deploying#self-hosting) on Node.js servers, Docker containers, and static exports. If you're happy with the Next.js toolchain and just want to run it somewhere other than Vercel, self-hosting is the simplest path.
|
|
@@ -176,7 +208,7 @@ The test suite has over 1,700 Vitest tests and 380 Playwright E2E tests. This in
|
|
|
176
208
|
A mix of humans and AI agents. Humans review PRs before they merge, focused on behavior, structure, and long-term direction. We lean heavily on agent-driven code review to catch issues at PR time and across the codebase. The test suite is the primary quality gate. Outside contributions and deeper human code review are very welcome.
|
|
177
209
|
|
|
178
210
|
**Why Vite?**
|
|
179
|
-
Vite is an excellent build tool with a rich plugin ecosystem, first-class ESM support, and fast HMR. The [`@vitejs/plugin-rsc`](https://github.com/vitejs/vite-plugin-react/tree/main/packages/plugin-rsc) plugin adds React Server Components support with multi-environment builds.
|
|
211
|
+
Vite is an excellent build tool with a rich plugin ecosystem, first-class ESM support, and fast HMR. The [`@vitejs/plugin-rsc`](https://github.com/vitejs/vite-plugin-react/tree/main/packages/plugin-rsc) plugin adds React Server Components support with multi-environment builds. vinext builds the Next.js developer experience on top of that infrastructure.
|
|
180
212
|
|
|
181
213
|
**Does this support the Pages Router, App Router, or both?**
|
|
182
214
|
Both. File-system routing, SSR, client hydration, and deployment to Cloudflare Workers work for both routers.
|
|
@@ -240,7 +272,7 @@ Use `--env <name>` to target `wrangler.jsonc` `env.<name>`. `--preview` is short
|
|
|
240
272
|
The init command also auto-detects and fixes common migration issues:
|
|
241
273
|
|
|
242
274
|
- Adds `"type": "module"` to package.json if missing
|
|
243
|
-
- Resolves tsconfig.json path aliases automatically
|
|
275
|
+
- Resolves tsconfig.json path aliases automatically with Vite's native resolver
|
|
244
276
|
- Detects MDX usage and configures `@mdx-js/rollup`
|
|
245
277
|
- Renames CJS config files (postcss.config.js, etc.) to `.cjs` when needed
|
|
246
278
|
- Detects native Node.js modules (sharp, resvg, satori, lightningcss, @napi-rs/canvas) and auto-stubs them for Workers. If you encounter others that need stubbing, PRs are welcome.
|
|
@@ -600,27 +632,16 @@ vinext({
|
|
|
600
632
|
|
|
601
633
|
## What's NOT supported (and won't be)
|
|
602
634
|
|
|
603
|
-
These are intentional exclusions. For things that are missing today but on the roadmap, see [Known
|
|
635
|
+
These are intentional exclusions. For things that are missing today but on the roadmap, see [Known gaps we're working on](#known-gaps-were-working-on) above.
|
|
604
636
|
|
|
605
637
|
- **Vercel-specific features** — `@vercel/og` edge runtime, Vercel Analytics integration, Vercel KV/Blob/Postgres bindings. Use platform equivalents.
|
|
606
638
|
- **AMP** — Deprecated since Next.js 13. `useAmp()` returns `false`.
|
|
607
639
|
- **`next export` (legacy)** — Use `output: 'export'` in config instead.
|
|
608
640
|
- **Turbopack/webpack configuration** — This runs on Vite. Use Vite plugins instead of webpack loaders/plugins.
|
|
609
641
|
- **`next/jest`** — Use Vitest.
|
|
610
|
-
- **`create-next-app` scaffolding** —
|
|
642
|
+
- **`create-next-app` scaffolding** — Use `create-vinext-app` for new vinext projects.
|
|
611
643
|
- **Bug-for-bug parity with undocumented behavior** — If it's not in the Next.js docs, we probably don't replicate it.
|
|
612
644
|
|
|
613
|
-
## Known limitations
|
|
614
|
-
|
|
615
|
-
These are gaps we'd like to close — distinct from the [intentional exclusions](#whats-not-supported-and-wont-be) above.
|
|
616
|
-
|
|
617
|
-
- **Image optimization doesn't happen at build time.** Remote images work via `@unpic/react` (auto-detects 28 CDN providers). Local images are routed through a `/_next/image` endpoint that can resize and transcode on Cloudflare Workers (via the Images binding) in production, but no build-time optimization or static resizing occurs.
|
|
618
|
-
- **Google Fonts are loaded from the CDN, not self-hosted.** No `size-adjust` fallback font metrics. Local fonts work but `@font-face` CSS is injected at runtime, not extracted at build time.
|
|
619
|
-
- **Route segment config** — `runtime` and `preferredRegion` are ignored (everything runs in the same environment).
|
|
620
|
-
- **Node.js production server (`vinext start`)** works for testing but is less complete than Workers deployment. Cloudflare Workers is the primary target.
|
|
621
|
-
- **Native Node modules (sharp, resvg, satori, lightningcss, @napi-rs/canvas)** crash Vite's RSC dev environment. Dynamic OG image/icon routes using these work in production builds but not in dev mode. These are auto-stubbed during `@vinext/cloudflare deploy`.
|
|
622
|
-
- **`next.config.ts` `baseUrl` bare imports require Vite 8.** A `next.config.ts` that imports a bare specifier resolved through `tsconfig.json`'s `compilerOptions.baseUrl` (e.g. `import { bar } from "bar"` resolving to a local `bar.ts`) relies on Vite 8's native `resolve.tsconfigPaths` (Rolldown/oxc-resolver). On Vite 7 there is no native equivalent, so these imports are not resolved. `compilerOptions.paths` aliases (e.g. `@/foo`) work on both Vite 7 and 8. Note that if a bare import matches both a `baseUrl`-local file and an installed package of the same name, the installed package wins (vinext keeps packages externalized so CJS config plugins like `@next/mdx` keep working).
|
|
623
|
-
|
|
624
645
|
## Benchmarks
|
|
625
646
|
|
|
626
647
|
> **Caveat:** Benchmarks are hard to get right and these are early results. Take them as directional, not definitive.
|
|
@@ -642,7 +663,7 @@ Benchmarks run on GitHub CI runners (2-core Ubuntu) on every merge to `main`. Se
|
|
|
642
663
|
|
|
643
664
|
Analysis of the build output shows two main factors:
|
|
644
665
|
|
|
645
|
-
1. **Tree-shaking**: Vite/
|
|
666
|
+
1. **Tree-shaking**: Vite/Rolldown produces a smaller React+ReactDOM bundle than Next.js/Turbopack. Rolldown's more aggressive dead-code elimination accounts for roughly half the overall difference.
|
|
646
667
|
2. **Framework overhead**: Next.js ships more client-side infrastructure (router, Turbopack runtime loader, prefetching, error handling) than vinext's lighter client runtime.
|
|
647
668
|
|
|
648
669
|
Both frameworks ship the same app code and the same RSC client runtime (`react-server-dom-webpack`). The difference is in how much of React's internals survive tree-shaking and how much framework plumbing each tool adds.
|
|
@@ -769,11 +790,11 @@ Or add it to your `package.json` as a file dependency:
|
|
|
769
790
|
}
|
|
770
791
|
```
|
|
771
792
|
|
|
772
|
-
vinext has peer dependencies on `react ^19.2.6`, `react-dom ^19.2.6`, `react-server-dom-webpack ^19.2.6`, and `vite ^
|
|
793
|
+
vinext has peer dependencies on `react ^19.2.6`, `react-dom ^19.2.6`, `react-server-dom-webpack ^19.2.6`, and `vite ^8.0.0`. Then replace `next` with `vinext` in your scripts and run as normal.
|
|
773
794
|
|
|
774
795
|
## Contributing
|
|
775
796
|
|
|
776
|
-
This project is
|
|
797
|
+
This project is under active development. Issues and PRs are welcome.
|
|
777
798
|
|
|
778
799
|
### CI
|
|
779
800
|
|
|
@@ -7,13 +7,6 @@ type ClientAssetFileNameInfo = {
|
|
|
7
7
|
readonly originalFileName?: string;
|
|
8
8
|
readonly originalFileNames?: readonly string[];
|
|
9
9
|
};
|
|
10
|
-
type RscFrameworkModuleInfo = {
|
|
11
|
-
importers: string[];
|
|
12
|
-
isEntry: boolean;
|
|
13
|
-
};
|
|
14
|
-
type RscFrameworkManualChunksMeta = {
|
|
15
|
-
getModuleInfo(id: string): RscFrameworkModuleInfo | null;
|
|
16
|
-
};
|
|
17
10
|
/**
|
|
18
11
|
* Routes client assets into Next-compatible subtrees: `.css` sources go to
|
|
19
12
|
* `<assetsDir>/css/`, everything else to `<assetsDir>/media/`. Returned as a
|
|
@@ -42,31 +35,15 @@ declare function createClientAssetFileNames(assetsDir: string): (assetInfo: Clie
|
|
|
42
35
|
* mobile devices.
|
|
43
36
|
* - No major Vite-based framework (Remix, SvelteKit, Astro, TanStack)
|
|
44
37
|
* uses per-package splitting. Next.js only isolates packages >160KB.
|
|
45
|
-
* -
|
|
38
|
+
* - The bundler's graph-based splitting already handles the common case
|
|
46
39
|
* well: shared dependencies between routes get their own chunks,
|
|
47
40
|
* and route-specific code stays in route chunks.
|
|
48
41
|
*/
|
|
49
42
|
declare function createClientManualChunks(shimsDir: string, preserveRouteBoundaries?: boolean): (id: string) => string | undefined;
|
|
50
|
-
/**
|
|
51
|
-
* Rollup output config with manualChunks for client code-splitting.
|
|
52
|
-
* Used by both CLI builds and multi-environment builds.
|
|
53
|
-
*
|
|
54
|
-
* experimentalMinChunkSize merges tiny shared chunks (< 10KB) back into
|
|
55
|
-
* their importers. This reduces HTTP request count and improves gzip
|
|
56
|
-
* compression efficiency — small files restart the compression dictionary,
|
|
57
|
-
* adding ~5-15% wire overhead vs fewer larger chunks.
|
|
58
|
-
*/
|
|
59
43
|
declare function createClientFileNameConfig(assetsDir: string): {
|
|
60
44
|
entryFileNames: string;
|
|
61
45
|
chunkFileNames: string;
|
|
62
46
|
};
|
|
63
|
-
declare function createClientOutputConfig(clientManualChunks: (id: string) => string | undefined, assetsDir: string): {
|
|
64
|
-
assetFileNames: (assetInfo: ClientAssetFileNameInfo) => string;
|
|
65
|
-
manualChunks: (id: string) => string | undefined;
|
|
66
|
-
experimentalMinChunkSize: number;
|
|
67
|
-
entryFileNames: string;
|
|
68
|
-
chunkFileNames: string;
|
|
69
|
-
};
|
|
70
47
|
declare function createClientCodeSplittingConfig(clientManualChunks: (id: string) => string | undefined): {
|
|
71
48
|
minSize: number;
|
|
72
49
|
groups: {
|
|
@@ -82,13 +59,12 @@ declare const RSC_FRAMEWORK_CHUNK_TEST: RegExp;
|
|
|
82
59
|
declare function isRscFrameworkModule(id: string): boolean;
|
|
83
60
|
/**
|
|
84
61
|
* Output config that isolates React (and the RSC flight runtime) into a
|
|
85
|
-
* dedicated "framework" chunk in the RSC server build.
|
|
86
|
-
*
|
|
87
|
-
*
|
|
88
|
-
*
|
|
89
|
-
* dynamic imports must stay out of the eager framework chunk (issue #2073).
|
|
62
|
+
* dedicated "framework" chunk in the RSC server build. See
|
|
63
|
+
* {@link RSC_FRAMEWORK_CHUNK_TEST} for the motivation (issue #1549). Framework
|
|
64
|
+
* modules that are only reachable through dynamic imports must stay out of the
|
|
65
|
+
* eager framework chunk (issue #2073).
|
|
90
66
|
*/
|
|
91
|
-
declare function createRscFrameworkChunkOutputConfig(
|
|
67
|
+
declare function createRscFrameworkChunkOutputConfig(): {
|
|
92
68
|
codeSplitting: {
|
|
93
69
|
groups: {
|
|
94
70
|
name: string;
|
|
@@ -96,76 +72,21 @@ declare function createRscFrameworkChunkOutputConfig(viteMajorVersion: number):
|
|
|
96
72
|
entriesAware: boolean;
|
|
97
73
|
}[];
|
|
98
74
|
};
|
|
99
|
-
manualChunks?: undefined;
|
|
100
|
-
} | {
|
|
101
|
-
manualChunks(id: string, meta: RscFrameworkManualChunksMeta): string | undefined;
|
|
102
|
-
codeSplitting?: undefined;
|
|
103
|
-
};
|
|
104
|
-
/**
|
|
105
|
-
* Rollup treeshake configuration for production client builds.
|
|
106
|
-
*
|
|
107
|
-
* Uses the 'recommended' preset as a safe base, then overrides
|
|
108
|
-
* moduleSideEffects to strip unused re-exports from npm packages.
|
|
109
|
-
*
|
|
110
|
-
* The 'no-external' value for moduleSideEffects means:
|
|
111
|
-
* - Local project modules: preserve side effects (CSS imports, polyfills)
|
|
112
|
-
* - node_modules packages: treat as side-effect-free unless exports are used
|
|
113
|
-
*
|
|
114
|
-
* This is the single highest-impact optimization for large barrel-exporting
|
|
115
|
-
* libraries like mermaid, @mui/material, lucide-react, etc. These libraries
|
|
116
|
-
* re-export hundreds of sub-modules through barrel files. Without this,
|
|
117
|
-
* Rollup preserves every sub-module even when only a few exports are consumed.
|
|
118
|
-
*
|
|
119
|
-
* Why 'no-external' instead of false (global side-effect-free)?
|
|
120
|
-
* - User code may rely on import-time side effects (e.g., `import './global.css'`)
|
|
121
|
-
* - 'no-external' is safe for app code while still enabling aggressive DCE for deps
|
|
122
|
-
*
|
|
123
|
-
* Why not the 'smallest' preset?
|
|
124
|
-
* - 'smallest' also sets propertyReadSideEffects: false and
|
|
125
|
-
* tryCatchDeoptimization: false, which can break specific libraries
|
|
126
|
-
* that rely on property access side effects or try/catch for feature detection
|
|
127
|
-
* - 'recommended' + 'no-external' gives most of the benefit with less risk
|
|
128
|
-
*
|
|
129
|
-
* @deprecated Use getClientTreeshakeConfigForVite(viteMajorVersion) instead
|
|
130
|
-
* for Vite version compatibility. Kept for backward compatibility.
|
|
131
|
-
*/
|
|
132
|
-
declare const clientTreeshakeConfig: {
|
|
133
|
-
preset: "recommended";
|
|
134
|
-
moduleSideEffects: "no-external";
|
|
135
75
|
};
|
|
136
76
|
/**
|
|
137
|
-
* Returns treeshake configuration
|
|
138
|
-
*
|
|
139
|
-
* Rollup (Vite 7) supports presets like "recommended" which set multiple
|
|
140
|
-
* treeshake options at once. Rolldown (Vite 8+) doesn't support presets,
|
|
141
|
-
* so we only return moduleSideEffects for Vite 8+.
|
|
142
|
-
*
|
|
143
|
-
* The Rollup "recommended" preset sets:
|
|
144
|
-
* - annotations: true (Rolldown default is also true)
|
|
145
|
-
* - manualPureFunctions: [] (Rolldown default is also [])
|
|
146
|
-
* - propertyReadSideEffects: true (Rolldown equivalent is 'always', the default)
|
|
147
|
-
* - unknownGlobalSideEffects: false (Rolldown default is true — this is a known acceptable
|
|
148
|
-
* divergence. Slightly less aggressive DCE on unknown globals, acceptable for client bundles)
|
|
149
|
-
* - correctVarValueBeforeDeclaration and tryCatchDeoptimization (Rolldown handles these differently)
|
|
77
|
+
* Returns Rolldown treeshake configuration for production client builds.
|
|
150
78
|
*
|
|
151
79
|
* The key optimization is moduleSideEffects: "no-external", which is supported
|
|
152
|
-
* by
|
|
153
|
-
*
|
|
154
|
-
*
|
|
80
|
+
* by Rolldown and provides the DCE benefits for barrel-exporting libraries. It
|
|
81
|
+
* treats node_modules as side-effect-free while preserving side effects in
|
|
82
|
+
* local code.
|
|
155
83
|
*/
|
|
156
|
-
declare function
|
|
157
|
-
moduleSideEffects: "no-external";
|
|
158
|
-
preset?: undefined;
|
|
159
|
-
} | {
|
|
160
|
-
preset: "recommended";
|
|
84
|
+
declare function getClientTreeshakeConfig(): {
|
|
161
85
|
moduleSideEffects: "no-external";
|
|
162
86
|
};
|
|
163
87
|
type VinextBuildConfig = NonNullable<UserConfig["build"]>;
|
|
164
88
|
type VinextBuildBundlerOptions = NonNullable<VinextBuildConfig["rolldownOptions"]>;
|
|
165
|
-
type VinextBuildConfigWithLegacy = VinextBuildConfig & {
|
|
166
|
-
rollupOptions?: VinextBuildBundlerOptions;
|
|
167
|
-
};
|
|
168
89
|
declare function getBuildBundlerOptions(build: UserConfig["build"] | undefined): VinextBuildBundlerOptions | undefined;
|
|
169
|
-
declare function withBuildBundlerOptions(
|
|
90
|
+
declare function withBuildBundlerOptions(bundlerOptions: VinextBuildBundlerOptions): Partial<VinextBuildConfig>;
|
|
170
91
|
//#endregion
|
|
171
|
-
export { RSC_FRAMEWORK_CHUNK_TEST,
|
|
92
|
+
export { RSC_FRAMEWORK_CHUNK_TEST, createClientAssetFileNames, createClientCodeSplittingConfig, createClientFileNameConfig, createClientManualChunks, createRscFrameworkChunkOutputConfig, getBuildBundlerOptions, getClientTreeshakeConfig, isRscFrameworkModule, withBuildBundlerOptions };
|
|
@@ -78,7 +78,7 @@ function getPackageName(id) {
|
|
|
78
78
|
* mobile devices.
|
|
79
79
|
* - No major Vite-based framework (Remix, SvelteKit, Astro, TanStack)
|
|
80
80
|
* uses per-package splitting. Next.js only isolates packages >160KB.
|
|
81
|
-
* -
|
|
81
|
+
* - The bundler's graph-based splitting already handles the common case
|
|
82
82
|
* well: shared dependencies between routes get their own chunks,
|
|
83
83
|
* and route-specific code stays in route chunks.
|
|
84
84
|
*/
|
|
@@ -101,15 +101,6 @@ function createClientManualChunks(shimsDir, preserveRouteBoundaries = false) {
|
|
|
101
101
|
}
|
|
102
102
|
};
|
|
103
103
|
}
|
|
104
|
-
/**
|
|
105
|
-
* Rollup output config with manualChunks for client code-splitting.
|
|
106
|
-
* Used by both CLI builds and multi-environment builds.
|
|
107
|
-
*
|
|
108
|
-
* experimentalMinChunkSize merges tiny shared chunks (< 10KB) back into
|
|
109
|
-
* their importers. This reduces HTTP request count and improves gzip
|
|
110
|
-
* compression efficiency — small files restart the compression dictionary,
|
|
111
|
-
* adding ~5-15% wire overhead vs fewer larger chunks.
|
|
112
|
-
*/
|
|
113
104
|
function createClientFileNameConfig(assetsDir) {
|
|
114
105
|
const chunksDir = `${assetsDir}/chunks`;
|
|
115
106
|
return {
|
|
@@ -117,14 +108,6 @@ function createClientFileNameConfig(assetsDir) {
|
|
|
117
108
|
chunkFileNames: `${chunksDir}/[name]-[hash].js`
|
|
118
109
|
};
|
|
119
110
|
}
|
|
120
|
-
function createClientOutputConfig(clientManualChunks, assetsDir) {
|
|
121
|
-
return {
|
|
122
|
-
...createClientFileNameConfig(assetsDir),
|
|
123
|
-
assetFileNames: createClientAssetFileNames(assetsDir),
|
|
124
|
-
manualChunks: clientManualChunks,
|
|
125
|
-
experimentalMinChunkSize: 1e4
|
|
126
|
-
};
|
|
127
|
-
}
|
|
128
111
|
function createClientCodeSplittingConfig(clientManualChunks) {
|
|
129
112
|
return {
|
|
130
113
|
minSize: 1e4,
|
|
@@ -174,97 +157,36 @@ function isRscFrameworkModule(id) {
|
|
|
174
157
|
const pkg = getPackageName(id);
|
|
175
158
|
return pkg !== null && FRAMEWORK_PACKAGES.includes(pkg);
|
|
176
159
|
}
|
|
177
|
-
function isStaticallyReachableFromEntry(id, meta, visited = /* @__PURE__ */ new Set()) {
|
|
178
|
-
if (visited.has(id)) return false;
|
|
179
|
-
visited.add(id);
|
|
180
|
-
const moduleInfo = meta.getModuleInfo(id);
|
|
181
|
-
if (!moduleInfo) return false;
|
|
182
|
-
if (moduleInfo.isEntry) return true;
|
|
183
|
-
return moduleInfo.importers.some((importer) => isStaticallyReachableFromEntry(importer, meta, visited));
|
|
184
|
-
}
|
|
185
160
|
/**
|
|
186
161
|
* Output config that isolates React (and the RSC flight runtime) into a
|
|
187
|
-
* dedicated "framework" chunk in the RSC server build.
|
|
188
|
-
*
|
|
189
|
-
*
|
|
190
|
-
*
|
|
191
|
-
* dynamic imports must stay out of the eager framework chunk (issue #2073).
|
|
162
|
+
* dedicated "framework" chunk in the RSC server build. See
|
|
163
|
+
* {@link RSC_FRAMEWORK_CHUNK_TEST} for the motivation (issue #1549). Framework
|
|
164
|
+
* modules that are only reachable through dynamic imports must stay out of the
|
|
165
|
+
* eager framework chunk (issue #2073).
|
|
192
166
|
*/
|
|
193
|
-
function createRscFrameworkChunkOutputConfig(
|
|
194
|
-
|
|
167
|
+
function createRscFrameworkChunkOutputConfig() {
|
|
168
|
+
return { codeSplitting: { groups: [{
|
|
195
169
|
name: "framework",
|
|
196
170
|
test: RSC_FRAMEWORK_CHUNK_TEST,
|
|
197
171
|
entriesAware: true
|
|
198
172
|
}] } };
|
|
199
|
-
return { manualChunks(id, meta) {
|
|
200
|
-
return isRscFrameworkModule(id) && isStaticallyReachableFromEntry(id, meta) ? "framework" : void 0;
|
|
201
|
-
} };
|
|
202
173
|
}
|
|
203
174
|
/**
|
|
204
|
-
*
|
|
205
|
-
*
|
|
206
|
-
* Uses the 'recommended' preset as a safe base, then overrides
|
|
207
|
-
* moduleSideEffects to strip unused re-exports from npm packages.
|
|
208
|
-
*
|
|
209
|
-
* The 'no-external' value for moduleSideEffects means:
|
|
210
|
-
* - Local project modules: preserve side effects (CSS imports, polyfills)
|
|
211
|
-
* - node_modules packages: treat as side-effect-free unless exports are used
|
|
212
|
-
*
|
|
213
|
-
* This is the single highest-impact optimization for large barrel-exporting
|
|
214
|
-
* libraries like mermaid, @mui/material, lucide-react, etc. These libraries
|
|
215
|
-
* re-export hundreds of sub-modules through barrel files. Without this,
|
|
216
|
-
* Rollup preserves every sub-module even when only a few exports are consumed.
|
|
217
|
-
*
|
|
218
|
-
* Why 'no-external' instead of false (global side-effect-free)?
|
|
219
|
-
* - User code may rely on import-time side effects (e.g., `import './global.css'`)
|
|
220
|
-
* - 'no-external' is safe for app code while still enabling aggressive DCE for deps
|
|
221
|
-
*
|
|
222
|
-
* Why not the 'smallest' preset?
|
|
223
|
-
* - 'smallest' also sets propertyReadSideEffects: false and
|
|
224
|
-
* tryCatchDeoptimization: false, which can break specific libraries
|
|
225
|
-
* that rely on property access side effects or try/catch for feature detection
|
|
226
|
-
* - 'recommended' + 'no-external' gives most of the benefit with less risk
|
|
227
|
-
*
|
|
228
|
-
* @deprecated Use getClientTreeshakeConfigForVite(viteMajorVersion) instead
|
|
229
|
-
* for Vite version compatibility. Kept for backward compatibility.
|
|
230
|
-
*/
|
|
231
|
-
const clientTreeshakeConfig = {
|
|
232
|
-
preset: "recommended",
|
|
233
|
-
moduleSideEffects: "no-external"
|
|
234
|
-
};
|
|
235
|
-
/**
|
|
236
|
-
* Returns treeshake configuration appropriate for the Vite version.
|
|
237
|
-
*
|
|
238
|
-
* Rollup (Vite 7) supports presets like "recommended" which set multiple
|
|
239
|
-
* treeshake options at once. Rolldown (Vite 8+) doesn't support presets,
|
|
240
|
-
* so we only return moduleSideEffects for Vite 8+.
|
|
241
|
-
*
|
|
242
|
-
* The Rollup "recommended" preset sets:
|
|
243
|
-
* - annotations: true (Rolldown default is also true)
|
|
244
|
-
* - manualPureFunctions: [] (Rolldown default is also [])
|
|
245
|
-
* - propertyReadSideEffects: true (Rolldown equivalent is 'always', the default)
|
|
246
|
-
* - unknownGlobalSideEffects: false (Rolldown default is true — this is a known acceptable
|
|
247
|
-
* divergence. Slightly less aggressive DCE on unknown globals, acceptable for client bundles)
|
|
248
|
-
* - correctVarValueBeforeDeclaration and tryCatchDeoptimization (Rolldown handles these differently)
|
|
175
|
+
* Returns Rolldown treeshake configuration for production client builds.
|
|
249
176
|
*
|
|
250
177
|
* The key optimization is moduleSideEffects: "no-external", which is supported
|
|
251
|
-
* by
|
|
252
|
-
*
|
|
253
|
-
*
|
|
178
|
+
* by Rolldown and provides the DCE benefits for barrel-exporting libraries. It
|
|
179
|
+
* treats node_modules as side-effect-free while preserving side effects in
|
|
180
|
+
* local code.
|
|
254
181
|
*/
|
|
255
|
-
function
|
|
256
|
-
|
|
257
|
-
return {
|
|
258
|
-
preset: "recommended",
|
|
259
|
-
moduleSideEffects: "no-external"
|
|
260
|
-
};
|
|
182
|
+
function getClientTreeshakeConfig() {
|
|
183
|
+
return { moduleSideEffects: "no-external" };
|
|
261
184
|
}
|
|
262
185
|
function getBuildBundlerOptions(build) {
|
|
263
|
-
|
|
264
|
-
return buildConfig?.rolldownOptions ?? buildConfig?.rollupOptions;
|
|
186
|
+
return build?.rolldownOptions;
|
|
265
187
|
}
|
|
266
|
-
function withBuildBundlerOptions(
|
|
267
|
-
return
|
|
188
|
+
function withBuildBundlerOptions(bundlerOptions) {
|
|
189
|
+
return { rolldownOptions: bundlerOptions };
|
|
268
190
|
}
|
|
269
191
|
//#endregion
|
|
270
|
-
export { RSC_FRAMEWORK_CHUNK_TEST,
|
|
192
|
+
export { RSC_FRAMEWORK_CHUNK_TEST, createClientAssetFileNames, createClientCodeSplittingConfig, createClientFileNameConfig, createClientManualChunks, createRscFrameworkChunkOutputConfig, getBuildBundlerOptions, getClientTreeshakeConfig, isRscFrameworkModule, withBuildBundlerOptions };
|
|
@@ -13,6 +13,8 @@ type EmitRestoredCssUrlAsset = (asset: {
|
|
|
13
13
|
* safe to run on every build-environment stylesheet, vendored CSS included.
|
|
14
14
|
*/
|
|
15
15
|
declare function markCssUrlAssetReferences(code: string, id: string): string | null;
|
|
16
|
+
/** Rebase relative asset URLs when Sass inlines a partial into an entry file. */
|
|
17
|
+
declare function rebaseCssUrlAssetReferences(code: string, sourceDirectory: string, targetDirectory: string): string | null;
|
|
16
18
|
/**
|
|
17
19
|
* Mutates emitted CSS assets in place so byte-identical `url()` dependencies
|
|
18
20
|
* keep their distinct Next-compatible filenames. Sibling files are produced via
|
|
@@ -26,4 +28,4 @@ declare function markCssUrlAssetReferences(code: string, id: string): string | n
|
|
|
26
28
|
*/
|
|
27
29
|
declare function restoreDedupedCssAssetReferences(bundle: CssUrlAssetBundle, emitRestoredAsset: EmitRestoredCssUrlAsset): void;
|
|
28
30
|
//#endregion
|
|
29
|
-
export { markCssUrlAssetReferences, restoreDedupedCssAssetReferences };
|
|
31
|
+
export { markCssUrlAssetReferences, rebaseCssUrlAssetReferences, restoreDedupedCssAssetReferences };
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import path from "node:path";
|
|
1
2
|
//#region src/build/css-url-assets.ts
|
|
2
3
|
/**
|
|
3
4
|
* Next-parity for CSS `url()` asset dependencies.
|
|
@@ -128,6 +129,22 @@ function markCssUrlAssetReferences(code, id) {
|
|
|
128
129
|
});
|
|
129
130
|
});
|
|
130
131
|
}
|
|
132
|
+
/** Rebase relative asset URLs when Sass inlines a partial into an entry file. */
|
|
133
|
+
function rebaseCssUrlAssetReferences(code, sourceDirectory, targetDirectory) {
|
|
134
|
+
return rewriteCssUrls(code, (rawUrl) => {
|
|
135
|
+
const parts = splitUrl(rawUrl.trim());
|
|
136
|
+
if (!isRelativeAssetUrl(parts.path)) return null;
|
|
137
|
+
const lower = parts.path.toLowerCase();
|
|
138
|
+
if (!CSS_ASSET_EXT_RE.test(lower) || lower.endsWith(".css")) return null;
|
|
139
|
+
const absolutePath = path.resolve(sourceDirectory, parts.path);
|
|
140
|
+
let rebasedPath = path.relative(targetDirectory, absolutePath).replaceAll("\\", "/");
|
|
141
|
+
if (!rebasedPath.startsWith(".")) rebasedPath = `./${rebasedPath}`;
|
|
142
|
+
return joinUrl({
|
|
143
|
+
...parts,
|
|
144
|
+
path: rebasedPath
|
|
145
|
+
});
|
|
146
|
+
});
|
|
147
|
+
}
|
|
131
148
|
function isCssFileName(fileName) {
|
|
132
149
|
return fileName.toLowerCase().endsWith(".css");
|
|
133
150
|
}
|
|
@@ -210,4 +227,4 @@ function stripChunkMarkers(code) {
|
|
|
210
227
|
return code.replace(CSS_URL_MARKER_PARAM_RE, (_m, leadingQuestion) => leadingQuestion ? leadingQuestion : "");
|
|
211
228
|
}
|
|
212
229
|
//#endregion
|
|
213
|
-
export { markCssUrlAssetReferences, restoreDedupedCssAssetReferences };
|
|
230
|
+
export { markCssUrlAssetReferences, rebaseCssUrlAssetReferences, restoreDedupedCssAssetReferences };
|
|
@@ -11,7 +11,10 @@ function injectPregeneratedConcretePaths(root) {
|
|
|
11
11
|
if (!fs.existsSync(workerEntry)) return;
|
|
12
12
|
let code = fs.readFileSync(workerEntry, "utf-8").replace(VINEXT_PREGEN_RE, "");
|
|
13
13
|
const table = readPrerenderManifest(path.join(root, "dist", "server", "vinext-prerender.json"))?.pregeneratedConcretePaths ?? [];
|
|
14
|
-
if (table.length > 0)
|
|
14
|
+
if (table.length > 0) {
|
|
15
|
+
globalThis.__VINEXT_PREGENERATED_CONCRETE_PATHS = table;
|
|
16
|
+
code = `${VINEXT_PREGEN_START}\nglobalThis.__VINEXT_PREGENERATED_CONCRETE_PATHS = ${JSON.stringify(table)};\n${VINEXT_PREGEN_END}\n` + code;
|
|
17
|
+
} else delete globalThis.__VINEXT_PREGENERATED_CONCRETE_PATHS;
|
|
15
18
|
fs.writeFileSync(workerEntry, code);
|
|
16
19
|
}
|
|
17
20
|
//#endregion
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { ResolvedNextConfig } from "../config/next-config.js";
|
|
2
|
+
import { VinextRouteRootConfig } from "../config/prerender.js";
|
|
3
|
+
|
|
4
|
+
//#region src/build/prerender-paths.d.ts
|
|
5
|
+
type PrerenderPathManifest = {
|
|
6
|
+
buildId?: string;
|
|
7
|
+
trailingSlash?: boolean;
|
|
8
|
+
paths: string[];
|
|
9
|
+
};
|
|
10
|
+
declare const PRERENDER_PATH_DISCOVERY_ENV = "__VINEXT_PRERENDER_PATH_DISCOVERY";
|
|
11
|
+
declare const PRERENDER_PATHS_MANIFEST = "vinext-prerender-paths.json";
|
|
12
|
+
type EmitPrerenderPathManifestOptions = {
|
|
13
|
+
root: string;
|
|
14
|
+
nextConfigOverride?: Partial<ResolvedNextConfig>;
|
|
15
|
+
appDir?: string | null;
|
|
16
|
+
pagesDir?: string | null;
|
|
17
|
+
routeRootConfig?: VinextRouteRootConfig | null;
|
|
18
|
+
pagesBundlePath?: string;
|
|
19
|
+
rscBundlePath?: string;
|
|
20
|
+
};
|
|
21
|
+
declare function emitPrerenderPathManifest(options: EmitPrerenderPathManifestOptions): Promise<PrerenderPathManifest | null>;
|
|
22
|
+
//#endregion
|
|
23
|
+
export { PRERENDER_PATHS_MANIFEST, PRERENDER_PATH_DISCOVERY_ENV, PrerenderPathManifest, emitPrerenderPathManifest };
|