vinext 1.0.0-beta.7 → 1.0.0-beta.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
|
@@ -606,6 +606,33 @@ Every `next/*` import is shimmed to a Vite-compatible implementation.
|
|
|
606
606
|
| `images` config | 🟡 | Parsed but not used for optimization |
|
|
607
607
|
| `experimental.optimizePackageImports` | ✅ | Rewrites barrel imports to direct sub-module imports in RSC/SSR environments. A default set (lucide-react, date-fns, radix-ui, antd, MUI, and others) are always optimized. Add package names here to extend the list. |
|
|
608
608
|
| `vinext({ nextConfig })` | ✅ | Inline Next-style config from `vite.config.*`. Supports object-form and function-form config. When provided, this overrides root `next.config.*`. |
|
|
609
|
+
| `vinext({ react: { compiler: true } })` | ✅ | React Compiler auto memoization. Needs `@vitejs/plugin-react` 6.1+ and the optional `oxc-transform-react` package. |
|
|
610
|
+
|
|
611
|
+
### React Compiler
|
|
612
|
+
|
|
613
|
+
vinext auto-registers `@vitejs/plugin-react`, so the React Compiler is enabled through the same `react` option:
|
|
614
|
+
|
|
615
|
+
```ts
|
|
616
|
+
import { defineConfig } from "vite";
|
|
617
|
+
import vinext from "vinext";
|
|
618
|
+
|
|
619
|
+
export default defineConfig({
|
|
620
|
+
plugins: [vinext({ react: { compiler: true } })],
|
|
621
|
+
});
|
|
622
|
+
```
|
|
623
|
+
|
|
624
|
+
The transform itself ships separately, so install it alongside:
|
|
625
|
+
|
|
626
|
+
```bash
|
|
627
|
+
npm install -D oxc-transform-react
|
|
628
|
+
```
|
|
629
|
+
|
|
630
|
+
This requires `@vitejs/plugin-react` 6.1.0 or newer. Older versions accept the option and drop it, so vinext fails with an actionable error instead of leaving the compiler silently disabled. The compiler runs on the client environment only.
|
|
631
|
+
|
|
632
|
+
One caveat: modules whose JSX is lowered earlier in the pipeline are not memoized. Those build and behave correctly, they just miss auto memoization:
|
|
633
|
+
|
|
634
|
+
- JSX in plain `.js` files, which `vinext:jsx-in-js` compiles first so the compiler can parse them at all. Rename to `.jsx` or `.tsx` to get memoization.
|
|
635
|
+
- Components using `<style jsx>`, which `vinext:styled-jsx` compiles through the Next.js SWC transform before the compiler runs.
|
|
609
636
|
|
|
610
637
|
### Environment variable loading (`.env*`)
|
|
611
638
|
|
package/dist/index.d.ts
CHANGED
|
@@ -61,6 +61,9 @@ type VinextOptions = {
|
|
|
61
61
|
* Enabled by default. Set to `false` to disable (e.g. if you configure
|
|
62
62
|
* @vitejs/plugin-react manually in your vite.config.ts), or pass an options
|
|
63
63
|
* object to customize the Babel transform.
|
|
64
|
+
*
|
|
65
|
+
* Pass `{ compiler: true }` to enable the React Compiler. That requires
|
|
66
|
+
* @vitejs/plugin-react 6.1+ and the optional `oxc-transform-react` package.
|
|
64
67
|
* @default true
|
|
65
68
|
*/
|
|
66
69
|
react?: Options | boolean;
|
package/dist/index.js
CHANGED
|
@@ -55,6 +55,7 @@ import { readTrustedRevalidationHostname } from "./server/revalidation-host.js";
|
|
|
55
55
|
import { installDevStackSourcemapMiddleware } from "./server/dev-stack-sourcemap.js";
|
|
56
56
|
import { runPagesRequest } from "./server/pages-request-pipeline.js";
|
|
57
57
|
import { pagesRouteHasPriorityOverAppRoute, validateHybridRouteConflicts } from "./server/hybrid-route-priority.js";
|
|
58
|
+
import { hasReactCompilerPlugin, isReactCompilerPlugin, isReactCompilerRequested, reactCompilerUnsupportedMessage } from "./utils/react-compiler-support.js";
|
|
58
59
|
import { VIRTUAL_MODULE_ID_RE } from "./utils/virtual-module.js";
|
|
59
60
|
import { assertNoPublicDirAssetConflict, assertNoPublicNextRequestConflict } from "./build/public-dir-conflict.js";
|
|
60
61
|
import { renderVinextBuiltUrl } from "./utils/built-asset-url.js";
|
|
@@ -915,9 +916,12 @@ function vinext(options = {}) {
|
|
|
915
916
|
const configuredReactOptions = options.react && options.react !== true ? options.react : void 0;
|
|
916
917
|
const reactOptions = configuredReactOptions;
|
|
917
918
|
let reactPluginPromise = null;
|
|
919
|
+
let reactCompilerPluginPromise = null;
|
|
918
920
|
if (options.react !== false) {
|
|
919
921
|
if (!resolvedReactPath) throw new Error("vinext: @vitejs/plugin-react is not installed.\nRun: " + detectPackageManager(process.cwd()) + " @vitejs/plugin-react");
|
|
920
|
-
|
|
922
|
+
const allReactPlugins = import(pathToFileURL(resolvedReactPath).href).catch((cause) => {
|
|
923
|
+
throw new Error("vinext: Failed to load @vitejs/plugin-react.", { cause });
|
|
924
|
+
}).then((mod) => {
|
|
921
925
|
const react = mod.default;
|
|
922
926
|
const limitToCommand = (plugin, command) => {
|
|
923
927
|
const originalApply = plugin.apply;
|
|
@@ -931,15 +935,17 @@ function vinext(options = {}) {
|
|
|
931
935
|
}
|
|
932
936
|
};
|
|
933
937
|
};
|
|
934
|
-
const
|
|
938
|
+
const resolvedBuildPlugins = react(reactOptions);
|
|
939
|
+
if (isReactCompilerRequested(configuredReactOptions) && !hasReactCompilerPlugin(resolvedBuildPlugins)) throw new Error(reactCompilerUnsupportedMessage(detectPackageManager(process.cwd())));
|
|
940
|
+
const buildPlugins = resolvedBuildPlugins.map((plugin) => limitToCommand(plugin, "build"));
|
|
935
941
|
const servePlugins = react(configuredReactOptions !== void 0 && Object.prototype.hasOwnProperty.call(configuredReactOptions, "include") ? reactOptions : {
|
|
936
942
|
...reactOptions,
|
|
937
943
|
include: /\.(?:[tj]sx?|mdx)$/i
|
|
938
944
|
}).map((plugin) => limitToCommand(plugin, "serve"));
|
|
939
945
|
return [...buildPlugins, ...servePlugins];
|
|
940
|
-
}).catch((cause) => {
|
|
941
|
-
throw new Error("vinext: Failed to load @vitejs/plugin-react.", { cause });
|
|
942
946
|
});
|
|
947
|
+
reactPluginPromise = allReactPlugins.then((plugins) => plugins.filter((plugin) => !isReactCompilerPlugin(plugin)));
|
|
948
|
+
reactCompilerPluginPromise = allReactPlugins.then((plugins) => plugins.filter(isReactCompilerPlugin));
|
|
943
949
|
}
|
|
944
950
|
const imageImportDimCache = /* @__PURE__ */ new Map();
|
|
945
951
|
const staticImageAssets = /* @__PURE__ */ new Map();
|
|
@@ -1075,6 +1081,7 @@ function vinext(options = {}) {
|
|
|
1075
1081
|
}
|
|
1076
1082
|
}
|
|
1077
1083
|
},
|
|
1084
|
+
reactCompilerPluginPromise,
|
|
1078
1085
|
createMiddlewareServerOnlyPlugin({
|
|
1079
1086
|
getMiddlewarePath: () => middlewarePath,
|
|
1080
1087
|
getCanonicalMiddlewarePath: () => middlewarePath ? tryRealpathSync(middlewarePath) ?? middlewarePath : null,
|
|
@@ -205,10 +205,11 @@ function finalizeEmittedModuleIdentity(code, emittedIdentitySentinels, fileName)
|
|
|
205
205
|
const urlNamespaceBinding = selectRuntimeBinding("__vinext_module_url");
|
|
206
206
|
const identityBinding = selectRuntimeBinding("__vinext_module_identity");
|
|
207
207
|
const emittedFileName = toSlash(fileName).replace(/^\.\//, "").replace(/^\/+/, "");
|
|
208
|
-
const processCwd =
|
|
209
|
-
const emittedPathFallback = emittedFileName ? `(${processCwd}.replace(/[\\\\/]$/, "") + ${JSON.stringify(`/${emittedFileName}`)})` : processCwd
|
|
208
|
+
const processCwd = `(typeof ${processNamespaceBinding}.cwd === "function" ? ${processNamespaceBinding}.cwd() : "")`;
|
|
209
|
+
const emittedPathFallback = emittedFileName ? `(${processCwd}.replace(/[\\\\/]$/, "") + ${JSON.stringify(`/${emittedFileName}`)})` : `(${processCwd} || "/")`;
|
|
210
210
|
const emittedDirName = path.dirname(emittedFileName);
|
|
211
|
-
const emittedDirFallback = emittedDirName === "." ? processCwd : `(${processCwd}.replace(/[\\\\/]$/, "") + ${JSON.stringify(`/${emittedDirName}`)})`;
|
|
211
|
+
const emittedDirFallback = emittedDirName === "." ? `(${processCwd} || "/")` : `(${processCwd}.replace(/[\\\\/]$/, "") + ${JSON.stringify(`/${emittedDirName}`)})`;
|
|
212
|
+
const absoluteEmittedPath = JSON.stringify(`/${emittedFileName}`.replace(/\/$/, "") || "/");
|
|
212
213
|
const replacements = {
|
|
213
214
|
__filename: `${identityBinding}.filename`,
|
|
214
215
|
__dirname: `${identityBinding}.dirname`,
|
|
@@ -230,7 +231,7 @@ function finalizeEmittedModuleIdentity(code, emittedIdentitySentinels, fileName)
|
|
|
230
231
|
const needsUrl = usedFields.has("url");
|
|
231
232
|
const needsPath = usedFields.has("__filename") || usedFields.has("__dirname");
|
|
232
233
|
const runtimePreamble = [
|
|
233
|
-
`import * as ${processNamespaceBinding} from "node:process"
|
|
234
|
+
...needsPath ? [`import * as ${processNamespaceBinding} from "node:process";`] : [],
|
|
234
235
|
...needsPath ? [`import * as ${fsNamespaceBinding} from "node:fs";`] : [],
|
|
235
236
|
...needsUrl ? [`import * as ${urlNamespaceBinding} from "node:url";`] : [],
|
|
236
237
|
`const ${identityBinding} = (() => {`,
|
|
@@ -238,10 +239,10 @@ function finalizeEmittedModuleIdentity(code, emittedIdentitySentinels, fileName)
|
|
|
238
239
|
` const filename = import.meta.filename;`,
|
|
239
240
|
` const native = typeof filename === "string" && ${fsNamespaceBinding}.existsSync(filename);`,
|
|
240
241
|
` const resolvedFilename = native ? filename : ${emittedPathFallback};`
|
|
241
|
-
] : [` const runtimeUrl = import.meta.url;`],
|
|
242
|
+
] : [` const runtimeUrl = import.meta.url;`, ` const runtimeFilename = import.meta.filename;`],
|
|
242
243
|
` return {`,
|
|
243
244
|
...needsPath ? [` filename: resolvedFilename,`, ` dirname: native ? import.meta.dirname : ${emittedDirFallback},`] : [],
|
|
244
|
-
...needsUrl ? [needsPath ? ` url: ${urlNamespaceBinding}.pathToFileURL(resolvedFilename).href,` : ` url: typeof runtimeUrl === "string" && runtimeUrl.startsWith("file:") ? runtimeUrl : ${urlNamespaceBinding}.pathToFileURL(${
|
|
245
|
+
...needsUrl ? [needsPath ? ` url: ${urlNamespaceBinding}.pathToFileURL(resolvedFilename).href,` : ` url: typeof runtimeUrl === "string" && runtimeUrl.startsWith("file:") ? runtimeUrl : ${urlNamespaceBinding}.pathToFileURL(typeof runtimeFilename === "string" ? runtimeFilename : ${absoluteEmittedPath}).href,`] : [],
|
|
245
246
|
` };`,
|
|
246
247
|
`})();`,
|
|
247
248
|
""
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
//#region src/utils/react-compiler-support.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* The React Compiler option landed in @vitejs/plugin-react 6.1. Older versions
|
|
4
|
+
* accept an unknown `compiler` key in their options object and silently drop
|
|
5
|
+
* it, which would leave the compiler disabled while the config says otherwise.
|
|
6
|
+
*
|
|
7
|
+
* The plugin factory only returns `vite:react-compiler` when the installed
|
|
8
|
+
* version understands the option, so its presence is what we probe for.
|
|
9
|
+
*/
|
|
10
|
+
declare const REACT_COMPILER_PLUGIN_NAME = "vite:react-compiler";
|
|
11
|
+
/** Whether the user asked for the React Compiler through vinext's `react` option. */
|
|
12
|
+
declare function isReactCompilerRequested(reactOptions: unknown): boolean;
|
|
13
|
+
/** Whether a plugin entry is the React Compiler plugin. */
|
|
14
|
+
declare function isReactCompilerPlugin(plugin: unknown): boolean;
|
|
15
|
+
/** Whether the resolved @vitejs/plugin-react actually registered the compiler. */
|
|
16
|
+
declare function hasReactCompilerPlugin(plugins: readonly unknown[]): boolean;
|
|
17
|
+
/** Message for when `react: { compiler: true }` cannot be honored. */
|
|
18
|
+
declare function reactCompilerUnsupportedMessage(installCommand: string): string;
|
|
19
|
+
//#endregion
|
|
20
|
+
export { REACT_COMPILER_PLUGIN_NAME, hasReactCompilerPlugin, isReactCompilerPlugin, isReactCompilerRequested, reactCompilerUnsupportedMessage };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
//#region src/utils/react-compiler-support.ts
|
|
2
|
+
/**
|
|
3
|
+
* The React Compiler option landed in @vitejs/plugin-react 6.1. Older versions
|
|
4
|
+
* accept an unknown `compiler` key in their options object and silently drop
|
|
5
|
+
* it, which would leave the compiler disabled while the config says otherwise.
|
|
6
|
+
*
|
|
7
|
+
* The plugin factory only returns `vite:react-compiler` when the installed
|
|
8
|
+
* version understands the option, so its presence is what we probe for.
|
|
9
|
+
*/
|
|
10
|
+
const REACT_COMPILER_PLUGIN_NAME = "vite:react-compiler";
|
|
11
|
+
/** Whether the user asked for the React Compiler through vinext's `react` option. */
|
|
12
|
+
function isReactCompilerRequested(reactOptions) {
|
|
13
|
+
if (!reactOptions || typeof reactOptions !== "object") return false;
|
|
14
|
+
return Boolean(reactOptions.compiler);
|
|
15
|
+
}
|
|
16
|
+
/** Whether a plugin entry is the React Compiler plugin. */
|
|
17
|
+
function isReactCompilerPlugin(plugin) {
|
|
18
|
+
return typeof plugin === "object" && plugin !== null && plugin.name === "vite:react-compiler";
|
|
19
|
+
}
|
|
20
|
+
/** Whether the resolved @vitejs/plugin-react actually registered the compiler. */
|
|
21
|
+
function hasReactCompilerPlugin(plugins) {
|
|
22
|
+
return plugins.some(isReactCompilerPlugin);
|
|
23
|
+
}
|
|
24
|
+
/** Message for when `react: { compiler: true }` cannot be honored. */
|
|
25
|
+
function reactCompilerUnsupportedMessage(installCommand) {
|
|
26
|
+
return "vinext: `react: { compiler: true }` requires @vitejs/plugin-react 6.1 or newer.\nThe installed version ignores the option, which would leave the React Compiler disabled.\nRun: " + installCommand + " @vitejs/plugin-react@latest";
|
|
27
|
+
}
|
|
28
|
+
//#endregion
|
|
29
|
+
export { REACT_COMPILER_PLUGIN_NAME, hasReactCompilerPlugin, isReactCompilerPlugin, isReactCompilerRequested, reactCompilerUnsupportedMessage };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vinext",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.8",
|
|
4
4
|
"description": "Run Next.js apps on Vite. Drop-in replacement for the next CLI.",
|
|
5
5
|
"homepage": "https://vinext.dev/",
|
|
6
6
|
"license": "MIT",
|
|
@@ -182,7 +182,7 @@
|
|
|
182
182
|
"@types/node": "^25.9.2",
|
|
183
183
|
"@types/react": "^19.2.16",
|
|
184
184
|
"@types/react-dom": "^19.2.3",
|
|
185
|
-
"@vitejs/plugin-react": "^6.0
|
|
185
|
+
"@vitejs/plugin-react": "^6.1.0",
|
|
186
186
|
"@vitejs/plugin-rsc": "^0.5.34",
|
|
187
187
|
"am-i-vibing": "^0.5.0",
|
|
188
188
|
"image-size": "2.0.2",
|