seabox 0.2.0 → 0.3.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/bin/seabox-rebuild.mjs +34 -15
- package/lib/build-cache.mjs +11 -4
- package/lib/multi-target-builder.mjs +12 -8
- package/package.json +1 -1
package/bin/seabox-rebuild.mjs
CHANGED
|
@@ -16,15 +16,16 @@ const __dirname = path.dirname(__filename);
|
|
|
16
16
|
/**
|
|
17
17
|
* Rebuild a native module for a specific target
|
|
18
18
|
* @param {string} modulePath - Path to the native module
|
|
19
|
+
* @param {string} nodeVersion - Target Node.js version (e.g., "24.13.0")
|
|
19
20
|
* @param {string} platform - Target platform (win32, linux, darwin)
|
|
20
21
|
* @param {string} arch - Target architecture (x64, arm64)
|
|
21
22
|
* @param {boolean} verbose - Enable verbose logging
|
|
22
23
|
*/
|
|
23
|
-
function rebuildNativeModule(modulePath, platform, arch, verbose = false) {
|
|
24
|
+
function rebuildNativeModule(modulePath, nodeVersion, platform, arch, verbose = false) {
|
|
24
25
|
diag.setVerbose(verbose);
|
|
25
26
|
|
|
26
27
|
diag.verbose(`Rebuilding native module: ${modulePath}`);
|
|
27
|
-
diag.verbose(`Target: ${platform}-${arch}`);
|
|
28
|
+
diag.verbose(`Target: Node.js ${nodeVersion} ${platform}-${arch}`);
|
|
28
29
|
|
|
29
30
|
const packageJsonPath = path.join(modulePath, 'package.json');
|
|
30
31
|
if (!fs.existsSync(packageJsonPath)) {
|
|
@@ -42,42 +43,60 @@ function rebuildNativeModule(modulePath, platform, arch, verbose = false) {
|
|
|
42
43
|
}
|
|
43
44
|
|
|
44
45
|
try {
|
|
45
|
-
// Use node-gyp to rebuild for the target platform
|
|
46
|
-
|
|
46
|
+
// Use node-gyp to rebuild for the target Node.js version, platform, and architecture
|
|
47
|
+
// --target specifies the Node.js version (critical for NODE_MODULE_VERSION)
|
|
48
|
+
// --dist-url ensures node-gyp downloads headers from the correct location
|
|
49
|
+
const cmd = `npx node-gyp rebuild --target=${nodeVersion} --arch=${arch} --dist-url=https://nodejs.org/dist`;
|
|
47
50
|
|
|
48
|
-
diag.verbose(`
|
|
51
|
+
diag.verbose(`Building for Node.js ${nodeVersion} (${platform}-${arch})`, 2);
|
|
52
|
+
diag.verbose(`Command: ${cmd}`, 2);
|
|
49
53
|
|
|
50
54
|
execSync(cmd, {
|
|
51
55
|
cwd: modulePath,
|
|
52
|
-
stdio:
|
|
56
|
+
stdio: 'pipe', // Hide output unless error occurs
|
|
53
57
|
env: {
|
|
54
58
|
...process.env,
|
|
55
|
-
|
|
56
|
-
|
|
59
|
+
npm_config_target: nodeVersion,
|
|
60
|
+
npm_config_arch: arch,
|
|
61
|
+
npm_config_target_arch: arch,
|
|
62
|
+
npm_config_disturl: 'https://nodejs.org/dist'
|
|
57
63
|
}
|
|
58
64
|
});
|
|
59
65
|
|
|
60
|
-
diag.verbose(`Successfully
|
|
66
|
+
diag.verbose(`Successfully built for Node.js ${nodeVersion}`, 2);
|
|
61
67
|
} catch (error) {
|
|
68
|
+
// Show node-gyp output on error
|
|
69
|
+
if (error.stdout) console.error(error.stdout.toString());
|
|
70
|
+
if (error.stderr) console.error(error.stderr.toString());
|
|
62
71
|
diag.verbose(`Failed to rebuild ${moduleName}: ${error.message}`);
|
|
63
72
|
throw error;
|
|
64
73
|
}
|
|
65
74
|
}
|
|
66
75
|
|
|
67
|
-
// CLI entry point
|
|
68
|
-
|
|
76
|
+
// CLI entry point - compare normalized paths for cross-platform compatibility
|
|
77
|
+
const isMainModule = (() => {
|
|
78
|
+
try {
|
|
79
|
+
const scriptPath = fileURLToPath(import.meta.url);
|
|
80
|
+
const argPath = path.resolve(process.argv[1]);
|
|
81
|
+
return scriptPath === argPath;
|
|
82
|
+
} catch {
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
})();
|
|
86
|
+
|
|
87
|
+
if (isMainModule) {
|
|
69
88
|
const args = process.argv.slice(2);
|
|
70
89
|
|
|
71
|
-
if (args.length <
|
|
72
|
-
diag.error('Usage: seabox-rebuild <module-path> <platform> <arch> [--verbose]');
|
|
90
|
+
if (args.length < 4) {
|
|
91
|
+
diag.error('Usage: seabox-rebuild <module-path> <node-version> <platform> <arch> [--verbose]');
|
|
73
92
|
process.exit(1);
|
|
74
93
|
}
|
|
75
94
|
|
|
76
|
-
const [modulePath, platform, arch] = args;
|
|
95
|
+
const [modulePath, nodeVersion, platform, arch] = args;
|
|
77
96
|
const verbose = args.includes('--verbose') || args.includes('-v');
|
|
78
97
|
|
|
79
98
|
try {
|
|
80
|
-
rebuildNativeModule(modulePath, platform, arch, verbose);
|
|
99
|
+
rebuildNativeModule(modulePath, nodeVersion, platform, arch, verbose);
|
|
81
100
|
process.exit(0);
|
|
82
101
|
} catch (error) {
|
|
83
102
|
diag.error(`Rebuild failed: ${error.message}`);
|
package/lib/build-cache.mjs
CHANGED
|
@@ -110,13 +110,15 @@ export class BuildCache {
|
|
|
110
110
|
/**
|
|
111
111
|
* Get cached native module build
|
|
112
112
|
* @param {string} moduleRoot - Module root path
|
|
113
|
-
* @param {string} target - Build target
|
|
113
|
+
* @param {string} target - Build target (e.g., node24.11.0-win32-x64)
|
|
114
114
|
* @returns {string|null} - Path to cached .node file
|
|
115
115
|
*/
|
|
116
116
|
getCachedNativeBuild(moduleRoot, target) {
|
|
117
|
+
// Include the FULL target string (with Node.js version) in cache key
|
|
118
|
+
// This ensures different Node.js versions have separate cache entries
|
|
117
119
|
const cacheKey = crypto
|
|
118
120
|
.createHash('sha256')
|
|
119
|
-
.update(moduleRoot
|
|
121
|
+
.update(`${moduleRoot}||${target}`)
|
|
120
122
|
.digest('hex')
|
|
121
123
|
.substring(0, 16);
|
|
122
124
|
|
|
@@ -132,6 +134,9 @@ export class BuildCache {
|
|
|
132
134
|
if (cacheStats.mtime > sourceStats.mtime) {
|
|
133
135
|
return cachePath;
|
|
134
136
|
}
|
|
137
|
+
} else {
|
|
138
|
+
// If no binding.gyp, still return cached binary (e.g., prebuild scenario)
|
|
139
|
+
return cachePath;
|
|
135
140
|
}
|
|
136
141
|
}
|
|
137
142
|
|
|
@@ -141,13 +146,15 @@ export class BuildCache {
|
|
|
141
146
|
/**
|
|
142
147
|
* Cache a native module build
|
|
143
148
|
* @param {string} moduleRoot - Module root path
|
|
144
|
-
* @param {string} target - Build target
|
|
149
|
+
* @param {string} target - Build target (e.g., node24.11.0-win32-x64)
|
|
145
150
|
* @param {string} builtBinaryPath - Path to built .node file
|
|
146
151
|
*/
|
|
147
152
|
cacheNativeBuild(moduleRoot, target, builtBinaryPath) {
|
|
153
|
+
// Use the FULL target string (with Node.js version) in cache key
|
|
154
|
+
// This ensures different Node.js versions have separate cache entries
|
|
148
155
|
const cacheKey = crypto
|
|
149
156
|
.createHash('sha256')
|
|
150
|
-
.update(moduleRoot
|
|
157
|
+
.update(`${moduleRoot}||${target}`)
|
|
151
158
|
.digest('hex')
|
|
152
159
|
.substring(0, 16);
|
|
153
160
|
|
|
@@ -287,7 +287,7 @@ export class MultiTargetBuilder {
|
|
|
287
287
|
}
|
|
288
288
|
|
|
289
289
|
// Rebuild the module
|
|
290
|
-
diag.verbose(`Rebuilding: ${moduleName}`, 2);
|
|
290
|
+
diag.verbose(`Rebuilding: ${moduleName} for Node.js ${parseTarget(target).nodeVersion}`, 2);
|
|
291
291
|
|
|
292
292
|
await this.rebuildNativeModule(moduleInfo.packageRoot, target);
|
|
293
293
|
|
|
@@ -326,9 +326,12 @@ export class MultiTargetBuilder {
|
|
|
326
326
|
throw new Error('seabox-rebuild.mjs not found');
|
|
327
327
|
}
|
|
328
328
|
|
|
329
|
+
const { nodeVersion, platform, arch } = parseTarget(target);
|
|
330
|
+
|
|
329
331
|
try {
|
|
330
|
-
|
|
331
|
-
|
|
332
|
+
// Always inherit stdio to show node-gyp progress (header downloads, etc.)
|
|
333
|
+
execSync(`node "${rebuildScript}" "${packageRoot}" ${nodeVersion} ${platform} ${arch}${this.verbose ? ' --verbose' : ''}`, {
|
|
334
|
+
stdio: 'inherit', // Show node-gyp output including header downloads
|
|
332
335
|
cwd: this.projectRoot
|
|
333
336
|
});
|
|
334
337
|
} catch (err) {
|
|
@@ -613,16 +616,17 @@ const SEA_ENCRYPTED_ASSETS = new Set([]);
|
|
|
613
616
|
const seaConfigPath = path.join(tempDir, 'sea-config.json');
|
|
614
617
|
writeSeaConfigJson(seaConfig, seaConfigPath, allAssets, tempDir);
|
|
615
618
|
|
|
616
|
-
//
|
|
617
|
-
await generateBlob(seaConfigPath, process.execPath);
|
|
618
|
-
diag.success('SEA blob generated');
|
|
619
|
-
|
|
620
|
-
// Fetch Node binary
|
|
619
|
+
// Fetch Node binary FIRST - needed for blob generation
|
|
621
620
|
diag.buildStep(buildNumber, 5, 'Fetching Node.js binary...');
|
|
622
621
|
const cacheDir = path.join(this.projectRoot, 'node_modules', '.cache', 'sea-node-binaries');
|
|
623
622
|
const nodeBinary = await fetchNodeBinary(nodeVersion, platform, arch, cacheDir);
|
|
624
623
|
diag.success('Node binary ready');
|
|
625
624
|
|
|
625
|
+
// Generate blob using the TARGET Node.js binary (not current process.execPath)
|
|
626
|
+
// This is critical for snapshots - they must be built with the target Node version
|
|
627
|
+
await generateBlob(seaConfigPath, nodeBinary);
|
|
628
|
+
diag.success('SEA blob generated');
|
|
629
|
+
|
|
626
630
|
// Inject blob
|
|
627
631
|
diag.buildStep(buildNumber, 6, 'Injecting blob into executable...');
|
|
628
632
|
const outputExe = path.join(outputDir, executableName);
|