next-bun-compile 0.6.9 → 0.6.11

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 CHANGED
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  compile,
4
4
  generateEntryPoint
5
- } from "./index-h8ak29p2.js";
5
+ } from "./index-8jf4ty06.js";
6
6
 
7
7
  // src/cli.ts
8
8
  import { existsSync } from "node:fs";
@@ -167,104 +167,6 @@ function findTurbopackAliases(standaloneNextDir) {
167
167
  subpaths: Array.from(subpaths)
168
168
  }));
169
169
  }
170
- function buildCanonicalResolutions(externalRoot, aliases) {
171
- const out = new Map;
172
- const findFile = (dir, candidates) => {
173
- for (const c of candidates) {
174
- if (!c)
175
- continue;
176
- const p = join(dir, c);
177
- if (existsSync(p) && statSync(p).isFile())
178
- return c.replace(/\\/g, "/");
179
- }
180
- return null;
181
- };
182
- const resolveMain = (canonicalDir) => {
183
- const pkgPath = join(canonicalDir, "package.json");
184
- let main = "index.js";
185
- if (existsSync(pkgPath)) {
186
- try {
187
- const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
188
- if (typeof pkg.main === "string")
189
- main = pkg.main;
190
- } catch {}
191
- }
192
- return findFile(canonicalDir, [
193
- main,
194
- main + ".js",
195
- main + ".cjs",
196
- main + ".mjs",
197
- join(main, "index.js"),
198
- join(main, "index.cjs"),
199
- join(main, "index.mjs"),
200
- "index.js",
201
- "index.cjs",
202
- "index.mjs"
203
- ]);
204
- };
205
- const resolveSub = (canonicalDir, sub) => {
206
- const stripped = sub.replace(/\.(?:js|cjs|mjs|json)$/, "");
207
- return findFile(canonicalDir, [
208
- sub,
209
- stripped + ".js",
210
- stripped + ".mjs",
211
- stripped + ".cjs",
212
- stripped + ".json",
213
- join(stripped, "index.js"),
214
- join(stripped, "index.mjs"),
215
- join(stripped, "index.cjs")
216
- ]);
217
- };
218
- for (const { alias, target, subpaths } of aliases) {
219
- const canonicalDir = join(externalRoot, target);
220
- if (!existsSync(canonicalDir))
221
- continue;
222
- const main = resolveMain(canonicalDir);
223
- if (main) {
224
- out.set(alias, `.next/node_modules/${target}/${main}`);
225
- }
226
- for (const sub of subpaths) {
227
- const file = resolveSub(canonicalDir, sub);
228
- if (file) {
229
- out.set(`${alias}/${sub}`, `.next/node_modules/${target}/${file}`);
230
- }
231
- }
232
- }
233
- return out;
234
- }
235
- function rewriteTurbopackAliases(standaloneNextDir, aliases, resolutions) {
236
- if (aliases.length === 0 || resolutions.size === 0)
237
- return;
238
- const serverDir = join(standaloneNextDir, "server");
239
- if (!existsSync(serverDir))
240
- return;
241
- const escape = (s) => s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
242
- const pattern = new RegExp(`(["'])((?:` + aliases.map((a) => escape(a.alias)).join("|") + `)(?:/[^"']+)?)\\1`, "g");
243
- let rewritten = 0;
244
- for (const f of walkDir(serverDir)) {
245
- if (!f.absolutePath.endsWith(".js"))
246
- continue;
247
- let content;
248
- try {
249
- content = readFileSync(f.absolutePath, "utf-8");
250
- } catch {
251
- continue;
252
- }
253
- const next = content.replace(pattern, (match, quote, spec) => {
254
- const rel = resolutions.get(spec);
255
- if (!rel)
256
- return match;
257
- return `${quote}__NBC_BASE__/${rel}${quote}`;
258
- });
259
- if (next !== content) {
260
- writeFileSync(f.absolutePath, next);
261
- rewritten++;
262
- }
263
- }
264
- if (rewritten > 0) {
265
- console.log(`next-bun-compile: Rewrote turbopack-mangled aliases in ${rewritten} server chunks`);
266
- }
267
- }
268
170
  function findServerDir(standaloneDir) {
269
171
  if (existsSync(join(standaloneDir, "server.js"))) {
270
172
  return standaloneDir;
@@ -451,8 +353,6 @@ function generateEntryPoint(options) {
451
353
  if (externalModules.length > 0) {
452
354
  console.log(`next-bun-compile: Embedding ${externalModules.length} external modules for SSR`);
453
355
  }
454
- const canonicalResolutions = buildCanonicalResolutions(externalDir, turbopackAliases);
455
- rewriteTurbopackAliases(standaloneNextDir, turbopackAliases, canonicalResolutions);
456
356
  const ctx = JSON.parse(readFileSync(join(distDir, "bun-compile-ctx.json"), "utf-8"));
457
357
  const { assetPrefix } = ctx;
458
358
  const assetsToEmbed = assetPrefix ? [...publicFiles, ...runtimeFiles] : [...staticFiles, ...publicFiles, ...runtimeFiles];
@@ -494,11 +394,124 @@ ${mapEntries.join(`
494
394
  const serverEntry = `import { assetMap } from "./assets.generated.js";
495
395
  const path = require("path");
496
396
  const fs = require("fs");
397
+ const Module = require("module");
497
398
 
498
399
  const baseDir = path.dirname(process.execPath);
499
400
  process.chdir(baseDir);
500
401
  process.env.NODE_ENV = "production";
501
402
 
403
+ // Install a fallback Module._resolveFilename hook. bun's compiled-binary
404
+ // resolver doesn't walk node_modules from inside a node_modules entry, so
405
+ // once execution enters an extracted package (sharp/lib/index.js → require
406
+ // of detect-libc, @img/sharp-linux-x64/sharp.node, etc.) bun gives up. The
407
+ // hook also redirects turbopack-mangled aliases ("sharp-457ea9eae1af1a9c"
408
+ // → "sharp") so the chunks' externalized require/import calls land on the
409
+ // canonical packages that collectExternalModules extracted.
410
+ //
411
+ // Runs ONLY when bun's resolver throws and reimplements Node-compatible
412
+ // resolution from scratch — walk node_modules, read package.json main,
413
+ // honor exports maps. Generic: every externalized package's internal deps
414
+ // get resolved without per-package patching.
415
+ const __nbcAliases = ${JSON.stringify(Object.fromEntries(turbopackAliases.map((a) => [a.alias, a.target])))};
416
+ const __nbcOrigResolveFilename = Module._resolveFilename;
417
+ function __nbcStatFile(p) {
418
+ try { return fs.statSync(p).isFile() ? p : null; } catch { return null; }
419
+ }
420
+ function __nbcResolveMain(pkgDir, pkgJson) {
421
+ const main = pkgJson && typeof pkgJson.main === "string" ? pkgJson.main : "index.js";
422
+ return __nbcStatFile(path.join(pkgDir, main))
423
+ || __nbcStatFile(path.join(pkgDir, main + ".js"))
424
+ || __nbcStatFile(path.join(pkgDir, main + ".cjs"))
425
+ || __nbcStatFile(path.join(pkgDir, main + ".mjs"))
426
+ || __nbcStatFile(path.join(pkgDir, main, "index.js"))
427
+ || __nbcStatFile(path.join(pkgDir, "index.js"))
428
+ || __nbcStatFile(path.join(pkgDir, "index.cjs"));
429
+ }
430
+ function __nbcResolveSubpath(pkgDir, pkgJson, sub) {
431
+ // Honor exports map (CJS-relevant conditions only)
432
+ if (pkgJson && pkgJson.exports && typeof pkgJson.exports === "object") {
433
+ const key = "./" + sub;
434
+ const entry = pkgJson.exports[key];
435
+ if (entry) {
436
+ let target = typeof entry === "string"
437
+ ? entry
438
+ : entry.require || entry.node || entry.default;
439
+ if (typeof target === "string" && target.startsWith("./")) {
440
+ const f = __nbcStatFile(path.join(pkgDir, target.slice(2)));
441
+ if (f) return f;
442
+ }
443
+ }
444
+ }
445
+ return __nbcStatFile(path.join(pkgDir, sub))
446
+ || __nbcStatFile(path.join(pkgDir, sub + ".js"))
447
+ || __nbcStatFile(path.join(pkgDir, sub + ".cjs"))
448
+ || __nbcStatFile(path.join(pkgDir, sub + ".mjs"))
449
+ || __nbcStatFile(path.join(pkgDir, sub + ".json"))
450
+ || __nbcStatFile(path.join(pkgDir, sub, "index.js"))
451
+ || __nbcStatFile(path.join(pkgDir, sub, "index.cjs"));
452
+ }
453
+ function __nbcResolvePackage(request, fromDir) {
454
+ let pkgName, sub = "";
455
+ if (request[0] === "@") {
456
+ const m = request.match(/^(@[^/]+\\/[^/]+)(?:\\/(.+))?$/);
457
+ if (!m) return null;
458
+ pkgName = m[1]; sub = m[2] || "";
459
+ } else {
460
+ const idx = request.indexOf("/");
461
+ if (idx === -1) { pkgName = request; }
462
+ else { pkgName = request.slice(0, idx); sub = request.slice(idx + 1); }
463
+ }
464
+ let dir = fromDir;
465
+ while (dir.length > 1) {
466
+ const pkgDir = path.join(dir, "node_modules", pkgName);
467
+ if (fs.existsSync(pkgDir)) {
468
+ let pkgJson = null;
469
+ const pkgJsonPath = path.join(pkgDir, "package.json");
470
+ if (fs.existsSync(pkgJsonPath)) {
471
+ try { pkgJson = JSON.parse(fs.readFileSync(pkgJsonPath, "utf-8")); } catch {}
472
+ }
473
+ const resolved = sub
474
+ ? __nbcResolveSubpath(pkgDir, pkgJson, sub)
475
+ : __nbcResolveMain(pkgDir, pkgJson);
476
+ if (resolved) return resolved;
477
+ }
478
+ const parent = path.dirname(dir);
479
+ if (parent === dir) break;
480
+ dir = parent;
481
+ }
482
+ return null;
483
+ }
484
+ function __nbcRedirectAlias(request) {
485
+ if (typeof request !== "string" || request.length === 0) return request;
486
+ // Direct alias match
487
+ if (Object.prototype.hasOwnProperty.call(__nbcAliases, request)) {
488
+ return __nbcAliases[request];
489
+ }
490
+ // Alias-with-subpath match
491
+ const slash = request.indexOf("/", request[0] === "@" ? request.indexOf("/") + 1 : 0);
492
+ if (slash === -1) return request;
493
+ const head = request.slice(0, slash);
494
+ if (Object.prototype.hasOwnProperty.call(__nbcAliases, head)) {
495
+ return __nbcAliases[head] + request.slice(slash);
496
+ }
497
+ return request;
498
+ }
499
+ Module._resolveFilename = function(request, parent, isMain, options) {
500
+ const redirected = __nbcRedirectAlias(request);
501
+ try {
502
+ return __nbcOrigResolveFilename.call(this, redirected, parent, isMain, options);
503
+ } catch (err) {
504
+ // Only attempt fallback for bare package specifiers
505
+ if (typeof redirected !== "string" || redirected[0] === "." || redirected[0] === "/" || /^[a-z]+:/.test(redirected)) {
506
+ throw err;
507
+ }
508
+ const fromDir = parent && parent.filename ? path.dirname(parent.filename) : process.cwd();
509
+ const resolved = __nbcResolvePackage(redirected, fromDir);
510
+ if (resolved) return resolved;
511
+ throw err;
512
+ }
513
+ };
514
+
502
515
  const nextConfig = ${configMatch[1]};
503
516
  process.env.__NEXT_PRIVATE_STANDALONE_CONFIG = JSON.stringify(nextConfig);
504
517
 
@@ -517,20 +530,7 @@ async function extractAssets() {
517
530
  if (fs.existsSync(fullPath)) continue;
518
531
  fs.mkdirSync(path.dirname(fullPath), { recursive: true });
519
532
  const embedded = assetMap.get(urlPath);
520
- if (!embedded) continue;
521
- // Server chunks may contain __NBC_BASE__ placeholders injected at
522
- // build time by rewriteTurbopackAliases. Substitute the real baseDir
523
- // before writing so bun resolves the absolute paths at chunk load.
524
- if (diskPath.startsWith(".next/server/")) {
525
- const text = await Bun.file(embedded).text();
526
- if (text.indexOf("__NBC_BASE__") !== -1) {
527
- await Bun.write(fullPath, text.split("__NBC_BASE__").join(baseDir));
528
- n++;
529
- continue;
530
- }
531
- }
532
- await Bun.write(fullPath, Bun.file(embedded));
533
- n++;
533
+ if (embedded) { await Bun.write(fullPath, Bun.file(embedded)); n++; }
534
534
  }
535
535
  if (n > 0) console.log(\`Extracted \${n} assets\`);
536
536
  }
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@ import {
2
2
  __require,
3
3
  compile,
4
4
  generateEntryPoint
5
- } from "./index-h8ak29p2.js";
5
+ } from "./index-8jf4ty06.js";
6
6
 
7
7
  // src/index.ts
8
8
  import { join } from "node:path";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "next-bun-compile",
3
- "version": "0.6.9",
3
+ "version": "0.6.11",
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",