Skip to content

Commit 47da916

Browse files
committed
move opennext setup to be universal and add commands
1 parent be76e04 commit 47da916

File tree

4 files changed

+103
-113
lines changed

4 files changed

+103
-113
lines changed

packages/cloudflare/src/cli/args.ts

Lines changed: 47 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -2,71 +2,58 @@ import { mkdirSync, type Stats, statSync } from "node:fs";
22
import { resolve } from "node:path";
33
import { parseArgs } from "node:util";
44

5-
import type { CacheBindingMode } from "./build/utils/index.js";
6-
import { isCacheBindingMode } from "./build/utils/index.js";
5+
import type { CacheBindingTarget } from "./build/utils/index.js";
6+
import { isCacheBindingTarget } from "./build/utils/index.js";
77

8-
export function getArgs(): {
9-
skipNextBuild: boolean;
10-
skipWranglerConfigCheck: boolean;
11-
outputDir?: string;
12-
minify: boolean;
13-
populateCache?: { mode: CacheBindingMode; onlyPopulateWithoutBuilding: boolean };
14-
} {
15-
const { skipBuild, skipWranglerConfigCheck, output, noMinify, populateCache, onlyPopulateCache } =
16-
parseArgs({
17-
options: {
18-
skipBuild: {
19-
type: "boolean",
20-
short: "s",
21-
default: false,
22-
},
23-
output: {
24-
type: "string",
25-
short: "o",
26-
},
27-
noMinify: {
28-
type: "boolean",
29-
default: false,
30-
},
31-
skipWranglerConfigCheck: {
32-
type: "boolean",
33-
default: false,
34-
},
35-
populateCache: {
36-
type: "string",
37-
},
38-
onlyPopulateCache: {
39-
type: "boolean",
40-
default: false,
41-
},
42-
},
43-
allowPositionals: false,
44-
}).values;
8+
export type Arguments = (
9+
| {
10+
command: "build";
11+
skipNextBuild: boolean;
12+
skipWranglerConfigCheck: boolean;
13+
minify: boolean;
14+
}
15+
| { command: "preview" | "deploy" }
16+
| { command: "populateCache"; target: CacheBindingTarget }
17+
) & { outputDir?: string };
4518

46-
const outputDir = output ? resolve(output) : undefined;
19+
export function getArgs(): Arguments {
20+
const { positionals, values } = parseArgs({
21+
options: {
22+
skipBuild: { type: "boolean", short: "s", default: false },
23+
output: { type: "string", short: "o" },
24+
noMinify: { type: "boolean", default: false },
25+
skipWranglerConfigCheck: { type: "boolean", default: false },
26+
},
27+
allowPositionals: true,
28+
});
4729

48-
if (outputDir) {
49-
assertDirArg(outputDir, "output", true);
50-
}
30+
const outputDir = values.output ? resolve(values.output) : undefined;
31+
if (outputDir) assertDirArg(outputDir, "output", true);
5132

52-
if (
53-
(populateCache !== undefined || onlyPopulateCache) &&
54-
(!populateCache?.length || !isCacheBindingMode(populateCache))
55-
) {
56-
throw new Error(`Error: missing mode for populate cache flag, expected 'local' | 'remote'`);
33+
switch (positionals[0]) {
34+
case "build":
35+
return {
36+
command: "build",
37+
outputDir,
38+
skipNextBuild:
39+
values.skipBuild || ["1", "true", "yes"].includes(String(process.env.SKIP_NEXT_APP_BUILD)),
40+
skipWranglerConfigCheck:
41+
values.skipWranglerConfigCheck ||
42+
["1", "true", "yes"].includes(String(process.env.SKIP_WRANGLER_CONFIG_CHECK)),
43+
minify: !values.noMinify,
44+
};
45+
case "preview":
46+
return { command: "preview", outputDir };
47+
case "deploy":
48+
return { command: "preview", outputDir };
49+
case "populateCache":
50+
if (!isCacheBindingTarget(positionals[1])) {
51+
throw new Error(`Error: invalid target for populating the cache, expected 'local' | 'remote'`);
52+
}
53+
return { command: "populateCache", outputDir, target: positionals[1] };
54+
default:
55+
throw new Error("Error: invalid command, expected 'build' | 'preview' | 'deploy' | 'populateCache'");
5756
}
58-
59-
return {
60-
outputDir,
61-
skipNextBuild: skipBuild || ["1", "true", "yes"].includes(String(process.env.SKIP_NEXT_APP_BUILD)),
62-
skipWranglerConfigCheck:
63-
skipWranglerConfigCheck ||
64-
["1", "true", "yes"].includes(String(process.env.SKIP_WRANGLER_CONFIG_CHECK)),
65-
minify: !noMinify,
66-
populateCache: populateCache
67-
? { mode: populateCache, onlyPopulateWithoutBuilding: !!onlyPopulateCache }
68-
: undefined,
69-
};
7057
}
7158

7259
function assertDirArg(path: string, argName?: string, make?: boolean) {

packages/cloudflare/src/cli/build/build.ts

Lines changed: 11 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,36 @@
1-
import { createRequire } from "node:module";
2-
import { dirname } from "node:path";
3-
41
import { buildNextjsApp, setStandaloneBuildMode } from "@opennextjs/aws/build/buildNextApp.js";
52
import { compileCache } from "@opennextjs/aws/build/compileCache.js";
6-
import { compileOpenNextConfig } from "@opennextjs/aws/build/compileConfig.js";
73
import { createCacheAssets, createStaticAssets } from "@opennextjs/aws/build/createAssets.js";
84
import { createMiddleware } from "@opennextjs/aws/build/createMiddleware.js";
95
import * as buildHelper from "@opennextjs/aws/build/helper.js";
10-
import { printHeader, showWarningOnWindows } from "@opennextjs/aws/build/utils.js";
6+
import { BuildOptions } from "@opennextjs/aws/build/helper.js";
7+
import { printHeader } from "@opennextjs/aws/build/utils.js";
118
import logger from "@opennextjs/aws/logger.js";
9+
import { OpenNextConfig } from "@opennextjs/aws/types/open-next.js";
1210

1311
import type { ProjectOptions } from "../project-options.js";
1412
import { bundleServer } from "./bundle-server.js";
1513
import { compileCacheAssetsManifestSqlFile } from "./open-next/compile-cache-assets-manifest.js";
1614
import { compileEnvFiles } from "./open-next/compile-env-files.js";
1715
import { copyCacheAssets } from "./open-next/copyCacheAssets.js";
1816
import { createServerBundle } from "./open-next/createServerBundle.js";
19-
import {
20-
createOpenNextConfigIfNotExistent,
21-
createWranglerConfigIfNotExistent,
22-
ensureCloudflareConfig,
23-
populateCache,
24-
} from "./utils/index.js";
17+
import { createWranglerConfigIfNotExistent } from "./utils/index.js";
2518
import { getVersion } from "./utils/version.js";
2619

2720
/**
2821
* Builds the application in a format that can be passed to workerd
2922
*
3023
* It saves the output in a `.worker-next` directory
3124
*
25+
* @param options The OpenNext options
26+
* @param config The OpenNext config
3227
* @param projectOpts The options for the project
3328
*/
34-
export async function build(projectOpts: ProjectOptions): Promise<void> {
35-
printHeader("Cloudflare build");
36-
37-
showWarningOnWindows();
38-
39-
const baseDir = projectOpts.sourceDir;
40-
const require = createRequire(import.meta.url);
41-
const openNextDistDir = dirname(require.resolve("@opennextjs/aws/index.js"));
42-
43-
await createOpenNextConfigIfNotExistent(projectOpts);
44-
45-
const { config, buildDir } = await compileOpenNextConfig(baseDir);
46-
47-
ensureCloudflareConfig(config);
48-
49-
// Initialize options
50-
const options = buildHelper.normalizeOptions(config, openNextDistDir, buildDir);
51-
logger.setLevel(options.debug ? "debug" : "info");
52-
29+
export async function build(
30+
options: BuildOptions,
31+
config: OpenNextConfig,
32+
projectOpts: ProjectOptions
33+
): Promise<void> {
5334
// Do not minify the code so that we can apply string replacement patch.
5435
// Note that wrangler will still minify the bundle.
5536
options.minify = false;
@@ -63,11 +44,6 @@ export async function build(projectOpts: ProjectOptions): Promise<void> {
6344
logger.info(`@opennextjs/cloudflare version: ${cloudflare}`);
6445
logger.info(`@opennextjs/aws version: ${aws}`);
6546

66-
if (projectOpts.populateCache?.onlyPopulateWithoutBuilding) {
67-
populateCache(options, config, projectOpts.populateCache.mode);
68-
return;
69-
}
70-
7147
if (projectOpts.skipNextBuild) {
7248
logger.warn("Skipping Next.js build");
7349
} else {
@@ -109,10 +85,6 @@ export async function build(projectOpts: ProjectOptions): Promise<void> {
10985
await createWranglerConfigIfNotExistent(projectOpts);
11086
}
11187

112-
if (projectOpts.populateCache) {
113-
populateCache(options, config, projectOpts.populateCache.mode);
114-
}
115-
11688
logger.info("OpenNext build complete.");
11789
}
11890

packages/cloudflare/src/cli/build/utils/create-config-files.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,10 +92,10 @@ export async function getLatestCompatDate(): Promise<string | undefined> {
9292
*
9393
* If the user refuses an error is thrown (since the file is mandatory).
9494
*
95-
* @param projectOpts The options for the project
95+
* @param sourceDir The source directory for the project
9696
*/
97-
export async function createOpenNextConfigIfNotExistent(projectOpts: ProjectOptions): Promise<void> {
98-
const openNextConfigPath = join(projectOpts.sourceDir, "open-next.config.ts");
97+
export async function createOpenNextConfigIfNotExistent(sourceDir: string): Promise<void> {
98+
const openNextConfigPath = join(sourceDir, "open-next.config.ts");
9999

100100
if (!existsSync(openNextConfigPath)) {
101101
const answer = await askConfirmation(
Lines changed: 42 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,49 @@
11
#!/usr/bin/env node
2-
import { resolve } from "node:path";
2+
import { createRequire } from "node:module";
3+
import path from "node:path";
34

4-
import { getArgs } from "./args.js";
5+
import { compileOpenNextConfig } from "@opennextjs/aws/build/compileConfig.js";
6+
import { normalizeOptions } from "@opennextjs/aws/build/helper.js";
7+
import { printHeader, showWarningOnWindows } from "@opennextjs/aws/build/utils.js";
8+
import logger from "@opennextjs/aws/logger.js";
9+
10+
import { Arguments, getArgs } from "./args.js";
511
import { build } from "./build/build.js";
12+
import { createOpenNextConfigIfNotExistent, ensureCloudflareConfig } from "./build/utils/index.js";
13+
import { deploy } from "./deploy/deploy.js";
14+
import { populateCache } from "./populate-cache/populate-cache.js";
15+
import { preview } from "./preview/preview.js";
616

717
const nextAppDir = process.cwd();
818

9-
const { skipNextBuild, skipWranglerConfigCheck, outputDir, minify, populateCache } = getArgs();
19+
async function runCommand(args: Arguments) {
20+
printHeader(`Cloudflare ${args.command}`);
21+
22+
showWarningOnWindows();
23+
24+
const baseDir = nextAppDir;
25+
const require = createRequire(import.meta.url);
26+
const openNextDistDir = path.dirname(require.resolve("@opennextjs/aws/index.js"));
27+
28+
await createOpenNextConfigIfNotExistent(baseDir);
29+
const { config, buildDir } = await compileOpenNextConfig(baseDir);
30+
31+
ensureCloudflareConfig(config);
32+
33+
// Initialize options
34+
const options = normalizeOptions(config, openNextDistDir, buildDir);
35+
logger.setLevel(options.debug ? "debug" : "info");
36+
37+
switch (args.command) {
38+
case "build":
39+
return build(options, config, args);
40+
case "preview":
41+
return preview(options, config);
42+
case "deploy":
43+
return deploy(options, config);
44+
case "populateCache":
45+
return populateCache(options, config, { target: args.target });
46+
}
47+
}
1048

11-
await build({
12-
sourceDir: nextAppDir,
13-
outputDir: resolve(outputDir ?? nextAppDir, ".open-next"),
14-
skipNextBuild,
15-
skipWranglerConfigCheck,
16-
minify,
17-
populateCache,
18-
});
49+
await runCommand(getArgs());

0 commit comments

Comments
 (0)