add workers support for tanstack start (#369)

This commit is contained in:
Aman Varshney
2025-07-06 16:32:13 +05:30
committed by GitHub
parent 79479e01f5
commit 0ae1347e9d
11 changed files with 252 additions and 254 deletions

View File

@@ -42,24 +42,6 @@ export async function addDeploymentToProject(
);
}
if (input.webDeploy === "workers") {
const compatibleFrontends = [
"tanstack-router",
"react-router",
"solid",
"next",
"svelte",
];
const hasCompatible = detectedConfig.frontend?.some((f) =>
compatibleFrontends.includes(f),
);
if (!hasCompatible) {
exitWithError(
"Cloudflare Workers deployment requires a compatible web frontend (tanstack-router, react-router, solid, next, or svelte).",
);
}
}
const config: ProjectConfig = {
projectName: detectedConfig.projectName || path.basename(projectDir),
projectDir,

View File

@@ -851,6 +851,7 @@ export async function setupDeploymentTemplates(
const templateMap: Record<string, string> = {
"tanstack-router": "react/tanstack-router",
"tanstack-start": "react/tanstack-start",
"react-router": "react/react-router",
solid: "solid",
next: "react/next",

View File

@@ -4,6 +4,7 @@ import type { PackageManager, ProjectConfig } from "../../types";
import { addPackageDependency } from "../../utils/add-package-deps";
import { setupNuxtWorkersDeploy } from "./workers-nuxt-setup";
import { setupSvelteWorkersDeploy } from "./workers-svelte-setup";
import { setupTanstackStartWorkersDeploy } from "./workers-tanstack-start-setup";
import { setupWorkersVitePlugin } from "./workers-vite-setup";
export async function setupWebDeploy(config: ProjectConfig): Promise<void> {
@@ -18,6 +19,7 @@ export async function setupWebDeploy(config: ProjectConfig): Promise<void> {
const isNuxt = frontend.includes("nuxt");
const isSvelte = frontend.includes("svelte");
const isTanstackRouter = frontend.includes("tanstack-router");
const isTanstackStart = frontend.includes("tanstack-start");
const isReactRouter = frontend.includes("react-router");
const isSolid = frontend.includes("solid");
@@ -27,6 +29,8 @@ export async function setupWebDeploy(config: ProjectConfig): Promise<void> {
await setupNuxtWorkersDeploy(projectDir, packageManager);
} else if (isSvelte) {
await setupSvelteWorkersDeploy(projectDir, packageManager);
} else if (isTanstackStart) {
await setupTanstackStartWorkersDeploy(projectDir, packageManager);
} else if (isTanstackRouter || isReactRouter || isSolid) {
await setupWorkersWebDeploy(projectDir, packageManager);
}

View File

@@ -0,0 +1,75 @@
import path from "node:path";
import fs from "fs-extra";
import {
type CallExpression,
Node,
type ObjectLiteralExpression,
SyntaxKind,
} from "ts-morph";
import type { PackageManager } from "../../types";
import { addPackageDependency } from "../../utils/add-package-deps";
import { ensureArrayProperty, tsProject } from "../../utils/ts-morph";
export async function setupTanstackStartWorkersDeploy(
projectDir: string,
packageManager: PackageManager,
): Promise<void> {
const webAppDir = path.join(projectDir, "apps/web");
if (!(await fs.pathExists(webAppDir))) return;
await addPackageDependency({
devDependencies: ["wrangler"],
projectDir: webAppDir,
});
const pkgPath = path.join(webAppDir, "package.json");
if (await fs.pathExists(pkgPath)) {
const pkg = await fs.readJson(pkgPath);
pkg.scripts = {
...pkg.scripts,
deploy: `${packageManager} run build && wrangler deploy`,
"cf-typegen": "wrangler types --env-interface Env",
};
await fs.writeJson(pkgPath, pkg, { spaces: 2 });
}
const viteConfigPath = path.join(webAppDir, "vite.config.ts");
if (!(await fs.pathExists(viteConfigPath))) return;
const sourceFile = tsProject.addSourceFileAtPathIfExists(viteConfigPath);
if (!sourceFile) return;
const defineCall = sourceFile
.getDescendantsOfKind(SyntaxKind.CallExpression)
.find((expr) => {
const expression = expr.getExpression();
return (
Node.isIdentifier(expression) && expression.getText() === "defineConfig"
);
}) as CallExpression | undefined;
if (!defineCall) return;
const configObj = defineCall.getArguments()[0] as
| ObjectLiteralExpression
| undefined;
if (!configObj) return;
const pluginsArray = ensureArrayProperty(configObj, "plugins");
const tanstackPluginIndex = pluginsArray
.getElements()
.findIndex((el) => el.getText().includes("tanstackStart("));
const tanstackPluginText = 'tanstackStart({ target: "cloudflare-module" })';
if (tanstackPluginIndex === -1) {
pluginsArray.addElement(tanstackPluginText);
} else {
pluginsArray
.getElements()
[tanstackPluginIndex].replaceWithText(tanstackPluginText);
}
await tsProject.save();
}