1export interface BasePluginOptions {
2 /**
3 * The main entry point to use.
4 * Defaults to the one from your Rolldown configuration.
5 * @default undefined
6 */
7 main?: string;
8 /**
9 * The compatibility date to use. This is optional, but should be defined to avoid unexpected behavior.
10 * @default undefined
11 */
12 compatibilityDate?: string;
13 /**
14 * The compatibility flags to enable.
15 * @default []
16 * @example
17 * ```ts
18 * cloudflare({ compatibilityDate: "2026-08-31" });
19 * ```
20 */
21 compatibilityFlags?: Array<string>;
22 /**
23 * Whether external CommonJS `require()` calls should be rewritten as ESM.
24 * Internal single-module Workers disable this because they cannot carry the
25 * generated helper chunk; user bundles should leave it enabled.
26 * @default true
27 */
28 externalRequire?: boolean;
29 /**
30 * The exports to include in the bundle.
31 * By default, all exports are included. However, if you only want to include certain exports, you can use this option.
32 * @example
33 * ```ts
34 * cloudflare({ exports: ["default"] });
35 * ```
36 */
37 exports?: Array<string>;
38 /**
39 * Which Vite environment hosts the Worker, and any child environments it
40 * loads at runtime. Defaults to the single `ssr` environment.
41 *
42 * `@vitejs/plugin-rsc` apps run the Worker in the `rsc` environment (resolved
43 * with the `react-server` condition) and load the `ssr` environment from it,
44 * so they set `{ name: "rsc", childEnvironments: ["ssr"] }`. Every named
45 * environment is given the Worker treatment (workerd resolve conditions,
46 * dependency pre-bundling) and a module runner in dev.
47 *
48 * @default { entry: "ssr", children: [] }
49 */
50 viteEnvironments?: {
51 entry?: string;
52 children?: Array<string>;
53 };
54 /**
55 * Vite environment names that must be left untouched by the Cloudflare
56 * plugins. Frameworks can add Node-side server environments to the same dev
57 * server or builder (e.g. Astro's `astro` and `prerender` environments), and
58 * applying the Worker treatment (unenv polyfills, workerd resolve
59 * conditions, dependency pre-bundling) to them breaks their Node runtime.
60 *
61 * The `client` environment is always excluded and does not need to be
62 * listed here.
63 *
64 * @default []
65 * @example
66 * ```ts
67 * cloudflare({ viteEnvironments: { entry: "ssr" }, skipEnvironments: ["astro", "prerender"] });
68 * ```
69 */
70 skipEnvironments?: Array<string>;
71}
72
73/**
74 * Whether the named Vite environment must be left untouched by the Cloudflare
75 * plugins — the browser `client` environment, plus anything the user listed in
76 * {@link BasePluginOptions.skipEnvironments}.
77 */
78export const isSkippedEnvironment = (
79 options: BasePluginOptions,
80 name: string,
81): boolean =>
82 name === "client" || (options.skipEnvironments?.includes(name) ?? false);
83
84export const parseViteEnvironments = (
85 options: BasePluginOptions,
86): [string, ...Array<string>] => {
87 const entry = options.viteEnvironments?.entry ?? "ssr";
88 if (entry === "client") {
89 throw new Error(
90 'The "client" environment cannot be used as a worker environment because it is reserved for the browser.',
91 );
92 }
93 const children = (options.viteEnvironments?.children ?? []).map(
94 (name, index, self) => {
95 if (name === "client") {
96 throw new Error(
97 'The "client" environment cannot be used as a worker environment because it is reserved for the browser.',
98 );
99 } else if (self.indexOf(name) !== index) {
100 throw new Error(
101 `The name "${name}" appears more than once in the Vite environment list. Worker environment names must be unique.`,
102 );
103 } else if (name === entry) {
104 throw new Error(
105 `The child environment "${name}" cannot have the same name as the entry environment "${entry}".`,
106 );
107 }
108 return name;
109 },
110 );
111 for (const name of options.skipEnvironments ?? []) {
112 if (name === entry || children.includes(name)) {
113 throw new Error(
114 `The environment "${name}" cannot be both a worker environment and listed in "skipEnvironments".`,
115 );
116 }
117 }
118 return [entry, ...children];
119};