next-bun-compile 0.6.8 → 0.6.9

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-mx555e90.js";
5
+ } from "./index-h8ak29p2.js";
6
6
 
7
7
  // src/cli.ts
8
8
  import { existsSync } from "node:fs";
@@ -113,9 +113,17 @@ function generateStubs(standaloneDir) {
113
113
  }
114
114
  function findTurbopackAliases(standaloneNextDir) {
115
115
  const seen = new Map;
116
+ const ensure = (alias) => {
117
+ let e = seen.get(alias);
118
+ if (!e) {
119
+ e = { target: alias.replace(/-[0-9a-f]{16}$/, ""), subpaths: new Set };
120
+ seen.set(alias, e);
121
+ }
122
+ return e;
123
+ };
116
124
  const serverDir = join(standaloneNextDir, "server");
117
125
  if (existsSync(serverDir)) {
118
- const re = /["']([^"'\s/]+-[0-9a-f]{16})(?:\/[^"'\s]+)?["']/g;
126
+ const re = /["']([^"'\s/]+-[0-9a-f]{16})(?:\/([^"'\s]+))?["']/g;
119
127
  for (const f of walkDir(serverDir)) {
120
128
  if (!f.absolutePath.endsWith(".js"))
121
129
  continue;
@@ -127,10 +135,9 @@ function findTurbopackAliases(standaloneNextDir) {
127
135
  }
128
136
  let m;
129
137
  while (m = re.exec(content)) {
130
- const alias = m[1];
131
- if (seen.has(alias))
132
- continue;
133
- seen.set(alias, alias.replace(/-[0-9a-f]{16}$/, ""));
138
+ const entry = ensure(m[1]);
139
+ if (m[2])
140
+ entry.subpaths.add(m[2]);
134
141
  }
135
142
  }
136
143
  }
@@ -145,23 +152,94 @@ function findTurbopackAliases(standaloneNextDir) {
145
152
  try {
146
153
  if (!lstatSync(aliasPath).isSymbolicLink())
147
154
  continue;
148
- seen.set(name, basename(realpathSync(aliasPath)));
155
+ seen.set(name, {
156
+ target: basename(realpathSync(aliasPath)),
157
+ subpaths: new Set
158
+ });
149
159
  } catch {
150
160
  continue;
151
161
  }
152
162
  }
153
163
  }
154
- return Array.from(seen, ([alias, target]) => ({ alias, target }));
164
+ return Array.from(seen, ([alias, { target, subpaths }]) => ({
165
+ alias,
166
+ target,
167
+ subpaths: Array.from(subpaths)
168
+ }));
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;
155
234
  }
156
- function rewriteTurbopackAliases(standaloneNextDir, aliases) {
157
- if (aliases.length === 0)
235
+ function rewriteTurbopackAliases(standaloneNextDir, aliases, resolutions) {
236
+ if (aliases.length === 0 || resolutions.size === 0)
158
237
  return;
159
238
  const serverDir = join(standaloneNextDir, "server");
160
239
  if (!existsSync(serverDir))
161
240
  return;
162
241
  const escape = (s) => s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
163
- const pattern = new RegExp(`(["'])(` + aliases.map((a) => escape(a.alias)).join("|") + `)(?=[/"'])`, "g");
164
- const targetByAlias = new Map(aliases.map((a) => [a.alias, a.target]));
242
+ const pattern = new RegExp(`(["'])((?:` + aliases.map((a) => escape(a.alias)).join("|") + `)(?:/[^"']+)?)\\1`, "g");
165
243
  let rewritten = 0;
166
244
  for (const f of walkDir(serverDir)) {
167
245
  if (!f.absolutePath.endsWith(".js"))
@@ -172,7 +250,12 @@ function rewriteTurbopackAliases(standaloneNextDir, aliases) {
172
250
  } catch {
173
251
  continue;
174
252
  }
175
- const next = content.replace(pattern, (_m, q, alias) => q + targetByAlias.get(alias));
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
+ });
176
259
  if (next !== content) {
177
260
  writeFileSync(f.absolutePath, next);
178
261
  rewritten++;
@@ -343,7 +426,6 @@ function generateEntryPoint(options) {
343
426
  }));
344
427
  const standaloneNextDir = join(serverDir, ".next");
345
428
  const turbopackAliases = findTurbopackAliases(standaloneNextDir);
346
- rewriteTurbopackAliases(standaloneNextDir, turbopackAliases);
347
429
  const aliasNames = new Set(turbopackAliases.map((a) => a.alias));
348
430
  const runtimeFiles = walkDir(standaloneNextDir).filter((f) => {
349
431
  const m = f.relativePath.replace(/\\/g, "/").match(/^node_modules\/([^/]+)/);
@@ -369,6 +451,8 @@ function generateEntryPoint(options) {
369
451
  if (externalModules.length > 0) {
370
452
  console.log(`next-bun-compile: Embedding ${externalModules.length} external modules for SSR`);
371
453
  }
454
+ const canonicalResolutions = buildCanonicalResolutions(externalDir, turbopackAliases);
455
+ rewriteTurbopackAliases(standaloneNextDir, turbopackAliases, canonicalResolutions);
372
456
  const ctx = JSON.parse(readFileSync(join(distDir, "bun-compile-ctx.json"), "utf-8"));
373
457
  const { assetPrefix } = ctx;
374
458
  const assetsToEmbed = assetPrefix ? [...publicFiles, ...runtimeFiles] : [...staticFiles, ...publicFiles, ...runtimeFiles];
@@ -433,7 +517,20 @@ async function extractAssets() {
433
517
  if (fs.existsSync(fullPath)) continue;
434
518
  fs.mkdirSync(path.dirname(fullPath), { recursive: true });
435
519
  const embedded = assetMap.get(urlPath);
436
- if (embedded) { await Bun.write(fullPath, Bun.file(embedded)); n++; }
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++;
437
534
  }
438
535
  if (n > 0) console.log(\`Extracted \${n} assets\`);
439
536
  }
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@ import {
2
2
  __require,
3
3
  compile,
4
4
  generateEntryPoint
5
- } from "./index-mx555e90.js";
5
+ } from "./index-h8ak29p2.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.8",
3
+ "version": "0.6.9",
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",