diff --git a/.changeset/weak-crews-tickle.md b/.changeset/weak-crews-tickle.md new file mode 100644 index 00000000..15cb5a09 --- /dev/null +++ b/.changeset/weak-crews-tickle.md @@ -0,0 +1,11 @@ +--- +"@opennextjs/cloudflare": minor +--- + +Support multiple Wrangler configuration files via `--config` flag + +Enable passing multiple configuration files to the OpenNext.js Cloudflare CLI +using the `--config` flag, matching Wrangler's native capability. This allows +running multiple workers in a single dev session, which is essential for RPC +communication with Durable Objects during local development as documented in the +[Wrangler API bindings guide](https://developers.cloudflare.com/workers/wrangler/api/#supported-bindings) diff --git a/packages/cloudflare/src/cli/commands/deploy.ts b/packages/cloudflare/src/cli/commands/deploy.ts index 033336c6..a8771e99 100644 --- a/packages/cloudflare/src/cli/commands/deploy.ts +++ b/packages/cloudflare/src/cli/commands/deploy.ts @@ -28,7 +28,7 @@ export async function deployCommand(args: WithWranglerArgs<{ cacheChunkSize: num const wranglerConfig = readWranglerConfig(args); const envVars = await getEnvFromPlatformProxy({ - configPath: args.wranglerConfigPath, + configPath: args.nextjsWranglerConfigPath, environment: args.env, }); @@ -37,7 +37,7 @@ export async function deployCommand(args: WithWranglerArgs<{ cacheChunkSize: num await populateCache(options, config, wranglerConfig, { target: "remote", environment: args.env, - wranglerConfigPath: args.wranglerConfigPath, + wranglerConfigPath: args.nextjsWranglerConfigPath, cacheChunkSize: args.cacheChunkSize, }); diff --git a/packages/cloudflare/src/cli/commands/populate-cache.ts b/packages/cloudflare/src/cli/commands/populate-cache.ts index f4fcd110..5412e8f9 100644 --- a/packages/cloudflare/src/cli/commands/populate-cache.ts +++ b/packages/cloudflare/src/cli/commands/populate-cache.ts @@ -313,7 +313,7 @@ async function populateCacheCommand( await populateCache(options, config, wranglerConfig, { target, environment: args.env, - wranglerConfigPath: args.wranglerConfigPath, + wranglerConfigPath: args.nextjsWranglerConfigPath, cacheChunkSize: args.cacheChunkSize, }); } diff --git a/packages/cloudflare/src/cli/commands/preview.ts b/packages/cloudflare/src/cli/commands/preview.ts index fbcc44ee..a9c0221c 100644 --- a/packages/cloudflare/src/cli/commands/preview.ts +++ b/packages/cloudflare/src/cli/commands/preview.ts @@ -27,7 +27,7 @@ export async function previewCommand(args: WithWranglerArgs<{ cacheChunkSize: nu await populateCache(options, config, wranglerConfig, { target: "local", environment: args.env, - wranglerConfigPath: args.wranglerConfigPath, + wranglerConfigPath: args.nextjsWranglerConfigPath, cacheChunkSize: args.cacheChunkSize, }); diff --git a/packages/cloudflare/src/cli/commands/upload.ts b/packages/cloudflare/src/cli/commands/upload.ts index 8c35fb92..f294cc5a 100644 --- a/packages/cloudflare/src/cli/commands/upload.ts +++ b/packages/cloudflare/src/cli/commands/upload.ts @@ -28,7 +28,7 @@ export async function uploadCommand(args: WithWranglerArgs<{ cacheChunkSize: num const wranglerConfig = readWranglerConfig(args); const envVars = await getEnvFromPlatformProxy({ - configPath: args.wranglerConfigPath, + configPath: args.nextjsWranglerConfigPath, environment: args.env, }); @@ -37,7 +37,7 @@ export async function uploadCommand(args: WithWranglerArgs<{ cacheChunkSize: num await populateCache(options, config, wranglerConfig, { target: "remote", environment: args.env, - wranglerConfigPath: args.wranglerConfigPath, + wranglerConfigPath: args.nextjsWranglerConfigPath, cacheChunkSize: args.cacheChunkSize, }); diff --git a/packages/cloudflare/src/cli/commands/utils.ts b/packages/cloudflare/src/cli/commands/utils.ts index 6da771b6..3f6631ee 100644 --- a/packages/cloudflare/src/cli/commands/utils.ts +++ b/packages/cloudflare/src/cli/commands/utils.ts @@ -15,7 +15,9 @@ import { createOpenNextConfigIfNotExistent, ensureCloudflareConfig } from "../bu export type WithWranglerArgs = T & { // Array of arguments that can be given to wrangler commands, including the `--config` and `--env` args. wranglerArgs: string[]; - wranglerConfigPath: string | undefined; + wranglerConfigPath: string[] | undefined; + // The first wrangler config path passed into the CLI, if any. Assumed to be the one used for OpenNext. + nextjsWranglerConfigPath: string | undefined; env: string | undefined; }; @@ -101,7 +103,7 @@ export function getNormalizedOptions(config: OpenNextConfig, buildDir = nextAppD * @returns Wrangler config. */ export function readWranglerConfig(args: WithWranglerArgs) { - return unstable_readConfig({ env: args.env, config: args.wranglerConfigPath }); + return unstable_readConfig({ env: args.env, config: args.nextjsWranglerConfigPath }); } /** @@ -111,6 +113,7 @@ export function withWranglerOptions(args: T) { return args .option("config", { type: "string", + array: true, alias: "c", desc: "Path to Wrangler configuration file", }) @@ -128,7 +131,7 @@ export function withWranglerOptions(args: T) { type WranglerInputArgs = { configPath: string | undefined; - config: string | undefined; + config: string[] | undefined; env: string | undefined; }; @@ -143,7 +146,7 @@ function getWranglerArgs(args: WranglerInputArgs & { _: (string | number)[] }): if (args.config) { logger.error( - "Multiple config flags found. Please use the `--config` flag for your Wrangler config path." + "Duplicate config flags found. Unable to pass both `--config` and `--configPath`. Please use the `--config` flag for your Wrangler config path." ); process.exit(1); } @@ -151,7 +154,7 @@ function getWranglerArgs(args: WranglerInputArgs & { _: (string | number)[] }): return [ ...(args.configPath ? ["--config", args.configPath] : []), - ...(args.config ? ["--config", args.config] : []), + ...(args.config ? args.config.flatMap((c) => ["--config", c]) : []), ...(args.env ? ["--env", args.env] : []), // Note: the first args in `_` will be the commands. ...args._.slice(args._[0] === "populateCache" ? 2 : 1).map((a) => `${a}`), @@ -166,9 +169,15 @@ function getWranglerArgs(args: WranglerInputArgs & { _: (string | number)[] }): export function withWranglerPassthroughArgs>( args: T ): WithWranglerArgs { + const wranglerConfigPath = args.config ?? (args.configPath ? [args.configPath] : undefined); + if (wranglerConfigPath && wranglerConfigPath.length > 1) { + logger.info("Multiple Wrangler config paths found, first config assumed as opennext config."); + } + return { ...args, - wranglerConfigPath: args.config ?? args.configPath, + wranglerConfigPath, + nextjsWranglerConfigPath: wranglerConfigPath?.[0], wranglerArgs: getWranglerArgs(args), }; }