Skip to content

Commit 450efc7

Browse files
authored
refactor: project options type shared with build + config init (#88)
1 parent f7b3a10 commit 450efc7

File tree

6 files changed

+50
-42
lines changed

6 files changed

+50
-42
lines changed

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,16 +32,16 @@ export async function buildWorker(config: Config): Promise<void> {
3232
// Copy over client-side generated files
3333
await cp(
3434
path.join(config.paths.dotNext, "static"),
35-
path.join(config.paths.builderOutput, "assets", "_next", "static"),
35+
path.join(config.paths.outputDir, "assets", "_next", "static"),
3636
{
3737
recursive: true,
3838
}
3939
);
4040

4141
// Copy over any static files (e.g. images) from the source project
42-
const publicDir = path.join(config.paths.nextApp, "public");
42+
const publicDir = path.join(config.paths.sourceDir, "public");
4343
if (existsSync(publicDir)) {
44-
await cp(publicDir, path.join(config.paths.builderOutput, "assets"), {
44+
await cp(publicDir, path.join(config.paths.outputDir, "assets"), {
4545
recursive: true,
4646
});
4747
}
@@ -52,7 +52,7 @@ export async function buildWorker(config: Config): Promise<void> {
5252
copyPackageCliFiles(packageDistDir, config);
5353

5454
const workerEntrypoint = path.join(config.paths.internalTemplates, "worker.ts");
55-
const workerOutputFile = path.join(config.paths.builderOutput, "index.mjs");
55+
const workerOutputFile = path.join(config.paths.outputDir, "index.mjs");
5656

5757
const nextConfigStr =
5858
readFileSync(path.join(config.paths.standaloneApp, "/server.js"), "utf8")?.match(
Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,39 @@
11
import { containsDotNextDir, getConfig } from "../config";
2+
import type { ProjectOptions } from "../config";
23
import { buildNextjsApp } from "./build-next-app";
34
import { buildWorker } from "./build-worker";
45
import { cpSync } from "node:fs";
5-
import path from "node:path";
6+
import { join } from "node:path";
67
import { rm } from "node:fs/promises";
78

89
/**
910
* Builds the application in a format that can be passed to workerd
1011
*
1112
* It saves the output in a `.worker-next` directory
1213
*
13-
* @param appDir the directory of the Next.js app to build
14-
* @param opts.outputDir the directory where to save the output (defaults to the app's directory)
15-
* @param opts.skipBuild boolean indicating whether the Next.js build should be skipped (i.e. if the `.next` dir is already built)
14+
* @param projectOpts The options for the project
1615
*/
17-
export async function build(appDir: string, opts: BuildOptions): Promise<void> {
18-
if (!opts.skipBuild) {
16+
export async function build(projectOpts: ProjectOptions): Promise<void> {
17+
if (!projectOpts.skipBuild) {
1918
// Build the next app
20-
await buildNextjsApp(appDir);
19+
await buildNextjsApp(projectOpts.sourceDir);
2120
}
2221

23-
if (!containsDotNextDir(appDir)) {
24-
throw new Error(`.next folder not found in ${appDir}`);
22+
if (!containsDotNextDir(projectOpts.sourceDir)) {
23+
throw new Error(`.next folder not found in ${projectOpts.sourceDir}`);
2524
}
2625

27-
// Create a clean output directory
28-
const outputDir = path.resolve(opts.outputDir ?? appDir, ".worker-next");
29-
await cleanDirectory(outputDir);
26+
// Clean the output directory
27+
await cleanDirectory(projectOpts.outputDir);
3028

3129
// Copy the .next directory to the output directory so it can be mutated.
32-
cpSync(path.join(appDir, ".next"), path.join(outputDir, ".next"), { recursive: true });
30+
cpSync(join(projectOpts.sourceDir, ".next"), join(projectOpts.outputDir, ".next"), { recursive: true });
3331

34-
const config = getConfig(appDir, outputDir);
32+
const config = getConfig(projectOpts);
3533

3634
await buildWorker(config);
3735
}
3836

39-
type BuildOptions = {
40-
skipBuild: boolean;
41-
outputDir?: string;
42-
};
43-
4437
async function cleanDirectory(path: string): Promise<void> {
4538
return await rm(path, { recursive: true, force: true });
4639
}

packages/cloudflare/src/cli/build/patches/investigated/patch-cache.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ export async function patchCache(code: string, config: Config): Promise<string>
1818

1919
const cacheHandlerFileName = "cache-handler.mjs";
2020
const cacheHandlerEntrypoint = join(config.paths.internalTemplates, "cache-handler", "index.ts");
21-
const cacheHandlerOutputFile = join(config.paths.builderOutput, cacheHandlerFileName);
21+
const cacheHandlerOutputFile = join(config.paths.outputDir, cacheHandlerFileName);
2222

2323
await build({
2424
entryPoints: [cacheHandlerEntrypoint],

packages/cloudflare/src/cli/build/utils/copy-prerendered-routes.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export function copyPrerenderedRoutes(config: Config) {
1919

2020
const serverAppDirPath = join(config.paths.standaloneAppServer, "app");
2121
const prerenderManifestPath = join(config.paths.standaloneAppDotNext, "prerender-manifest.json");
22-
const outputPath = join(config.paths.builderOutput, "assets", SEED_DATA_DIR);
22+
const outputPath = join(config.paths.outputDir, "assets", SEED_DATA_DIR);
2323

2424
const prerenderManifest: PrerenderManifest = existsSync(prerenderManifestPath)
2525
? JSON.parse(readFileSync(prerenderManifestPath, "utf8"))
@@ -38,7 +38,7 @@ export function copyPrerenderedRoutes(config: Config) {
3838

3939
if (fullPath.endsWith(NEXT_META_SUFFIX)) {
4040
const data = JSON.parse(readFileSync(fullPath, "utf8"));
41-
writeFileSync(destPath, JSON.stringify({ ...data, lastModified: config.buildTimestamp }));
41+
writeFileSync(destPath, JSON.stringify({ ...data, lastModified: config.build.timestamp }));
4242
} else {
4343
copyFileSync(fullPath, destPath);
4444
}

packages/cloudflare/src/cli/config.ts

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,18 @@ import { readdirSync, statSync } from "node:fs";
44
const PACKAGE_NAME = "@opennextjs/cloudflare";
55

66
export type Config = {
7-
// Timestamp for when the build was started
8-
buildTimestamp: number;
7+
build: {
8+
// Timestamp for when the build was started
9+
timestamp: number;
10+
// Whether to skip building the Next.js app or not
11+
skipNextBuild: boolean;
12+
};
913

1014
paths: {
1115
// Path to the next application
12-
nextApp: string;
16+
sourceDir: string;
1317
// Path to the output folder
14-
builderOutput: string;
18+
outputDir: string;
1519
// Path to the app's `.next` directory (where `next build` saves the build output)
1620
dotNext: string;
1721
// Path to the application standalone root directory
@@ -39,13 +43,11 @@ export type Config = {
3943
/**
4044
* Computes the configuration.
4145
*
42-
* @param appDir Next app root folder
43-
* @param outputDir Output of the cloudflare builder
44-
*
45-
* @returns the configuration, see `Config`
46+
* @param projectOpts The options for the project
47+
* @returns The configuration, see `Config`
4648
*/
47-
export function getConfig(appDir: string, outputDir: string): Config {
48-
const dotNext = path.join(outputDir, ".next");
49+
export function getConfig(projectOpts: ProjectOptions): Config {
50+
const dotNext = path.join(projectOpts.outputDir, ".next");
4951
const appPath = getNextjsApplicationPath(dotNext).replace(/\/$/, "");
5052
const standaloneRoot = path.join(dotNext, "standalone");
5153
const standaloneApp = path.join(standaloneRoot, appPath);
@@ -59,11 +61,14 @@ export function getConfig(appDir: string, outputDir: string): Config {
5961
process.env.__OPENNEXT_KV_BINDING_NAME ??= "NEXT_CACHE_WORKERS_KV";
6062

6163
return {
62-
buildTimestamp: Date.now(),
64+
build: {
65+
timestamp: Date.now(),
66+
skipNextBuild: !!projectOpts.skipBuild,
67+
},
6368

6469
paths: {
65-
nextApp: appDir,
66-
builderOutput: outputDir,
70+
sourceDir: projectOpts.sourceDir,
71+
outputDir: projectOpts.outputDir,
6772
dotNext,
6873
standaloneRoot,
6974
standaloneApp,
@@ -89,6 +94,15 @@ export function containsDotNextDir(folder: string): boolean {
8994
}
9095
}
9196

97+
export type ProjectOptions = {
98+
// Next app root folder
99+
sourceDir: string;
100+
// The directory to save the output to (defaults to the app's directory)
101+
outputDir: string;
102+
// Whether the Next.js build should be skipped (i.e. if the `.next` dir is already built)
103+
skipBuild?: boolean;
104+
};
105+
92106
/**
93107
* It basically tries to find the path that the application is under inside the `.next/standalone` directory, using the `.next/server` directory
94108
* presence as the condition that needs to be met.

packages/cloudflare/src/cli/index.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ if (!["js", "cjs", "mjs", "ts"].some((ext) => existsSync(`./next.config.${ext}`)
1818

1919
const { skipBuild, outputDir } = getArgs();
2020

21-
await build(nextAppDir, {
22-
outputDir,
23-
skipBuild: !!skipBuild,
21+
await build({
22+
sourceDir: nextAppDir,
23+
outputDir: resolve(outputDir ?? nextAppDir, ".worker-next"),
24+
skipBuild,
2425
});

0 commit comments

Comments
 (0)