Skip to content

Commit

Permalink
Add Vite 6 support (#12469)
Browse files Browse the repository at this point in the history
  • Loading branch information
markdalgleish authored Dec 17, 2024
1 parent 3be44ec commit 5115991
Show file tree
Hide file tree
Showing 38 changed files with 1,423 additions and 2,315 deletions.
5 changes: 5 additions & 0 deletions .changeset/lovely-lemons-bake.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@react-router/dev": minor
---

Add support for Vite v6
2 changes: 1 addition & 1 deletion integration/helpers/create-fixture.ts
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,7 @@ export async function createFixtureProject(
init: FixtureInit = {},
mode?: ServerMode
): Promise<string> {
let template = "vite-template";
let template = "vite-5-template";
let integrationTemplateDir = path.resolve(__dirname, template);
let projectName = `rr-${template}-${Math.random().toString(32).slice(2)}`;
let projectDir = path.join(TMP_DIR, projectName);
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "integration-vite-template",
"name": "integration-vite-5-template",
"version": "0.0.0",
"private": true,
"sideEffects": false,
Expand Down
Binary file not shown.
11 changes: 11 additions & 0 deletions integration/helpers/vite-5-template/vite.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { reactRouter } from "@react-router/dev/vite";
import { defineConfig } from "vite";
import tsconfigPaths from "vite-tsconfig-paths";

export default defineConfig({
plugins: [
// @ts-expect-error `dev` depends on Vite 6, Plugin type is mismatched.
reactRouter(),
tsconfigPaths(),
],
});
6 changes: 6 additions & 0 deletions integration/helpers/vite-6-template/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
node_modules

/.cache
/build
.env
.react-router
19 changes: 19 additions & 0 deletions integration/helpers/vite-6-template/app/root.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { Links, Meta, Outlet, Scripts, ScrollRestoration } from "react-router";

export default function App() {
return (
<html lang="en">
<head>
<meta charSet="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<Meta />
<Links />
</head>
<body>
<Outlet />
<ScrollRestoration />
<Scripts />
</body>
</html>
);
}
4 changes: 4 additions & 0 deletions integration/helpers/vite-6-template/app/routes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { type RouteConfig } from "@react-router/dev/routes";
import { flatRoutes } from "@react-router/fs-routes";

export default flatRoutes() satisfies RouteConfig;
16 changes: 16 additions & 0 deletions integration/helpers/vite-6-template/app/routes/_index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import type { MetaFunction } from "react-router";

export const meta: MetaFunction = () => {
return [
{ title: "New React Router App" },
{ name: "description", content: "Welcome to React Router!" },
];
};

export default function Index() {
return (
<div style={{ fontFamily: "system-ui, sans-serif", lineHeight: "1.8" }}>
<h1>Welcome to React Router</h1>
</div>
);
}
2 changes: 2 additions & 0 deletions integration/helpers/vite-6-template/env.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/// <reference types="@react-router/node" />
/// <reference types="vite/client" />
41 changes: 41 additions & 0 deletions integration/helpers/vite-6-template/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"name": "integration-vite-6-template",
"version": "0.0.0",
"private": true,
"sideEffects": false,
"type": "module",
"scripts": {
"dev": "react-router dev",
"build": "react-router build",
"start": "react-router-serve ./build/server/index.js",
"typecheck": "react-router typegen && tsc"
},
"dependencies": {
"@react-router/express": "workspace:*",
"@react-router/node": "workspace:*",
"@react-router/serve": "workspace:*",
"@vanilla-extract/css": "^1.10.0",
"@vanilla-extract/vite-plugin": "^3.9.2",
"express": "^4.19.2",
"isbot": "^5.1.11",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router": "workspace:*",
"serialize-javascript": "^6.0.1"
},
"devDependencies": {
"@react-router/dev": "workspace:*",
"@react-router/fs-routes": "workspace:*",
"@react-router/remix-routes-option-adapter": "workspace:*",
"@types/react": "^18.2.20",
"@types/react-dom": "^18.2.7",
"eslint": "^8.38.0",
"typescript": "^5.1.6",
"vite": "^6.0.0",
"vite-env-only": "^3.0.1",
"vite-tsconfig-paths": "^4.2.1"
},
"engines": {
"node": ">=20.0.0"
}
}
Binary file not shown.
27 changes: 27 additions & 0 deletions integration/helpers/vite-6-template/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"include": [
"env.d.ts",
"**/*.ts",
"**/*.tsx",
".react-router/types/**/*.d.ts"
],
"compilerOptions": {
"lib": ["DOM", "DOM.Iterable", "ES2022"],
"verbatimModuleSyntax": true,
"esModuleInterop": true,
"jsx": "react-jsx",
"module": "ESNext",
"moduleResolution": "Bundler",
"resolveJsonModule": true,
"target": "ES2022",
"strict": true,
"allowJs": true,
"skipLibCheck": true,
"baseUrl": ".",
"paths": {
"~/*": ["./app/*"]
},
"noEmit": true,
"rootDirs": [".", ".react-router/types/"]
}
}
2 changes: 1 addition & 1 deletion integration/helpers/vite-cloudflare-template/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
"@types/react": "^18.2.20",
"@types/react-dom": "^18.2.7",
"typescript": "^5.1.6",
"vite": "^5.1.0",
"vite": "^6.0.0",
"wrangler": "^3.28.2"
},
"engines": {
Expand Down
Binary file removed integration/helpers/vite-template/public/favicon.ico
Binary file not shown.
71 changes: 64 additions & 7 deletions integration/helpers/vite.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { spawn, spawnSync, type ChildProcess } from "node:child_process";
import path from "node:path";
import path from "pathe";
import fs from "node:fs/promises";
import type { Readable } from "node:stream";
import url from "node:url";
Expand Down Expand Up @@ -123,19 +123,73 @@ export const EXPRESS_SERVER = (args: {
app.listen(port, () => console.log('http://localhost:' + port));
`;

type TemplateName = "vite-template" | "vite-cloudflare-template";
type TemplateName =
| "vite-5-template"
| "vite-6-template"
| "vite-cloudflare-template";

export const viteMajorTemplates = [
{ templateName: "vite-5-template", templateDisplayName: "Vite 5" },
{ templateName: "vite-6-template", templateDisplayName: "Vite 6" },
] as const satisfies Array<{
templateName: TemplateName;
templateDisplayName: string;
}>;

function resolveDevPackageDir(root: string) {
return path.join(root, "node_modules", "@react-router", "dev");
}

function resolveDevPackageNodeModulesDir(root: string) {
return path.join(resolveDevPackageDir(root), "node_modules");
}

async function copyDirContents(
srcDir: string,
destDir: string,
filter?: (file: string) => boolean
) {
for (const file of await fse.readdir(srcDir)) {
if (filter && !filter(path.normalize(file))) {
continue;
}
const srcFile = path.join(srcDir, file);
const destFile = path.join(destDir, file);
await fse.copy(srcFile, destFile, { errorOnExist: true });
}
}

export async function createProject(
files: Record<string, string> = {},
templateName: TemplateName = "vite-template"
templateName: TemplateName = "vite-5-template"
) {
let projectName = `rr-${Math.random().toString(32).slice(2)}`;
let projectDir = path.join(TMP_DIR, projectName);
await fse.ensureDir(projectDir);

// base template
let templateDir = path.resolve(__dirname, templateName);
await fse.copy(templateDir, projectDir, { errorOnExist: true });

// When we copy the template, we need to filter out the version of Vite
// installed locally within @react-router/dev. If we don't do this, the dev
// package doesn't use the version of Vite defined within the test template
// which means we can't run integration tests across different versions of
// Vite. Since pnpm uses symlinks for dependencies, we need to perform the
// copy in multiple steps so that we can filter at each level.
await fse.copy(templateDir, projectDir, {
errorOnExist: true,
filter: (src) => !path.normalize(src).endsWith("/@react-router/dev"),
});
await copyDirContents(
resolveDevPackageDir(templateDir),
resolveDevPackageDir(projectDir),
(file) => file !== "node_modules"
);
await copyDirContents(
resolveDevPackageNodeModulesDir(templateDir),
resolveDevPackageNodeModulesDir(projectDir),
(file) => file !== "vite"
);

// user-defined files
await Promise.all(
Expand Down Expand Up @@ -273,7 +327,10 @@ type Fixtures = {
port: number;
cwd: string;
}>;
customDev: (files: Files) => Promise<{
customDev: (
files: Files,
templateName?: TemplateName
) => Promise<{
port: number;
cwd: string;
}>;
Expand Down Expand Up @@ -307,9 +364,9 @@ export const test = base.extend<Fixtures>({
// eslint-disable-next-line no-empty-pattern
customDev: async ({}, use) => {
let stop: (() => unknown) | undefined;
await use(async (files) => {
await use(async (files, template) => {
let port = await getPort();
let cwd = await createProject(await files({ port }));
let cwd = await createProject(await files({ port }), template);
stop = await customDev({ cwd, port });
return { port, cwd };
});
Expand Down
3 changes: 2 additions & 1 deletion integration/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"glob": "8.0.3",
"isbot": "^5.1.11",
"npm-run-all": "^4.1.5",
"pathe": "^1.1.2",
"postcss": "^8.4.19",
"postcss-import": "^15.1.0",
"prettier": "^2.7.1",
Expand All @@ -40,7 +41,7 @@
"tailwindcss": "^3.3.0",
"type-fest": "^4.0.0",
"typescript": "^5.1.0",
"vite": "^5.1.0",
"vite": "^6.0.0",
"vite-env-only": "^3.0.1",
"vite-tsconfig-paths": "^4.2.2",
"wait-on": "^7.0.1"
Expand Down
Loading

0 comments on commit 5115991

Please sign in to comment.