next-bun-compile 0.4.2 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +12 -286
- package/dist/{generate.js → index-81394x5f.js} +129 -33
- package/dist/index.js +7 -280
- package/package.json +2 -2
- package/dist/compile.js +0 -34
package/dist/cli.js
CHANGED
|
@@ -1,297 +1,23 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { createRequire } from "node:module";
|
|
3
|
-
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
4
|
-
|
|
5
|
-
// src/generate.ts
|
|
6
2
|
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
readdirSync,
|
|
11
|
-
statSync,
|
|
12
|
-
mkdirSync
|
|
13
|
-
} from "node:fs";
|
|
14
|
-
import { join, relative } from "node:path";
|
|
15
|
-
import { createHash } from "node:crypto";
|
|
16
|
-
function walkDir(dir, base = dir) {
|
|
17
|
-
const results = [];
|
|
18
|
-
if (!existsSync(dir))
|
|
19
|
-
return results;
|
|
20
|
-
for (const entry of readdirSync(dir)) {
|
|
21
|
-
const full = join(dir, entry);
|
|
22
|
-
if (statSync(full).isDirectory()) {
|
|
23
|
-
results.push(...walkDir(full, base));
|
|
24
|
-
} else {
|
|
25
|
-
results.push({ absolutePath: full, relativePath: relative(base, full) });
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
return results;
|
|
29
|
-
}
|
|
30
|
-
function toVarName(filePath) {
|
|
31
|
-
const hash = createHash("md5").update(filePath).digest("hex").slice(0, 6);
|
|
32
|
-
const safe = filePath.replace(/[^a-zA-Z0-9]/g, "_").slice(0, 40);
|
|
33
|
-
return `asset_${safe}_${hash}`;
|
|
34
|
-
}
|
|
35
|
-
function generateStubs(standaloneDir) {
|
|
36
|
-
const stubs = [
|
|
37
|
-
{
|
|
38
|
-
path: "node_modules/next/dist/server/dev/next-dev-server.js",
|
|
39
|
-
content: "module.exports = { default: null };"
|
|
40
|
-
},
|
|
41
|
-
{
|
|
42
|
-
path: "node_modules/next/dist/server/lib/router-utils/setup-dev-bundler.js",
|
|
43
|
-
content: "module.exports = {};"
|
|
44
|
-
},
|
|
45
|
-
{
|
|
46
|
-
path: "node_modules/@opentelemetry/api/index.js",
|
|
47
|
-
content: "throw new Error('not installed');"
|
|
48
|
-
},
|
|
49
|
-
{
|
|
50
|
-
path: "node_modules/critters/index.js",
|
|
51
|
-
content: "module.exports = {};"
|
|
52
|
-
}
|
|
53
|
-
];
|
|
54
|
-
let count = 0;
|
|
55
|
-
for (const stub of stubs) {
|
|
56
|
-
const fullPath = join(standaloneDir, stub.path);
|
|
57
|
-
if (!existsSync(fullPath)) {
|
|
58
|
-
const dir = join(fullPath, "..");
|
|
59
|
-
if (!existsSync(dir)) {
|
|
60
|
-
mkdirSync(dir, { recursive: true });
|
|
61
|
-
}
|
|
62
|
-
writeFileSync(fullPath, stub.content);
|
|
63
|
-
count++;
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
if (count > 0) {
|
|
67
|
-
console.log(`next-bun-compile: Created ${count} module stubs`);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
function patchRequireHook(standaloneDir) {
|
|
71
|
-
const hookPath = join(standaloneDir, "node_modules/next/dist/server/require-hook.js");
|
|
72
|
-
if (!existsSync(hookPath))
|
|
73
|
-
return;
|
|
74
|
-
let content = readFileSync(hookPath, "utf-8");
|
|
75
|
-
const target = "let resolve = process.env.NEXT_MINIMAL ? __non_webpack_require__.resolve : require.resolve;";
|
|
76
|
-
if (!content.includes(target))
|
|
77
|
-
return;
|
|
78
|
-
content = content.replace(target, `let _resolve = process.env.NEXT_MINIMAL ? __non_webpack_require__.resolve : require.resolve;
|
|
79
|
-
let resolve = (id) => { try { return _resolve(id); } catch { return ''; } };`);
|
|
80
|
-
writeFileSync(hookPath, content);
|
|
81
|
-
console.log("next-bun-compile: Patched require-hook.js for compiled binary compatibility");
|
|
82
|
-
}
|
|
83
|
-
function collectExternalModules(standaloneDir) {
|
|
84
|
-
const chunksDir = join(standaloneDir, ".next/server/chunks");
|
|
85
|
-
if (!existsSync(chunksDir))
|
|
86
|
-
return [];
|
|
87
|
-
const seeds = new Set;
|
|
88
|
-
for (const { absolutePath } of walkDir(chunksDir)) {
|
|
89
|
-
if (!absolutePath.endsWith(".js"))
|
|
90
|
-
continue;
|
|
91
|
-
const content = readFileSync(absolutePath, "utf-8");
|
|
92
|
-
for (const match of content.matchAll(/require\("(next\/dist\/[^"]+)"\)/g)) {
|
|
93
|
-
seeds.add(match[1]);
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
const deps = new Set;
|
|
97
|
-
function trace(file) {
|
|
98
|
-
if (deps.has(file))
|
|
99
|
-
return;
|
|
100
|
-
let fullPath = join(standaloneDir, "node_modules", file);
|
|
101
|
-
if (existsSync(fullPath) && statSync(fullPath).isDirectory()) {
|
|
102
|
-
const pkgJson = join(fullPath, "package.json");
|
|
103
|
-
if (existsSync(pkgJson)) {
|
|
104
|
-
deps.add(file + "/package.json");
|
|
105
|
-
}
|
|
106
|
-
file = file + "/index.js";
|
|
107
|
-
fullPath = join(standaloneDir, "node_modules", file);
|
|
108
|
-
}
|
|
109
|
-
if (!existsSync(fullPath))
|
|
110
|
-
return;
|
|
111
|
-
deps.add(file);
|
|
112
|
-
const content = readFileSync(fullPath, "utf-8");
|
|
113
|
-
for (const match of content.matchAll(/require\("([^"]+)"\)/g)) {
|
|
114
|
-
const req = match[1];
|
|
115
|
-
let resolved;
|
|
116
|
-
if (req.startsWith(".")) {
|
|
117
|
-
resolved = join(file, "..", req).replace(/\\/g, "/");
|
|
118
|
-
if (!resolved.endsWith(".js"))
|
|
119
|
-
resolved += ".js";
|
|
120
|
-
} else if (req.startsWith("next/")) {
|
|
121
|
-
resolved = req;
|
|
122
|
-
if (!resolved.endsWith(".js"))
|
|
123
|
-
resolved += ".js";
|
|
124
|
-
}
|
|
125
|
-
if (resolved)
|
|
126
|
-
trace(resolved);
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
for (const seed of seeds)
|
|
130
|
-
trace(seed);
|
|
131
|
-
return [...deps];
|
|
132
|
-
}
|
|
133
|
-
function generateEntryPoint(options) {
|
|
134
|
-
const { standaloneDir, distDir, projectDir } = options;
|
|
135
|
-
generateStubs(standaloneDir);
|
|
136
|
-
patchRequireHook(standaloneDir);
|
|
137
|
-
const staticDir = join(distDir, "static");
|
|
138
|
-
const staticFiles = walkDir(staticDir).map((f) => ({
|
|
139
|
-
...f,
|
|
140
|
-
urlPath: `/_next/static/${f.relativePath.replace(/\\/g, "/")}`
|
|
141
|
-
}));
|
|
142
|
-
const publicDir = join(projectDir, "public");
|
|
143
|
-
const publicFiles = walkDir(publicDir).map((f) => ({
|
|
144
|
-
...f,
|
|
145
|
-
urlPath: `/${f.relativePath.replace(/\\/g, "/")}`
|
|
146
|
-
}));
|
|
147
|
-
const standaloneNextDir = join(standaloneDir, ".next");
|
|
148
|
-
const runtimeFiles = walkDir(standaloneNextDir).map((f) => ({
|
|
149
|
-
...f,
|
|
150
|
-
urlPath: `__runtime/.next/${f.relativePath.replace(/\\/g, "/")}`
|
|
151
|
-
}));
|
|
152
|
-
const externalModules = collectExternalModules(standaloneDir);
|
|
153
|
-
const externalPaths = ["next/package.json", ...externalModules];
|
|
154
|
-
const externalDir = join(standaloneDir, ".next/__external");
|
|
155
|
-
for (const mod of externalPaths) {
|
|
156
|
-
const src = join(standaloneDir, "node_modules", mod);
|
|
157
|
-
if (!existsSync(src))
|
|
158
|
-
continue;
|
|
159
|
-
const dest = join(externalDir, mod);
|
|
160
|
-
mkdirSync(join(dest, ".."), { recursive: true });
|
|
161
|
-
writeFileSync(dest, readFileSync(src));
|
|
162
|
-
runtimeFiles.push({
|
|
163
|
-
absolutePath: dest,
|
|
164
|
-
relativePath: `__external/${mod}`,
|
|
165
|
-
urlPath: `__runtime/.next/node_modules/${mod.replace(/\\/g, "/")}`
|
|
166
|
-
});
|
|
167
|
-
}
|
|
168
|
-
if (externalModules.length > 0) {
|
|
169
|
-
console.log(`next-bun-compile: Embedding ${externalModules.length} external modules for SSR`);
|
|
170
|
-
}
|
|
171
|
-
const ctx = JSON.parse(readFileSync(join(distDir, "bun-compile-ctx.json"), "utf-8"));
|
|
172
|
-
const { assetPrefix } = ctx;
|
|
173
|
-
const assetsToEmbed = assetPrefix ? [...publicFiles, ...runtimeFiles] : [...staticFiles, ...publicFiles, ...runtimeFiles];
|
|
174
|
-
if (assetPrefix) {
|
|
175
|
-
console.log(`next-bun-compile: assetPrefix detected — skipping ${staticFiles.length} static assets (served from CDN)`);
|
|
176
|
-
}
|
|
177
|
-
console.log(`next-bun-compile: Embedding ${assetsToEmbed.length} assets (${staticFiles.length} static + ${publicFiles.length} public + ${runtimeFiles.length} runtime)`);
|
|
178
|
-
const imports = [];
|
|
179
|
-
const mapEntries = [];
|
|
180
|
-
for (const asset of assetsToEmbed) {
|
|
181
|
-
const varName = toVarName(asset.urlPath);
|
|
182
|
-
const importPath = relative(standaloneDir, asset.absolutePath).replace(/\\/g, "/");
|
|
183
|
-
imports.push(`import ${varName} from "./${importPath}" with { type: "file" };`);
|
|
184
|
-
mapEntries.push(` ["${asset.urlPath}", ${varName}],`);
|
|
185
|
-
}
|
|
186
|
-
writeFileSync(join(standaloneDir, "assets.generated.js"), `${imports.join(`
|
|
187
|
-
`)}
|
|
188
|
-
export const assetMap = new Map([
|
|
189
|
-
${mapEntries.join(`
|
|
190
|
-
`)}
|
|
191
|
-
]);
|
|
192
|
-
`);
|
|
193
|
-
const standaloneServerSrc = readFileSync(join(standaloneDir, "server.js"), "utf-8");
|
|
194
|
-
const configMatch = standaloneServerSrc.match(/const nextConfig = ({[\s\S]*?})\n/);
|
|
195
|
-
if (!configMatch) {
|
|
196
|
-
throw new Error("next-bun-compile: Could not extract nextConfig from standalone server.js");
|
|
197
|
-
}
|
|
198
|
-
const assetExtractions = assetsToEmbed.map((a) => {
|
|
199
|
-
let diskPath;
|
|
200
|
-
if (a.urlPath.startsWith("__runtime/")) {
|
|
201
|
-
diskPath = a.urlPath.slice("__runtime/".length);
|
|
202
|
-
} else if (a.urlPath.startsWith("/_next/static/")) {
|
|
203
|
-
diskPath = ".next/static/" + a.relativePath;
|
|
204
|
-
} else {
|
|
205
|
-
diskPath = "public/" + a.relativePath;
|
|
206
|
-
}
|
|
207
|
-
return [a.urlPath, diskPath];
|
|
208
|
-
});
|
|
209
|
-
const serverEntry = `import { assetMap } from "./assets.generated.js";
|
|
210
|
-
const path = require("path");
|
|
211
|
-
const fs = require("fs");
|
|
212
|
-
|
|
213
|
-
const baseDir = path.dirname(process.execPath);
|
|
214
|
-
process.chdir(baseDir);
|
|
215
|
-
process.env.NODE_ENV = "production";
|
|
216
|
-
|
|
217
|
-
const nextConfig = ${configMatch[1]};
|
|
218
|
-
process.env.__NEXT_PRIVATE_STANDALONE_CONFIG = JSON.stringify(nextConfig);
|
|
219
|
-
|
|
220
|
-
const currentPort = parseInt(process.env.PORT, 10) || 3000;
|
|
221
|
-
const hostname = process.env.HOSTNAME || "0.0.0.0";
|
|
222
|
-
let keepAliveTimeout = parseInt(process.env.KEEP_ALIVE_TIMEOUT, 10);
|
|
223
|
-
if (Number.isNaN(keepAliveTimeout) || !Number.isFinite(keepAliveTimeout) || keepAliveTimeout < 0) {
|
|
224
|
-
keepAliveTimeout = undefined;
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
const extractions = ${JSON.stringify(assetExtractions)};
|
|
228
|
-
async function extractAssets() {
|
|
229
|
-
let n = 0;
|
|
230
|
-
for (const [urlPath, diskPath] of extractions) {
|
|
231
|
-
const fullPath = path.join(baseDir, diskPath);
|
|
232
|
-
if (fs.existsSync(fullPath)) continue;
|
|
233
|
-
fs.mkdirSync(path.dirname(fullPath), { recursive: true });
|
|
234
|
-
const embedded = assetMap.get(urlPath);
|
|
235
|
-
if (embedded) { await Bun.write(fullPath, Bun.file(embedded)); n++; }
|
|
236
|
-
}
|
|
237
|
-
if (n > 0) console.log(\`Extracted \${n} assets\`);
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
extractAssets().then(() => {
|
|
241
|
-
require("next");
|
|
242
|
-
const { startServer } = require("next/dist/server/lib/start-server");
|
|
243
|
-
return startServer({
|
|
244
|
-
dir: baseDir, isDev: false, config: nextConfig,
|
|
245
|
-
hostname, port: currentPort, allowRetry: false, keepAliveTimeout,
|
|
246
|
-
});
|
|
247
|
-
}).catch((err) => { console.error(err); process.exit(1); });
|
|
248
|
-
`;
|
|
249
|
-
writeFileSync(join(standaloneDir, "server-entry.js"), serverEntry);
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
// src/compile.ts
|
|
253
|
-
import { execFileSync } from "node:child_process";
|
|
254
|
-
import { join as join2 } from "node:path";
|
|
255
|
-
function compile(options) {
|
|
256
|
-
const { standaloneDir, outfile, extraArgs = [] } = options;
|
|
257
|
-
const entryPoint = join2(standaloneDir, "server-entry.js");
|
|
258
|
-
const args = [
|
|
259
|
-
"build",
|
|
260
|
-
entryPoint,
|
|
261
|
-
"--production",
|
|
262
|
-
"--compile",
|
|
263
|
-
"--minify",
|
|
264
|
-
"--bytecode",
|
|
265
|
-
"--sourcemap",
|
|
266
|
-
"--define",
|
|
267
|
-
"process.env.TURBOPACK=1",
|
|
268
|
-
"--define",
|
|
269
|
-
"process.env.__NEXT_EXPERIMENTAL_REACT=",
|
|
270
|
-
"--define",
|
|
271
|
-
'process.env.NEXT_RUNTIME="nodejs"',
|
|
272
|
-
"--outfile",
|
|
273
|
-
outfile,
|
|
274
|
-
...extraArgs
|
|
275
|
-
];
|
|
276
|
-
console.log(`next-bun-compile: Compiling to ${outfile}...`);
|
|
277
|
-
execFileSync("bun", args, { stdio: "inherit" });
|
|
278
|
-
console.log(`next-bun-compile: Done → ${outfile}`);
|
|
279
|
-
}
|
|
3
|
+
compile,
|
|
4
|
+
generateEntryPoint
|
|
5
|
+
} from "./index-81394x5f.js";
|
|
280
6
|
|
|
281
7
|
// src/cli.ts
|
|
282
|
-
import { existsSync
|
|
283
|
-
import { join
|
|
8
|
+
import { existsSync } from "node:fs";
|
|
9
|
+
import { join, resolve } from "node:path";
|
|
284
10
|
var extraArgs = process.argv.slice(2);
|
|
285
11
|
var projectDir = resolve(".");
|
|
286
|
-
var distDir =
|
|
287
|
-
var standaloneDir =
|
|
288
|
-
if (!
|
|
12
|
+
var distDir = join(projectDir, ".next");
|
|
13
|
+
var standaloneDir = join(distDir, "standalone");
|
|
14
|
+
if (!existsSync(standaloneDir)) {
|
|
289
15
|
console.error('next-bun-compile: No standalone output found. Run "next build" first with output: "standalone" in next.config.ts.');
|
|
290
16
|
process.exit(1);
|
|
291
17
|
}
|
|
292
|
-
var ctxPath =
|
|
293
|
-
if (
|
|
18
|
+
var ctxPath = join(distDir, "bun-compile-ctx.json");
|
|
19
|
+
if (existsSync(ctxPath)) {
|
|
294
20
|
console.log("next-bun-compile: Using build context from adapter");
|
|
295
21
|
}
|
|
296
|
-
generateEntryPoint({ standaloneDir, distDir, projectDir });
|
|
297
|
-
compile({
|
|
22
|
+
var serverDir = generateEntryPoint({ standaloneDir, distDir, projectDir });
|
|
23
|
+
compile({ serverDir, outfile: join(projectDir, "server"), extraArgs });
|
|
@@ -31,56 +31,122 @@ function toVarName(filePath) {
|
|
|
31
31
|
const safe = filePath.replace(/[^a-zA-Z0-9]/g, "_").slice(0, 40);
|
|
32
32
|
return `asset_${safe}_${hash}`;
|
|
33
33
|
}
|
|
34
|
+
function findPackageDirs(nodeModulesDir, pkg) {
|
|
35
|
+
const dirs = [];
|
|
36
|
+
const direct = join(nodeModulesDir, pkg);
|
|
37
|
+
if (existsSync(direct))
|
|
38
|
+
dirs.push(direct);
|
|
39
|
+
const bunDir = join(nodeModulesDir, ".bun");
|
|
40
|
+
if (existsSync(bunDir)) {
|
|
41
|
+
const scope = pkg.startsWith("@") ? pkg.split("/")[0] + "+" + pkg.split("/")[1] : pkg;
|
|
42
|
+
for (const entry of readdirSync(bunDir)) {
|
|
43
|
+
if (!entry.startsWith(scope + "@"))
|
|
44
|
+
continue;
|
|
45
|
+
const hoisted = join(bunDir, entry, "node_modules", pkg);
|
|
46
|
+
if (existsSync(hoisted))
|
|
47
|
+
dirs.push(hoisted);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return dirs;
|
|
51
|
+
}
|
|
34
52
|
function generateStubs(standaloneDir) {
|
|
35
53
|
const stubs = [
|
|
36
54
|
{
|
|
37
|
-
|
|
55
|
+
pkg: "next",
|
|
56
|
+
subpath: "dist/server/dev/next-dev-server.js",
|
|
38
57
|
content: "module.exports = { default: null };"
|
|
39
58
|
},
|
|
40
59
|
{
|
|
41
|
-
|
|
60
|
+
pkg: "next",
|
|
61
|
+
subpath: "dist/server/lib/router-utils/setup-dev-bundler.js",
|
|
42
62
|
content: "module.exports = {};"
|
|
43
63
|
},
|
|
44
64
|
{
|
|
45
|
-
|
|
65
|
+
pkg: "@opentelemetry/api",
|
|
66
|
+
subpath: "index.js",
|
|
46
67
|
content: "throw new Error('not installed');"
|
|
47
68
|
},
|
|
48
69
|
{
|
|
49
|
-
|
|
70
|
+
pkg: "critters",
|
|
71
|
+
subpath: "index.js",
|
|
50
72
|
content: "module.exports = {};"
|
|
51
73
|
}
|
|
52
74
|
];
|
|
75
|
+
const nodeModulesDir = join(standaloneDir, "node_modules");
|
|
53
76
|
let count = 0;
|
|
54
77
|
for (const stub of stubs) {
|
|
55
|
-
const
|
|
56
|
-
if (
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
78
|
+
const pkgDirs = findPackageDirs(nodeModulesDir, stub.pkg);
|
|
79
|
+
if (pkgDirs.length === 0)
|
|
80
|
+
pkgDirs.push(join(nodeModulesDir, stub.pkg));
|
|
81
|
+
for (const pkgDir of pkgDirs) {
|
|
82
|
+
const fullPath = join(pkgDir, stub.subpath);
|
|
83
|
+
if (!existsSync(fullPath)) {
|
|
84
|
+
const dir = join(fullPath, "..");
|
|
85
|
+
if (!existsSync(dir)) {
|
|
86
|
+
mkdirSync(dir, { recursive: true });
|
|
87
|
+
}
|
|
88
|
+
writeFileSync(fullPath, stub.content);
|
|
89
|
+
count++;
|
|
60
90
|
}
|
|
61
|
-
writeFileSync(fullPath, stub.content);
|
|
62
|
-
count++;
|
|
63
91
|
}
|
|
64
92
|
}
|
|
65
93
|
if (count > 0) {
|
|
66
94
|
console.log(`next-bun-compile: Created ${count} module stubs`);
|
|
67
95
|
}
|
|
68
96
|
}
|
|
97
|
+
function findServerDir(standaloneDir) {
|
|
98
|
+
if (existsSync(join(standaloneDir, "server.js"))) {
|
|
99
|
+
return standaloneDir;
|
|
100
|
+
}
|
|
101
|
+
function search(dir) {
|
|
102
|
+
if (!existsSync(dir))
|
|
103
|
+
return null;
|
|
104
|
+
for (const entry of readdirSync(dir)) {
|
|
105
|
+
if (entry === "node_modules")
|
|
106
|
+
continue;
|
|
107
|
+
const full = join(dir, entry);
|
|
108
|
+
if (!statSync(full).isDirectory())
|
|
109
|
+
continue;
|
|
110
|
+
if (existsSync(join(full, "server.js")))
|
|
111
|
+
return full;
|
|
112
|
+
const found2 = search(full);
|
|
113
|
+
if (found2)
|
|
114
|
+
return found2;
|
|
115
|
+
}
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
const found = search(standaloneDir);
|
|
119
|
+
if (!found) {
|
|
120
|
+
throw new Error("next-bun-compile: Could not find server.js in standalone output");
|
|
121
|
+
}
|
|
122
|
+
const rel = relative(standaloneDir, found);
|
|
123
|
+
console.log(`next-bun-compile: Monorepo layout detected — server.js found at ${rel}/`);
|
|
124
|
+
return found;
|
|
125
|
+
}
|
|
69
126
|
function patchRequireHook(standaloneDir) {
|
|
70
|
-
const
|
|
71
|
-
|
|
72
|
-
return;
|
|
73
|
-
let content = readFileSync(hookPath, "utf-8");
|
|
127
|
+
const nodeModulesDir = join(standaloneDir, "node_modules");
|
|
128
|
+
const nextDirs = findPackageDirs(nodeModulesDir, "next");
|
|
74
129
|
const target = "let resolve = process.env.NEXT_MINIMAL ? __non_webpack_require__.resolve : require.resolve;";
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
130
|
+
const replacement = `let _resolve = process.env.NEXT_MINIMAL ? __non_webpack_require__.resolve : require.resolve;
|
|
131
|
+
let resolve = (id) => { try { return _resolve(id); } catch { return ''; } };`;
|
|
132
|
+
let patched = 0;
|
|
133
|
+
for (const nextDir of nextDirs) {
|
|
134
|
+
const hookPath = join(nextDir, "dist/server/require-hook.js");
|
|
135
|
+
if (!existsSync(hookPath))
|
|
136
|
+
continue;
|
|
137
|
+
let content = readFileSync(hookPath, "utf-8");
|
|
138
|
+
if (!content.includes(target))
|
|
139
|
+
continue;
|
|
140
|
+
content = content.replace(target, replacement);
|
|
141
|
+
writeFileSync(hookPath, content);
|
|
142
|
+
patched++;
|
|
143
|
+
}
|
|
144
|
+
if (patched > 0) {
|
|
145
|
+
console.log("next-bun-compile: Patched require-hook.js for compiled binary compatibility");
|
|
146
|
+
}
|
|
81
147
|
}
|
|
82
|
-
function collectExternalModules(standaloneDir) {
|
|
83
|
-
const chunksDir = join(
|
|
148
|
+
function collectExternalModules(standaloneDir, serverDir) {
|
|
149
|
+
const chunksDir = join(serverDir, ".next/server/chunks");
|
|
84
150
|
if (!existsSync(chunksDir))
|
|
85
151
|
return [];
|
|
86
152
|
const seeds = new Set;
|
|
@@ -131,6 +197,7 @@ function collectExternalModules(standaloneDir) {
|
|
|
131
197
|
}
|
|
132
198
|
function generateEntryPoint(options) {
|
|
133
199
|
const { standaloneDir, distDir, projectDir } = options;
|
|
200
|
+
const serverDir = findServerDir(standaloneDir);
|
|
134
201
|
generateStubs(standaloneDir);
|
|
135
202
|
patchRequireHook(standaloneDir);
|
|
136
203
|
const staticDir = join(distDir, "static");
|
|
@@ -143,14 +210,14 @@ function generateEntryPoint(options) {
|
|
|
143
210
|
...f,
|
|
144
211
|
urlPath: `/${f.relativePath.replace(/\\/g, "/")}`
|
|
145
212
|
}));
|
|
146
|
-
const standaloneNextDir = join(
|
|
213
|
+
const standaloneNextDir = join(serverDir, ".next");
|
|
147
214
|
const runtimeFiles = walkDir(standaloneNextDir).map((f) => ({
|
|
148
215
|
...f,
|
|
149
216
|
urlPath: `__runtime/.next/${f.relativePath.replace(/\\/g, "/")}`
|
|
150
217
|
}));
|
|
151
|
-
const externalModules = collectExternalModules(standaloneDir);
|
|
218
|
+
const externalModules = collectExternalModules(standaloneDir, serverDir);
|
|
152
219
|
const externalPaths = ["next/package.json", ...externalModules];
|
|
153
|
-
const externalDir = join(
|
|
220
|
+
const externalDir = join(serverDir, ".next/__external");
|
|
154
221
|
for (const mod of externalPaths) {
|
|
155
222
|
const src = join(standaloneDir, "node_modules", mod);
|
|
156
223
|
if (!existsSync(src))
|
|
@@ -178,18 +245,18 @@ function generateEntryPoint(options) {
|
|
|
178
245
|
const mapEntries = [];
|
|
179
246
|
for (const asset of assetsToEmbed) {
|
|
180
247
|
const varName = toVarName(asset.urlPath);
|
|
181
|
-
const importPath = relative(
|
|
248
|
+
const importPath = relative(serverDir, asset.absolutePath).replace(/\\/g, "/");
|
|
182
249
|
imports.push(`import ${varName} from "./${importPath}" with { type: "file" };`);
|
|
183
250
|
mapEntries.push(` ["${asset.urlPath}", ${varName}],`);
|
|
184
251
|
}
|
|
185
|
-
writeFileSync(join(
|
|
252
|
+
writeFileSync(join(serverDir, "assets.generated.js"), `${imports.join(`
|
|
186
253
|
`)}
|
|
187
254
|
export const assetMap = new Map([
|
|
188
255
|
${mapEntries.join(`
|
|
189
256
|
`)}
|
|
190
257
|
]);
|
|
191
258
|
`);
|
|
192
|
-
const standaloneServerSrc = readFileSync(join(
|
|
259
|
+
const standaloneServerSrc = readFileSync(join(serverDir, "server.js"), "utf-8");
|
|
193
260
|
const configMatch = standaloneServerSrc.match(/const nextConfig = ({[\s\S]*?})\n/);
|
|
194
261
|
if (!configMatch) {
|
|
195
262
|
throw new Error("next-bun-compile: Could not extract nextConfig from standalone server.js");
|
|
@@ -245,8 +312,37 @@ extractAssets().then(() => {
|
|
|
245
312
|
});
|
|
246
313
|
}).catch((err) => { console.error(err); process.exit(1); });
|
|
247
314
|
`;
|
|
248
|
-
writeFileSync(join(
|
|
315
|
+
writeFileSync(join(serverDir, "server-entry.js"), serverEntry);
|
|
316
|
+
return serverDir;
|
|
249
317
|
}
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
};
|
|
318
|
+
|
|
319
|
+
// src/compile.ts
|
|
320
|
+
import { execFileSync } from "node:child_process";
|
|
321
|
+
import { join as join2 } from "node:path";
|
|
322
|
+
function compile(options) {
|
|
323
|
+
const { serverDir, outfile, extraArgs = [] } = options;
|
|
324
|
+
const entryPoint = join2(serverDir, "server-entry.js");
|
|
325
|
+
const args = [
|
|
326
|
+
"build",
|
|
327
|
+
entryPoint,
|
|
328
|
+
"--production",
|
|
329
|
+
"--compile",
|
|
330
|
+
"--minify",
|
|
331
|
+
"--bytecode",
|
|
332
|
+
"--sourcemap",
|
|
333
|
+
"--define",
|
|
334
|
+
"process.env.TURBOPACK=1",
|
|
335
|
+
"--define",
|
|
336
|
+
"process.env.__NEXT_EXPERIMENTAL_REACT=",
|
|
337
|
+
"--define",
|
|
338
|
+
'process.env.NEXT_RUNTIME="nodejs"',
|
|
339
|
+
"--outfile",
|
|
340
|
+
outfile,
|
|
341
|
+
...extraArgs
|
|
342
|
+
];
|
|
343
|
+
console.log(`next-bun-compile: Compiling to ${outfile}...`);
|
|
344
|
+
execFileSync("bun", args, { stdio: "inherit" });
|
|
345
|
+
console.log(`next-bun-compile: Done → ${outfile}`);
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
export { __require, generateEntryPoint, compile };
|
package/dist/index.js
CHANGED
|
@@ -1,284 +1,11 @@
|
|
|
1
|
-
import { createRequire } from "node:module";
|
|
2
|
-
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
3
|
-
|
|
4
|
-
// src/generate.ts
|
|
5
1
|
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
statSync,
|
|
11
|
-
mkdirSync
|
|
12
|
-
} from "node:fs";
|
|
13
|
-
import { join, relative } from "node:path";
|
|
14
|
-
import { createHash } from "node:crypto";
|
|
15
|
-
function walkDir(dir, base = dir) {
|
|
16
|
-
const results = [];
|
|
17
|
-
if (!existsSync(dir))
|
|
18
|
-
return results;
|
|
19
|
-
for (const entry of readdirSync(dir)) {
|
|
20
|
-
const full = join(dir, entry);
|
|
21
|
-
if (statSync(full).isDirectory()) {
|
|
22
|
-
results.push(...walkDir(full, base));
|
|
23
|
-
} else {
|
|
24
|
-
results.push({ absolutePath: full, relativePath: relative(base, full) });
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
return results;
|
|
28
|
-
}
|
|
29
|
-
function toVarName(filePath) {
|
|
30
|
-
const hash = createHash("md5").update(filePath).digest("hex").slice(0, 6);
|
|
31
|
-
const safe = filePath.replace(/[^a-zA-Z0-9]/g, "_").slice(0, 40);
|
|
32
|
-
return `asset_${safe}_${hash}`;
|
|
33
|
-
}
|
|
34
|
-
function generateStubs(standaloneDir) {
|
|
35
|
-
const stubs = [
|
|
36
|
-
{
|
|
37
|
-
path: "node_modules/next/dist/server/dev/next-dev-server.js",
|
|
38
|
-
content: "module.exports = { default: null };"
|
|
39
|
-
},
|
|
40
|
-
{
|
|
41
|
-
path: "node_modules/next/dist/server/lib/router-utils/setup-dev-bundler.js",
|
|
42
|
-
content: "module.exports = {};"
|
|
43
|
-
},
|
|
44
|
-
{
|
|
45
|
-
path: "node_modules/@opentelemetry/api/index.js",
|
|
46
|
-
content: "throw new Error('not installed');"
|
|
47
|
-
},
|
|
48
|
-
{
|
|
49
|
-
path: "node_modules/critters/index.js",
|
|
50
|
-
content: "module.exports = {};"
|
|
51
|
-
}
|
|
52
|
-
];
|
|
53
|
-
let count = 0;
|
|
54
|
-
for (const stub of stubs) {
|
|
55
|
-
const fullPath = join(standaloneDir, stub.path);
|
|
56
|
-
if (!existsSync(fullPath)) {
|
|
57
|
-
const dir = join(fullPath, "..");
|
|
58
|
-
if (!existsSync(dir)) {
|
|
59
|
-
mkdirSync(dir, { recursive: true });
|
|
60
|
-
}
|
|
61
|
-
writeFileSync(fullPath, stub.content);
|
|
62
|
-
count++;
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
if (count > 0) {
|
|
66
|
-
console.log(`next-bun-compile: Created ${count} module stubs`);
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
function patchRequireHook(standaloneDir) {
|
|
70
|
-
const hookPath = join(standaloneDir, "node_modules/next/dist/server/require-hook.js");
|
|
71
|
-
if (!existsSync(hookPath))
|
|
72
|
-
return;
|
|
73
|
-
let content = readFileSync(hookPath, "utf-8");
|
|
74
|
-
const target = "let resolve = process.env.NEXT_MINIMAL ? __non_webpack_require__.resolve : require.resolve;";
|
|
75
|
-
if (!content.includes(target))
|
|
76
|
-
return;
|
|
77
|
-
content = content.replace(target, `let _resolve = process.env.NEXT_MINIMAL ? __non_webpack_require__.resolve : require.resolve;
|
|
78
|
-
let resolve = (id) => { try { return _resolve(id); } catch { return ''; } };`);
|
|
79
|
-
writeFileSync(hookPath, content);
|
|
80
|
-
console.log("next-bun-compile: Patched require-hook.js for compiled binary compatibility");
|
|
81
|
-
}
|
|
82
|
-
function collectExternalModules(standaloneDir) {
|
|
83
|
-
const chunksDir = join(standaloneDir, ".next/server/chunks");
|
|
84
|
-
if (!existsSync(chunksDir))
|
|
85
|
-
return [];
|
|
86
|
-
const seeds = new Set;
|
|
87
|
-
for (const { absolutePath } of walkDir(chunksDir)) {
|
|
88
|
-
if (!absolutePath.endsWith(".js"))
|
|
89
|
-
continue;
|
|
90
|
-
const content = readFileSync(absolutePath, "utf-8");
|
|
91
|
-
for (const match of content.matchAll(/require\("(next\/dist\/[^"]+)"\)/g)) {
|
|
92
|
-
seeds.add(match[1]);
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
const deps = new Set;
|
|
96
|
-
function trace(file) {
|
|
97
|
-
if (deps.has(file))
|
|
98
|
-
return;
|
|
99
|
-
let fullPath = join(standaloneDir, "node_modules", file);
|
|
100
|
-
if (existsSync(fullPath) && statSync(fullPath).isDirectory()) {
|
|
101
|
-
const pkgJson = join(fullPath, "package.json");
|
|
102
|
-
if (existsSync(pkgJson)) {
|
|
103
|
-
deps.add(file + "/package.json");
|
|
104
|
-
}
|
|
105
|
-
file = file + "/index.js";
|
|
106
|
-
fullPath = join(standaloneDir, "node_modules", file);
|
|
107
|
-
}
|
|
108
|
-
if (!existsSync(fullPath))
|
|
109
|
-
return;
|
|
110
|
-
deps.add(file);
|
|
111
|
-
const content = readFileSync(fullPath, "utf-8");
|
|
112
|
-
for (const match of content.matchAll(/require\("([^"]+)"\)/g)) {
|
|
113
|
-
const req = match[1];
|
|
114
|
-
let resolved;
|
|
115
|
-
if (req.startsWith(".")) {
|
|
116
|
-
resolved = join(file, "..", req).replace(/\\/g, "/");
|
|
117
|
-
if (!resolved.endsWith(".js"))
|
|
118
|
-
resolved += ".js";
|
|
119
|
-
} else if (req.startsWith("next/")) {
|
|
120
|
-
resolved = req;
|
|
121
|
-
if (!resolved.endsWith(".js"))
|
|
122
|
-
resolved += ".js";
|
|
123
|
-
}
|
|
124
|
-
if (resolved)
|
|
125
|
-
trace(resolved);
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
for (const seed of seeds)
|
|
129
|
-
trace(seed);
|
|
130
|
-
return [...deps];
|
|
131
|
-
}
|
|
132
|
-
function generateEntryPoint(options) {
|
|
133
|
-
const { standaloneDir, distDir, projectDir } = options;
|
|
134
|
-
generateStubs(standaloneDir);
|
|
135
|
-
patchRequireHook(standaloneDir);
|
|
136
|
-
const staticDir = join(distDir, "static");
|
|
137
|
-
const staticFiles = walkDir(staticDir).map((f) => ({
|
|
138
|
-
...f,
|
|
139
|
-
urlPath: `/_next/static/${f.relativePath.replace(/\\/g, "/")}`
|
|
140
|
-
}));
|
|
141
|
-
const publicDir = join(projectDir, "public");
|
|
142
|
-
const publicFiles = walkDir(publicDir).map((f) => ({
|
|
143
|
-
...f,
|
|
144
|
-
urlPath: `/${f.relativePath.replace(/\\/g, "/")}`
|
|
145
|
-
}));
|
|
146
|
-
const standaloneNextDir = join(standaloneDir, ".next");
|
|
147
|
-
const runtimeFiles = walkDir(standaloneNextDir).map((f) => ({
|
|
148
|
-
...f,
|
|
149
|
-
urlPath: `__runtime/.next/${f.relativePath.replace(/\\/g, "/")}`
|
|
150
|
-
}));
|
|
151
|
-
const externalModules = collectExternalModules(standaloneDir);
|
|
152
|
-
const externalPaths = ["next/package.json", ...externalModules];
|
|
153
|
-
const externalDir = join(standaloneDir, ".next/__external");
|
|
154
|
-
for (const mod of externalPaths) {
|
|
155
|
-
const src = join(standaloneDir, "node_modules", mod);
|
|
156
|
-
if (!existsSync(src))
|
|
157
|
-
continue;
|
|
158
|
-
const dest = join(externalDir, mod);
|
|
159
|
-
mkdirSync(join(dest, ".."), { recursive: true });
|
|
160
|
-
writeFileSync(dest, readFileSync(src));
|
|
161
|
-
runtimeFiles.push({
|
|
162
|
-
absolutePath: dest,
|
|
163
|
-
relativePath: `__external/${mod}`,
|
|
164
|
-
urlPath: `__runtime/.next/node_modules/${mod.replace(/\\/g, "/")}`
|
|
165
|
-
});
|
|
166
|
-
}
|
|
167
|
-
if (externalModules.length > 0) {
|
|
168
|
-
console.log(`next-bun-compile: Embedding ${externalModules.length} external modules for SSR`);
|
|
169
|
-
}
|
|
170
|
-
const ctx = JSON.parse(readFileSync(join(distDir, "bun-compile-ctx.json"), "utf-8"));
|
|
171
|
-
const { assetPrefix } = ctx;
|
|
172
|
-
const assetsToEmbed = assetPrefix ? [...publicFiles, ...runtimeFiles] : [...staticFiles, ...publicFiles, ...runtimeFiles];
|
|
173
|
-
if (assetPrefix) {
|
|
174
|
-
console.log(`next-bun-compile: assetPrefix detected — skipping ${staticFiles.length} static assets (served from CDN)`);
|
|
175
|
-
}
|
|
176
|
-
console.log(`next-bun-compile: Embedding ${assetsToEmbed.length} assets (${staticFiles.length} static + ${publicFiles.length} public + ${runtimeFiles.length} runtime)`);
|
|
177
|
-
const imports = [];
|
|
178
|
-
const mapEntries = [];
|
|
179
|
-
for (const asset of assetsToEmbed) {
|
|
180
|
-
const varName = toVarName(asset.urlPath);
|
|
181
|
-
const importPath = relative(standaloneDir, asset.absolutePath).replace(/\\/g, "/");
|
|
182
|
-
imports.push(`import ${varName} from "./${importPath}" with { type: "file" };`);
|
|
183
|
-
mapEntries.push(` ["${asset.urlPath}", ${varName}],`);
|
|
184
|
-
}
|
|
185
|
-
writeFileSync(join(standaloneDir, "assets.generated.js"), `${imports.join(`
|
|
186
|
-
`)}
|
|
187
|
-
export const assetMap = new Map([
|
|
188
|
-
${mapEntries.join(`
|
|
189
|
-
`)}
|
|
190
|
-
]);
|
|
191
|
-
`);
|
|
192
|
-
const standaloneServerSrc = readFileSync(join(standaloneDir, "server.js"), "utf-8");
|
|
193
|
-
const configMatch = standaloneServerSrc.match(/const nextConfig = ({[\s\S]*?})\n/);
|
|
194
|
-
if (!configMatch) {
|
|
195
|
-
throw new Error("next-bun-compile: Could not extract nextConfig from standalone server.js");
|
|
196
|
-
}
|
|
197
|
-
const assetExtractions = assetsToEmbed.map((a) => {
|
|
198
|
-
let diskPath;
|
|
199
|
-
if (a.urlPath.startsWith("__runtime/")) {
|
|
200
|
-
diskPath = a.urlPath.slice("__runtime/".length);
|
|
201
|
-
} else if (a.urlPath.startsWith("/_next/static/")) {
|
|
202
|
-
diskPath = ".next/static/" + a.relativePath;
|
|
203
|
-
} else {
|
|
204
|
-
diskPath = "public/" + a.relativePath;
|
|
205
|
-
}
|
|
206
|
-
return [a.urlPath, diskPath];
|
|
207
|
-
});
|
|
208
|
-
const serverEntry = `import { assetMap } from "./assets.generated.js";
|
|
209
|
-
const path = require("path");
|
|
210
|
-
const fs = require("fs");
|
|
211
|
-
|
|
212
|
-
const baseDir = path.dirname(process.execPath);
|
|
213
|
-
process.chdir(baseDir);
|
|
214
|
-
process.env.NODE_ENV = "production";
|
|
215
|
-
|
|
216
|
-
const nextConfig = ${configMatch[1]};
|
|
217
|
-
process.env.__NEXT_PRIVATE_STANDALONE_CONFIG = JSON.stringify(nextConfig);
|
|
218
|
-
|
|
219
|
-
const currentPort = parseInt(process.env.PORT, 10) || 3000;
|
|
220
|
-
const hostname = process.env.HOSTNAME || "0.0.0.0";
|
|
221
|
-
let keepAliveTimeout = parseInt(process.env.KEEP_ALIVE_TIMEOUT, 10);
|
|
222
|
-
if (Number.isNaN(keepAliveTimeout) || !Number.isFinite(keepAliveTimeout) || keepAliveTimeout < 0) {
|
|
223
|
-
keepAliveTimeout = undefined;
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
const extractions = ${JSON.stringify(assetExtractions)};
|
|
227
|
-
async function extractAssets() {
|
|
228
|
-
let n = 0;
|
|
229
|
-
for (const [urlPath, diskPath] of extractions) {
|
|
230
|
-
const fullPath = path.join(baseDir, diskPath);
|
|
231
|
-
if (fs.existsSync(fullPath)) continue;
|
|
232
|
-
fs.mkdirSync(path.dirname(fullPath), { recursive: true });
|
|
233
|
-
const embedded = assetMap.get(urlPath);
|
|
234
|
-
if (embedded) { await Bun.write(fullPath, Bun.file(embedded)); n++; }
|
|
235
|
-
}
|
|
236
|
-
if (n > 0) console.log(\`Extracted \${n} assets\`);
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
extractAssets().then(() => {
|
|
240
|
-
require("next");
|
|
241
|
-
const { startServer } = require("next/dist/server/lib/start-server");
|
|
242
|
-
return startServer({
|
|
243
|
-
dir: baseDir, isDev: false, config: nextConfig,
|
|
244
|
-
hostname, port: currentPort, allowRetry: false, keepAliveTimeout,
|
|
245
|
-
});
|
|
246
|
-
}).catch((err) => { console.error(err); process.exit(1); });
|
|
247
|
-
`;
|
|
248
|
-
writeFileSync(join(standaloneDir, "server-entry.js"), serverEntry);
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
// src/compile.ts
|
|
252
|
-
import { execFileSync } from "node:child_process";
|
|
253
|
-
import { join as join2 } from "node:path";
|
|
254
|
-
function compile(options) {
|
|
255
|
-
const { standaloneDir, outfile, extraArgs = [] } = options;
|
|
256
|
-
const entryPoint = join2(standaloneDir, "server-entry.js");
|
|
257
|
-
const args = [
|
|
258
|
-
"build",
|
|
259
|
-
entryPoint,
|
|
260
|
-
"--production",
|
|
261
|
-
"--compile",
|
|
262
|
-
"--minify",
|
|
263
|
-
"--bytecode",
|
|
264
|
-
"--sourcemap",
|
|
265
|
-
"--define",
|
|
266
|
-
"process.env.TURBOPACK=1",
|
|
267
|
-
"--define",
|
|
268
|
-
"process.env.__NEXT_EXPERIMENTAL_REACT=",
|
|
269
|
-
"--define",
|
|
270
|
-
'process.env.NEXT_RUNTIME="nodejs"',
|
|
271
|
-
"--outfile",
|
|
272
|
-
outfile,
|
|
273
|
-
...extraArgs
|
|
274
|
-
];
|
|
275
|
-
console.log(`next-bun-compile: Compiling to ${outfile}...`);
|
|
276
|
-
execFileSync("bun", args, { stdio: "inherit" });
|
|
277
|
-
console.log(`next-bun-compile: Done → ${outfile}`);
|
|
278
|
-
}
|
|
2
|
+
__require,
|
|
3
|
+
compile,
|
|
4
|
+
generateEntryPoint
|
|
5
|
+
} from "./index-81394x5f.js";
|
|
279
6
|
|
|
280
7
|
// src/index.ts
|
|
281
|
-
import { join
|
|
8
|
+
import { join } from "node:path";
|
|
282
9
|
var knownTranspilePackages = ["pino", "pino-pretty"];
|
|
283
10
|
var adapter = {
|
|
284
11
|
name: "next-bun-compile",
|
|
@@ -303,8 +30,8 @@ var adapter = {
|
|
|
303
30
|
return config;
|
|
304
31
|
},
|
|
305
32
|
async onBuildComplete(ctx) {
|
|
306
|
-
const { writeFileSync
|
|
307
|
-
|
|
33
|
+
const { writeFileSync } = await import("node:fs");
|
|
34
|
+
writeFileSync(join(ctx.distDir, "bun-compile-ctx.json"), JSON.stringify({
|
|
308
35
|
distDir: ctx.distDir,
|
|
309
36
|
projectDir: ctx.projectDir,
|
|
310
37
|
assetPrefix: ctx.config.assetPrefix || ""
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "next-bun-compile",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.1",
|
|
4
4
|
"description": "Next.js Build Adapter that compiles your app into a Bun single-file executable",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"dist"
|
|
19
19
|
],
|
|
20
20
|
"scripts": {
|
|
21
|
-
"build": "bun build src/index.ts src/
|
|
21
|
+
"build": "bun build src/index.ts src/cli.ts --outdir dist --target node --splitting",
|
|
22
22
|
"typecheck": "tsc --noEmit"
|
|
23
23
|
},
|
|
24
24
|
"peerDependencies": {
|
package/dist/compile.js
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { createRequire } from "node:module";
|
|
2
|
-
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
3
|
-
|
|
4
|
-
// src/compile.ts
|
|
5
|
-
import { execFileSync } from "node:child_process";
|
|
6
|
-
import { join } from "node:path";
|
|
7
|
-
function compile(options) {
|
|
8
|
-
const { standaloneDir, outfile, extraArgs = [] } = options;
|
|
9
|
-
const entryPoint = join(standaloneDir, "server-entry.js");
|
|
10
|
-
const args = [
|
|
11
|
-
"build",
|
|
12
|
-
entryPoint,
|
|
13
|
-
"--production",
|
|
14
|
-
"--compile",
|
|
15
|
-
"--minify",
|
|
16
|
-
"--bytecode",
|
|
17
|
-
"--sourcemap",
|
|
18
|
-
"--define",
|
|
19
|
-
"process.env.TURBOPACK=1",
|
|
20
|
-
"--define",
|
|
21
|
-
"process.env.__NEXT_EXPERIMENTAL_REACT=",
|
|
22
|
-
"--define",
|
|
23
|
-
'process.env.NEXT_RUNTIME="nodejs"',
|
|
24
|
-
"--outfile",
|
|
25
|
-
outfile,
|
|
26
|
-
...extraArgs
|
|
27
|
-
];
|
|
28
|
-
console.log(`next-bun-compile: Compiling to ${outfile}...`);
|
|
29
|
-
execFileSync("bun", args, { stdio: "inherit" });
|
|
30
|
-
console.log(`next-bun-compile: Done → ${outfile}`);
|
|
31
|
-
}
|
|
32
|
-
export {
|
|
33
|
-
compile
|
|
34
|
-
};
|