| 1 | export 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 | */ |
| 78 | export const isSkippedEnvironment = ( |
| 79 | options: BasePluginOptions, |
| 80 | name: string, |
| 81 | ): boolean => |
| 82 | name === "client" || (options.skipEnvironments?.includes(name) ?? false); |
| 83 | |
| 84 | export 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 | }; |