create-bhvr
Version:
Create a new bhvr project
108 lines (107 loc) • 5.15 kB
JavaScript
import path from "node:path";
import fs from "fs-extra";
import yoctoSpinner from "yocto-spinner";
import pc from "picocolors";
import { consola } from "consola";
import { addPackageDependency } from "@/utils/add-package-dependency";
import { EXTRAS_DIR } from "@/utils";
import { nameGenerator } from "@/utils/name-generator";
export const reactRouterMpaInstaller = async (options) => {
const spinner = yoctoSpinner({
text: "Setting up React Router MPA...",
}).start();
try {
const { projectName, rpc, shadcn, tailwind, tanstackQuery } = options;
const projectPath = path.resolve(process.cwd(), projectName);
spinner.text = "Installing React Router MPA dependencies...";
await addPackageDependency({
dependencies: [
"react-router",
"@react-router/dev",
"@react-router/node",
"@react-router/serve",
"vite-tsconfig-paths",
"isbot",
],
target: "client",
projectName,
});
// Copy root.tsx
const rootTsxSrc = path.join(EXTRAS_DIR, "client", "src", "root.tsx", "root.tsx");
const rootTsxTarget = path.join(projectPath, "client", "src", "root.tsx");
fs.copySync(rootTsxSrc, rootTsxTarget);
// Copy routes.ts
const routesTsSrc = path.join(EXTRAS_DIR, "client", "src", "routes.ts", "routes.ts");
const routesTsTarget = path.join(projectPath, "client", "src", "routes.ts");
fs.copySync(routesTsSrc, routesTsTarget);
// Create routes directory and copy home.tsx
const routesDir = path.join(projectPath, "client", "src", "routes");
fs.ensureDirSync(routesDir);
const homeTsxSrc = path.join(EXTRAS_DIR, "client", "src", "routes", "home.tsx", "home.tsx");
const homeTsxTarget = path.join(routesDir, "home.tsx");
fs.copySync(homeTsxSrc, homeTsxTarget);
// Copy ClientOnly component
const clientOnlySrc = path.join(EXTRAS_DIR, "client", "src", "components", "ClientOnly.tsx", "ClientOnly.tsx");
const clientOnlyTarget = path.join(projectPath, "client", "src", "components", "ClientOnly.tsx");
fs.copySync(clientOnlySrc, clientOnlyTarget);
// Update Home component with ClientOnly wrapper
const homeTsxTemplate = nameGenerator("Home.tsx", {
reactroutermpa: true,
rpc,
shadcn,
tailwind,
tanstackQuery,
});
const homeComponentSrc = path.join(EXTRAS_DIR, "client", "src", "components", "Home.tsx", homeTsxTemplate);
const homeComponentTarget = path.join(projectPath, "client", "src", "components", "Home.tsx");
fs.copySync(homeComponentSrc, homeComponentTarget);
// Remove unused files (App.tsx and main.tsx are not used in MPA setup)
const appTsxPath = path.join(projectPath, "client", "src", "App.tsx");
const mainTsxPath = path.join(projectPath, "client", "src", "main.tsx");
if (fs.existsSync(appTsxPath)) {
fs.removeSync(appTsxPath);
}
if (fs.existsSync(mainTsxPath)) {
fs.removeSync(mainTsxPath);
}
// Copy react-router.config.ts
const reactRouterConfigSrc = path.join(EXTRAS_DIR, "client", "react-router.config.ts", "react-router.config.ts");
const reactRouterConfigTarget = path.join(projectPath, "client", "react-router.config.ts");
fs.copySync(reactRouterConfigSrc, reactRouterConfigTarget);
// Copy tsconfig.app.json
const tsconfigAppSrc = path.join(EXTRAS_DIR, "client", "tsconfig.app.json", "tsconfig.app.json");
const tsconfigAppTarget = path.join(projectPath, "client", "tsconfig.app.json");
fs.copySync(tsconfigAppSrc, tsconfigAppTarget);
// Update vite.config.ts
const viteConfigTemplate = nameGenerator("vite.config.ts", {
reactroutermpa: true,
shadcn,
tailwind,
});
const viteConfigSrc = path.join(EXTRAS_DIR, "client", "vite.config.ts", viteConfigTemplate);
const viteConfigTarget = path.join(projectPath, "client", "vite.config.ts");
fs.copySync(viteConfigSrc, viteConfigTarget);
// Update package.json scripts
const packageJsonPath = path.join(projectPath, "client", "package.json");
const packageJson = fs.readJsonSync(packageJsonPath);
packageJson.scripts = {
...packageJson.scripts,
dev: "react-router dev",
build: "react-router typegen && tsc -b && react-router build",
typecheck: "react-router typegen && tsc",
};
fs.writeJsonSync(packageJsonPath, packageJson, { spaces: 2 });
spinner.success("React Router MPA setup completed");
return true;
}
catch (err) {
spinner.error("Failed to set up React Router MPA");
if (err instanceof Error) {
consola.error(pc.red("Error:"), err.message);
}
else {
consola.error(pc.red("Error: Unknown error"));
}
return false;
}
};