Skip to content

Commit fb9ccd0

Browse files
committed
add local commands
1 parent c2da3a8 commit fb9ccd0

File tree

3 files changed

+133
-10
lines changed

3 files changed

+133
-10
lines changed

.changeset/seven-dodos-draw.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@opennextjs/aws": patch
3+
---
4+
5+
feature: add cli commands to build and run OpenNext locally with dev overrides
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,35 @@
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+
export const LOCAL_CONFIG_PATH = "./open-next.config.local.ts";
6+
/**
7+
* https://opennext.js.org/aws/contribute/local_run
8+
* This is an OpenNext config to run the default server function locally
9+
* Be aware that this will not work the same way as in production.
10+
* Its mostly used for debugging and development purposes.
11+
*/
12+
export const LOCAL_CONFIG = `export default {
13+
default: {
14+
override: {
15+
wrapper: "express-dev",
16+
converter: "node",
17+
incrementalCache: "fs-dev",
18+
queue: "direct",
19+
tagCache: "fs-dev",
20+
},
21+
},
22+
imageOptimization: {
23+
override: {
24+
wrapper: "dummy",
25+
converter: "dummy",
26+
},
27+
loader: "fs-dev",
28+
// This part is not needed on ARM Linux as it will be installed by default
29+
// Remember to change this depending on your arch and system
30+
install: {
31+
arch: "x64",
32+
packages: ["sharp"],
33+
},
34+
},
35+
}`;

packages/open-next/src/index.ts

Lines changed: 96 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,34 @@
11
#!/usr/bin/env node
2+
import { spawnSync } from "node:child_process";
3+
import { existsSync, writeFileSync } from "node:fs";
4+
import path from "node:path";
25

36
import { build } from "./build.js";
7+
import { LOCAL_CONFIG, LOCAL_CONFIG_PATH } from "./build/constant.js";
8+
import { printHeader } from "./build/utils.js";
49

510
const command = process.argv[2];
6-
if (command !== "build") printHelp();
11+
const stage = process.argv[3];
12+
const validCommand =
13+
command === "build" ||
14+
command === "preview" ||
15+
(command === "generate" && stage === "local");
16+
17+
if (!validCommand) {
18+
printHelp();
19+
}
720

821
const args = parseArgs();
922
if (Object.keys(args).includes("--help")) printHelp();
1023

11-
await build(args["--config-path"], args["--node-externals"]);
12-
24+
if (command === "build") {
25+
await build(args["--config-path"], args["--node-externals"]);
26+
} else if (command === "generate" && stage === "local") {
27+
generateLocalConfig();
28+
} else if (command === "preview") {
29+
await buildLocalConfig();
30+
runLocally();
31+
}
1332
function parseArgs() {
1433
return process.argv.slice(2).reduce(
1534
(acc, key, ind, self) => {
@@ -29,20 +48,87 @@ function parseArgs() {
2948
);
3049
}
3150

51+
async function buildLocalConfig() {
52+
if (!existsSync(LOCAL_CONFIG_PATH)) {
53+
console.error(
54+
"open-next.config.local.ts does not exist. You can run `generate local` first to generate it.",
55+
);
56+
process.exit(1);
57+
}
58+
59+
// Build OpenNext with dev overrides
60+
printHeader("Building OpenNext with open-next.config.local.ts");
61+
await build(LOCAL_CONFIG_PATH, args["--node-externals"]);
62+
}
63+
64+
function runLocally() {
65+
const handlerPath = path.join(
66+
".open-next",
67+
"server-functions",
68+
"default",
69+
"index.mjs",
70+
);
71+
if (!existsSync(handlerPath)) {
72+
console.error(
73+
"OpenNext server function not found. Please build it before running this command.",
74+
);
75+
process.exit(1);
76+
}
77+
printHeader("Running OpenNext locally");
78+
spawnSync("node", [handlerPath], {
79+
stdio: "inherit",
80+
shell: true,
81+
});
82+
}
83+
84+
function generateLocalConfig() {
85+
if (existsSync(LOCAL_CONFIG_PATH)) {
86+
console.error(
87+
"open-next.config.local.ts already exists. Please remove it before running this command.",
88+
);
89+
process.exit(1);
90+
}
91+
92+
try {
93+
writeFileSync(LOCAL_CONFIG_PATH, LOCAL_CONFIG);
94+
} catch (e) {
95+
console.error("Error writing open-next.config.local.ts", e);
96+
}
97+
}
98+
3299
function printHelp() {
33-
console.log("Unknown command");
34-
console.log("");
100+
console.log("╔══════════════════════════════════════════╗");
101+
console.log("║ Unknown Command ║");
102+
console.log("╚══════════════════════════════════════════╝\n");
103+
35104
console.log("Usage:");
36105
console.log(" npx open-next build");
37-
console.log("You can use a custom config path here");
106+
console.log(" Build the project with OpenNext.\n");
107+
108+
console.log("Options:");
109+
console.log(" --config-path <path>");
110+
console.log(" Use a custom config path.");
38111
console.log(
39-
" npx open-next build --config-path ./path/to/open-next.config.ts",
112+
" Usage: npx open-next build --config-path ./path/to/open-next.config.ts\n",
40113
);
114+
115+
console.log(" --node-externals <modules>");
116+
console.log(" Configure externals for the esbuild compilation of the");
117+
console.log(" open-next.config.ts file.");
118+
console.log(
119+
" Usage: npx open-next build --node-externals aws-sdk,sharp,sqlite3\n",
120+
);
121+
122+
console.log("Other commands:");
123+
console.log(" preview");
124+
console.log(
125+
" Build and run OpenNext locally with open-next.config.local.ts",
126+
);
127+
128+
console.log(" generate local");
41129
console.log(
42-
"You can configure externals for the esbuild compilation of the open-next.config.ts file",
130+
" Generate a config file with dev overrides for OpenNext in open-next.config.local.ts",
43131
);
44-
console.log(" npx open-next build --node-externals aws-sdk,sharp,sqlite3");
45-
console.log("");
46132

47133
process.exit(1);
48134
}

0 commit comments

Comments
 (0)