Skip to content

Commit a28f8ce

Browse files
committed
add dev command
1 parent c212ed0 commit a28f8ce

File tree

4 files changed

+119
-18
lines changed

4 files changed

+119
-18
lines changed

packages/open-next/src/build.ts

+23
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { spawnSync } from "node:child_process";
2+
import path from "node:path";
13
import url from "node:url";
24

35
import {
@@ -25,6 +27,7 @@ export type PublicFiles = {
2527
export async function build(
2628
openNextConfigPath?: string,
2729
nodeExternals?: string,
30+
dev = false,
2831
) {
2932
showWarningOnWindows();
3033

@@ -35,6 +38,7 @@ export async function build(
3538
baseDir,
3639
openNextConfigPath,
3740
{ nodeExternals },
41+
dev,
3842
);
3943

4044
// Initialize options
@@ -80,4 +84,23 @@ export async function build(
8084
await createWarmerBundle(options);
8185
await generateOutput(options);
8286
logger.info("OpenNext build complete.");
87+
88+
if (dev) {
89+
printHeader("Starting development server");
90+
spawnSync(
91+
"node",
92+
[
93+
path.join(
94+
options.outputDir,
95+
"server-functions",
96+
"default",
97+
"index.mjs",
98+
),
99+
],
100+
{
101+
stdio: "inherit",
102+
shell: process.platform === "win32",
103+
},
104+
);
105+
}
83106
}

packages/open-next/src/build/compileConfig.ts

+60-16
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { buildSync } from "esbuild";
66
import type { OpenNextConfig } from "types/open-next.js";
77

88
import logger from "../logger.js";
9+
import { DEV_CONFIG } from "./constant.js";
910
import { validateConfig } from "./validateConfig.js";
1011

1112
/**
@@ -23,6 +24,7 @@ export async function compileOpenNextConfig(
2324
baseDir: string,
2425
openNextConfigPath?: string,
2526
{ nodeExternals = "", compileEdge = false } = {},
27+
dev = false,
2628
) {
2729
const sourcePath = path.join(
2830
baseDir,
@@ -34,6 +36,7 @@ export async function compileOpenNextConfig(
3436
sourcePath,
3537
buildDir,
3638
nodeExternals.split(","),
39+
dev,
3740
);
3841

3942
// On Windows, we need to use file:// protocol to load the config file using import()
@@ -69,32 +72,32 @@ export function compileOpenNextConfigNode(
6972
sourcePath: string,
7073
outputDir: string,
7174
externals: string[],
75+
dev = false,
7276
) {
7377
const outputPath = path.join(outputDir, "open-next.config.mjs");
7478
logger.debug("Compiling open-next.config.ts for Node.", outputPath);
7579

80+
if (dev) {
81+
buildConfig({
82+
sourcePath,
83+
externals,
84+
outputPath,
85+
dev,
86+
});
87+
return outputPath;
88+
}
89+
7690
//Check if open-next.config.ts exists
7791
if (!fs.existsSync(sourcePath)) {
7892
//Create a simple open-next.config.mjs file
7993
logger.debug("Cannot find open-next.config.ts. Using default config.");
8094
fs.writeFileSync(outputPath, "export default { default: { } };");
8195
} else {
82-
buildSync({
83-
entryPoints: [sourcePath],
84-
outfile: outputPath,
85-
bundle: true,
86-
format: "esm",
87-
target: ["node18"],
88-
external: externals,
89-
platform: "node",
90-
banner: {
91-
js: [
92-
"import { createRequire as topLevelCreateRequire } from 'module';",
93-
"const require = topLevelCreateRequire(import.meta.url);",
94-
"import bannerUrl from 'url';",
95-
"const __dirname = bannerUrl.fileURLToPath(new URL('.', import.meta.url));",
96-
].join(""),
97-
},
96+
buildConfig({
97+
sourcePath,
98+
externals,
99+
outputPath,
100+
dev,
98101
});
99102
}
100103

@@ -120,3 +123,44 @@ export function compileOpenNextConfigEdge(
120123
external: externals,
121124
});
122125
}
126+
127+
function buildConfig({
128+
sourcePath,
129+
outputPath,
130+
externals,
131+
dev,
132+
}: {
133+
sourcePath: string;
134+
outputPath: string;
135+
externals: string[];
136+
dev: boolean;
137+
}) {
138+
buildSync({
139+
...(dev
140+
? {
141+
stdin: {
142+
contents: DEV_CONFIG,
143+
resolveDir: process.cwd(),
144+
loader: "ts",
145+
sourcefile: "open-next.config.ts",
146+
},
147+
}
148+
: {
149+
entryPoints: [sourcePath],
150+
}),
151+
outfile: outputPath,
152+
bundle: true,
153+
format: "esm",
154+
target: ["node18"],
155+
external: externals,
156+
platform: "node",
157+
banner: {
158+
js: [
159+
"import { createRequire as topLevelCreateRequire } from 'module';",
160+
"const require = topLevelCreateRequire(import.meta.url);",
161+
"import bannerUrl from 'url';",
162+
"const __dirname = bannerUrl.fileURLToPath(new URL('.', import.meta.url));",
163+
].join(""),
164+
},
165+
});
166+
}
+26
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,29 @@
11
//TODO: Move all other manifest path here as well
22
export const MIDDLEWARE_TRACE_FILE = "server/middleware.js.nft.json";
33
export const INSTRUMENTATION_TRACE_FILE = "server/instrumentation.js.nft.json";
4+
5+
// This is an OpenNext config to run the default server function locally
6+
// https://opennext.js.org/aws/contribute/local_run
7+
export const DEV_CONFIG = `
8+
export default {
9+
default: {
10+
override: {
11+
wrapper: "express-dev",
12+
converter: "node",
13+
incrementalCache: "fs-dev",
14+
queue: "direct",
15+
tagCache: "fs-dev",
16+
},
17+
},
18+
imageOptimization: {
19+
override: {
20+
wrapper: "dummy",
21+
converter: "dummy",
22+
},
23+
loader: "fs-dev",
24+
install: {
25+
arch: "x64",
26+
packages: ["sharp"],
27+
},
28+
},
29+
}`;

packages/open-next/src/index.ts

+10-2
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,16 @@
33
import { build } from "./build.js";
44

55
const command = process.argv[2];
6-
if (command !== "build") printHelp();
6+
if (command !== "build" && command !== "dev") printHelp();
77

88
const args = parseArgs();
99
if (Object.keys(args).includes("--help")) printHelp();
1010

11-
await build(args["--config-path"], args["--node-externals"]);
11+
if (command === "build") {
12+
await build(args["--config-path"], args["--node-externals"]);
13+
} else if (command === "dev") {
14+
await build(undefined, args["--node-externals"], true);
15+
}
1216

1317
function parseArgs() {
1418
return process.argv.slice(2).reduce(
@@ -43,6 +47,10 @@ function printHelp() {
4347
);
4448
console.log(" npx open-next build --node-externals aws-sdk,sharp,sqlite3");
4549
console.log("");
50+
console.log(
51+
"This is to start OpenNext locally for testing/debugging purposes",
52+
);
53+
console.log(" npx open-next dev");
4654

4755
process.exit(1);
4856
}

0 commit comments

Comments
 (0)