UNPKG

rwsdk

Version:

Build fast, server-driven webapps on Cloudflare with SSR, RSC, and realtime

111 lines (110 loc) 4.98 kB
import { resolve } from "node:path"; import { unstable_readConfig } from "wrangler"; import { cloudflare } from "@cloudflare/vite-plugin"; import { devServerConstantPlugin } from "./devServerConstant.mjs"; import { hasOwnCloudflareVitePlugin } from "./hasOwnCloudflareVitePlugin.mjs"; import reactPlugin from "@vitejs/plugin-react"; import tsconfigPaths from "vite-tsconfig-paths"; import { transformJsxScriptTagsPlugin } from "./transformJsxScriptTagsPlugin.mjs"; import { directivesPlugin } from "./directivesPlugin.mjs"; import { useClientLookupPlugin } from "./useClientLookupPlugin.mjs"; import { useServerLookupPlugin } from "./useServerLookupPlugin.mjs"; import { miniflareHMRPlugin } from "./miniflareHMRPlugin.mjs"; import { moveStaticAssetsPlugin } from "./moveStaticAssetsPlugin.mjs"; import { configPlugin } from "./configPlugin.mjs"; import { $ } from "../lib/$.mjs"; import { reactConditionsResolverPlugin } from "./reactConditionsResolverPlugin.mjs"; import { findWranglerConfig } from "../lib/findWranglerConfig.mjs"; import { pathExists } from "fs-extra"; import { injectVitePreamble } from "./injectVitePreamblePlugin.mjs"; import { vitePreamblePlugin } from "./vitePreamblePlugin.mjs"; import { prismaPlugin } from "./prismaPlugin.mjs"; import { ssrBridgePlugin } from "./ssrBridgePlugin.mjs"; import { hasPkgScript } from "../lib/hasPkgScript.mjs"; import { devServerTimingPlugin } from "./devServerTimingPlugin.mjs"; const determineWorkerEntryPathname = async (projectRootDir, workerConfigPath, options) => { if (options.entry?.worker) { return resolve(projectRootDir, options.entry.worker); } const workerConfig = unstable_readConfig({ config: workerConfigPath }); return resolve(projectRootDir, workerConfig.main ?? "src/worker.tsx"); }; export const redwoodPlugin = async (options = {}) => { const projectRootDir = process.cwd(); const workerConfigPath = options.configPath ?? (process.env.RWSDK_WRANGLER_CONFIG ? resolve(projectRootDir, process.env.RWSDK_WRANGLER_CONFIG) : await findWranglerConfig(projectRootDir)); const workerEntryPathname = await determineWorkerEntryPathname(projectRootDir, workerConfigPath, options); const clientEntryPathnames = (Array.isArray(options.entry?.client) ? options.entry.client : [options.entry?.client ?? "src/client.tsx"]).map((entry) => resolve(projectRootDir, entry)); const clientFiles = new Set(); const serverFiles = new Set(); const shouldIncludeCloudflarePlugin = options.includeCloudflarePlugin ?? !(await hasOwnCloudflareVitePlugin({ rootProjectDir: projectRootDir })); // context(justinvdm, 31 Mar 2025): We assume that if there is no .wrangler directory, // then this is fresh install, and we run `npm run dev:init` here. if (process.env.RWSDK_WORKER_RUN !== "1" && process.env.RWSDK_DEPLOY !== "1" && !(await pathExists(resolve(projectRootDir, ".wrangler"))) && (await hasPkgScript(projectRootDir, "dev:init"))) { console.log("🚀 Project has no .wrangler directory yet, assuming fresh install: running `npm run dev:init`..."); await $({ // context(justinvdm, 01 Apr 2025): We want to avoid interactive migration y/n prompt, so we ignore stdin // as a signal to operate in no-tty mode stdio: ["ignore", "inherit", "inherit"], }) `npm run dev:init`; } return [ devServerTimingPlugin(), devServerConstantPlugin(), configPlugin({ silent: options.silent ?? false, projectRootDir, clientEntryPathnames, workerEntryPathname, }), ssrBridgePlugin({ clientFiles, serverFiles, projectRootDir, }), reactConditionsResolverPlugin(), tsconfigPaths({ root: projectRootDir }), shouldIncludeCloudflarePlugin ? cloudflare({ viteEnvironment: { name: "worker" }, configPath: workerConfigPath, }) : [], miniflareHMRPlugin({ clientFiles, serverFiles, rootDir: projectRootDir, viteEnvironment: { name: "worker" }, workerEntryPathname, }), reactPlugin(), directivesPlugin({ projectRootDir, clientFiles, serverFiles, }), vitePreamblePlugin(), injectVitePreamble({ clientEntryPathnames }), useClientLookupPlugin({ projectRootDir, clientFiles, }), useServerLookupPlugin({ projectRootDir, serverFiles, }), transformJsxScriptTagsPlugin({ manifestPath: resolve(projectRootDir, "dist", "client", ".vite", "manifest.json"), }), moveStaticAssetsPlugin({ rootDir: projectRootDir }), prismaPlugin({ projectRootDir }), ]; };