vite-plugin-react-server
Version:
Vite plugin for React Server Components (RSC)
125 lines (109 loc) • 3.69 kB
text/typescript
import {
createLogger,
type ConfigEnv,
type ResolvedConfig,
type Logger,
} from "vite";
import type {
AutoDiscoveredFiles,
ResolvedUserConfig,
VitePluginFn,
} from "../types.js";
import { resolveOptions } from "../config/resolveOptions.js";
import { resolveUserConfig } from "../config/resolveUserConfig.js";
import { resolveAutoDiscover } from "../config/autoDiscover/resolveAutoDiscover.js";
import { handleError } from "../error/handleError.js";
import { assertNonReactServer } from "../config/getCondition.js";
assertNonReactServer();
/**
* Main entry for `react-client` behavior. This plugin is imported when the plugin is imported from the main
* entrypoint and the condition is not `react-server`.
*
* This plugin is responsible for:
* Dev mode under non-react-server conditions:
* - Disabled, user react-server/plugin.client.ts instead
* Build mode under non-react-server conditions:
* - Configure the config for the client boundary build
* @param options
* @returns
*/
export const reactClientPlugin: VitePluginFn = function _reactClientPlugin(
options
) {
let userConfig: ResolvedUserConfig;
let configEnv: ConfigEnv;
let autoDiscoveredFiles: AutoDiscoveredFiles;
let resolvedConfig: ResolvedConfig | null = null;
let logger: Logger;
let implicitSsr: boolean | undefined = undefined;
// Initial options resolution
const resolvedOptions = resolveOptions(options);
if (resolvedOptions.type === "error") {
if (resolvedOptions.error != null) {
throw resolvedOptions.error;
}
throw new Error("Failed to resolve options");
}
const currentUserOptions = resolvedOptions.userOptions;
return {
name: "vite:plugin-react-server/client",
enforce: "post",
async config(config, viteConfigEnv) {
configEnv = viteConfigEnv;
if (configEnv.command !== "build") {
return;
}
if(typeof config?.build?.ssr === "boolean" || typeof config?.build?.ssr === "string") {
implicitSsr = Boolean(config?.build?.ssr);
} else if(implicitSsr === undefined) {
implicitSsr = configEnv.isSsrBuild;
}
const logger = config.customLogger || createLogger();
const autoDiscoverResult = await resolveAutoDiscover({
config,
configEnv,
userOptions: currentUserOptions,
logger,
});
if (autoDiscoverResult.type === "error") {
const panicError = handleError({
error: autoDiscoverResult.error,
logger,
panicThreshold: currentUserOptions.panicThreshold,
context: "config(autoDiscover)",
});
if (panicError != null) {
throw panicError;
}
return;
}
autoDiscoveredFiles = autoDiscoverResult.autoDiscoveredFiles;
if (!autoDiscoveredFiles) {
throw new Error("Failed to find autoDiscoveredFiles");
}
const resolvedConfig = resolveUserConfig({
condition: "react-client",
config,
configEnv,
userOptions: currentUserOptions,
autoDiscoveredFiles,
ssr: implicitSsr,
});
if (resolvedConfig.type === "error") {
if (resolvedConfig.error != null) {
throw resolvedConfig.error;
}
throw new Error("Failed to resolve config");
}
userConfig = resolvedConfig.userConfig;
return userConfig;
},
configResolved(viteResolvedConfig) {
if (currentUserOptions.verbose) {
logger?.info("configResolved");
}
resolvedConfig = viteResolvedConfig;
logger = resolvedConfig.customLogger || resolvedConfig.logger;
},
};
};