next-bun-compile 0.5.1 → 0.6.0

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/README.md CHANGED
@@ -26,14 +26,24 @@ Add the adapter to your `next.config.ts`:
26
26
  ```ts
27
27
  import type { NextConfig } from "next";
28
28
 
29
+ const nextConfig: NextConfig = {
30
+ adapterPath: require.resolve("next-bun-compile"),
31
+ };
32
+
33
+ export default nextConfig;
34
+ ```
35
+
36
+ <details>
37
+ <summary>Using Next.js 16.1? Use the experimental config instead</summary>
38
+
39
+ ```ts
29
40
  const nextConfig: NextConfig = {
30
41
  experimental: {
31
42
  adapterPath: require.resolve("next-bun-compile"),
32
43
  },
33
44
  };
34
-
35
- export default nextConfig;
36
45
  ```
46
+ </details>
37
47
 
38
48
  Update your build script in `package.json`:
39
49
 
@@ -81,9 +91,7 @@ If you configure `assetPrefix` in your `next.config.ts`, static assets (`/_next/
81
91
  ```ts
82
92
  const nextConfig: NextConfig = {
83
93
  assetPrefix: "https://cdn.example.com",
84
- experimental: {
85
- adapterPath: require.resolve("next-bun-compile"),
86
- },
94
+ adapterPath: require.resolve("next-bun-compile"),
87
95
  };
88
96
  ```
89
97
 
@@ -133,9 +141,7 @@ Failed to load external module pino-142500b1eb3f4baf: Cannot find package ...
133
141
  ```ts
134
142
  const nextConfig: NextConfig = {
135
143
  transpilePackages: ["pino", "pino-pretty"],
136
- experimental: {
137
- adapterPath: require.resolve("next-bun-compile"),
138
- },
144
+ adapterPath: require.resolve("next-bun-compile"),
139
145
  };
140
146
  ```
141
147
 
package/dist/cli.js CHANGED
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  compile,
4
4
  generateEntryPoint
5
- } from "./index-81394x5f.js";
5
+ } from "./index-5m65k8kw.js";
6
6
 
7
7
  // src/cli.ts
8
8
  import { existsSync } from "node:fs";
@@ -36,13 +36,15 @@ function findPackageDirs(nodeModulesDir, pkg) {
36
36
  const direct = join(nodeModulesDir, pkg);
37
37
  if (existsSync(direct))
38
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 + "@"))
39
+ const prefix = pkg.startsWith("@") ? pkg.split("/")[0] + "+" + pkg.split("/")[1] : pkg;
40
+ for (const store of [".bun", ".pnpm"]) {
41
+ const storeDir = join(nodeModulesDir, store);
42
+ if (!existsSync(storeDir))
43
+ continue;
44
+ for (const entry of readdirSync(storeDir)) {
45
+ if (!entry.startsWith(prefix + "@"))
44
46
  continue;
45
- const hoisted = join(bunDir, entry, "node_modules", pkg);
47
+ const hoisted = join(storeDir, entry, "node_modules", pkg);
46
48
  if (existsSync(hoisted))
47
49
  dirs.push(hoisted);
48
50
  }
@@ -145,61 +147,100 @@ let resolve = (id) => { try { return _resolve(id); } catch { return ''; } };`;
145
147
  console.log("next-bun-compile: Patched require-hook.js for compiled binary compatibility");
146
148
  }
147
149
  }
148
- function collectExternalModules(standaloneDir, serverDir) {
149
- const chunksDir = join(serverDir, ".next/server/chunks");
150
- if (!existsSync(chunksDir))
150
+ function collectExternalModules(standaloneDir) {
151
+ const nodeModulesDir = join(standaloneDir, "node_modules");
152
+ if (!existsSync(nodeModulesDir))
151
153
  return [];
152
- const seeds = new Set;
153
- for (const { absolutePath } of walkDir(chunksDir)) {
154
- if (!absolutePath.endsWith(".js"))
155
- continue;
156
- const content = readFileSync(absolutePath, "utf-8");
157
- for (const match of content.matchAll(/require\("(next\/dist\/[^"]+)"\)/g)) {
158
- seeds.add(match[1]);
159
- }
154
+ const pkgRoots = new Map;
155
+ function addPkg(name, path) {
156
+ if (!pkgRoots.has(name))
157
+ pkgRoots.set(name, path);
160
158
  }
161
- const deps = new Set;
162
- function trace(file) {
163
- if (deps.has(file))
159
+ function scanDir(dir) {
160
+ if (!existsSync(dir))
164
161
  return;
165
- let fullPath = join(standaloneDir, "node_modules", file);
166
- if (existsSync(fullPath) && statSync(fullPath).isDirectory()) {
167
- const pkgJson = join(fullPath, "package.json");
168
- if (existsSync(pkgJson)) {
169
- deps.add(file + "/package.json");
162
+ for (const entry of readdirSync(dir)) {
163
+ if (entry.startsWith(".") || entry === "next-bun-compile")
164
+ continue;
165
+ const entryPath = join(dir, entry);
166
+ if (!statSync(entryPath).isDirectory())
167
+ continue;
168
+ if (entry.startsWith("@")) {
169
+ for (const sub of readdirSync(entryPath)) {
170
+ const subPath = join(entryPath, sub);
171
+ if (statSync(subPath).isDirectory())
172
+ addPkg(`${entry}/${sub}`, subPath);
173
+ }
174
+ } else {
175
+ addPkg(entry, entryPath);
170
176
  }
171
- file = file + "/index.js";
172
- fullPath = join(standaloneDir, "node_modules", file);
173
177
  }
174
- if (!existsSync(fullPath))
175
- return;
176
- deps.add(file);
177
- const content = readFileSync(fullPath, "utf-8");
178
- for (const match of content.matchAll(/require\("([^"]+)"\)/g)) {
179
- const req = match[1];
180
- let resolved;
181
- if (req.startsWith(".")) {
182
- resolved = join(file, "..", req).replace(/\\/g, "/");
183
- if (!resolved.endsWith(".js"))
184
- resolved += ".js";
185
- } else if (req.startsWith("next/")) {
186
- resolved = req;
187
- if (!resolved.endsWith(".js"))
188
- resolved += ".js";
178
+ }
179
+ scanDir(nodeModulesDir);
180
+ for (const store of [".bun", ".pnpm"]) {
181
+ const storeDir = join(nodeModulesDir, store);
182
+ if (!existsSync(storeDir))
183
+ continue;
184
+ for (const storeEntry of readdirSync(storeDir)) {
185
+ const nested = join(storeDir, storeEntry, "node_modules");
186
+ if (existsSync(nested))
187
+ scanDir(nested);
188
+ }
189
+ }
190
+ const results = [];
191
+ for (const [name, pkgPath] of pkgRoots) {
192
+ for (const f of walkDir(pkgPath)) {
193
+ results.push({
194
+ mod: `${name}/${f.relativePath.replace(/\\/g, "/")}`,
195
+ src: f.absolutePath
196
+ });
197
+ }
198
+ }
199
+ return results;
200
+ }
201
+ function fixModuleResolution(standaloneDir) {
202
+ const nodeModulesDir = join(standaloneDir, "node_modules");
203
+ for (const pkgDir of findPackageDirs(nodeModulesDir, "next")) {
204
+ const compiledDir = join(pkgDir, "dist/compiled");
205
+ if (!existsSync(compiledDir))
206
+ continue;
207
+ for (const entry of readdirSync(compiledDir)) {
208
+ const dir = join(compiledDir, entry);
209
+ if (!statSync(dir).isDirectory())
210
+ continue;
211
+ const pkgJsonPath = join(dir, "package.json");
212
+ const indexPath = join(dir, "index.js");
213
+ if (!existsSync(pkgJsonPath) || existsSync(indexPath))
214
+ continue;
215
+ const pkg = JSON.parse(readFileSync(pkgJsonPath, "utf-8"));
216
+ if (pkg.main && pkg.main !== "index.js") {
217
+ writeFileSync(indexPath, `module.exports = require("./${pkg.main}");`);
189
218
  }
190
- if (resolved)
191
- trace(resolved);
192
219
  }
193
220
  }
194
- for (const seed of seeds)
195
- trace(seed);
196
- return [...deps];
221
+ for (const helpersDir of findPackageDirs(nodeModulesDir, "@swc/helpers")) {
222
+ const cjsDir = join(helpersDir, "cjs");
223
+ if (!existsSync(cjsDir))
224
+ continue;
225
+ for (const file of readdirSync(cjsDir)) {
226
+ if (!file.endsWith(".cjs"))
227
+ continue;
228
+ const name = file.slice(0, -4);
229
+ const shimDir = join(helpersDir, "_", name);
230
+ const shimFile = join(shimDir, "index.js");
231
+ if (existsSync(shimFile))
232
+ continue;
233
+ mkdirSync(shimDir, { recursive: true });
234
+ writeFileSync(shimFile, `module.exports = require("../../cjs/${file}");`);
235
+ }
236
+ }
197
237
  }
198
238
  function generateEntryPoint(options) {
199
239
  const { standaloneDir, distDir, projectDir } = options;
200
240
  const serverDir = findServerDir(standaloneDir);
201
241
  generateStubs(standaloneDir);
202
242
  patchRequireHook(standaloneDir);
243
+ fixModuleResolution(standaloneDir);
203
244
  const staticDir = join(distDir, "static");
204
245
  const staticFiles = walkDir(staticDir).map((f) => ({
205
246
  ...f,
@@ -215,11 +256,9 @@ function generateEntryPoint(options) {
215
256
  ...f,
216
257
  urlPath: `__runtime/.next/${f.relativePath.replace(/\\/g, "/")}`
217
258
  }));
218
- const externalModules = collectExternalModules(standaloneDir, serverDir);
219
- const externalPaths = ["next/package.json", ...externalModules];
259
+ const externalModules = collectExternalModules(standaloneDir);
220
260
  const externalDir = join(serverDir, ".next/__external");
221
- for (const mod of externalPaths) {
222
- const src = join(standaloneDir, "node_modules", mod);
261
+ for (const { mod, src } of externalModules) {
223
262
  if (!existsSync(src))
224
263
  continue;
225
264
  const dest = join(externalDir, mod);
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@ import {
2
2
  __require,
3
3
  compile,
4
4
  generateEntryPoint
5
- } from "./index-81394x5f.js";
5
+ } from "./index-5m65k8kw.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.5.1",
3
+ "version": "0.6.0",
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",