Skip to content

Commit 958cea7

Browse files
authored
Load native addons directly from prebuilds directory (#809)
* Load native addons directly from prebuilds directory * feat: remove prebuilds when npm_config_build_from_source is set * feat: change the load order to local builds and unbundled first * chore: skip copying prebuilds to build dir
1 parent 31ca5ce commit 958cea7

File tree

6 files changed

+43
-54
lines changed

6 files changed

+43
-54
lines changed

scripts/prebuild.js

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,27 +4,31 @@ const fs = require('fs');
44
const path = require('path');
55

66
/**
7-
* This script copies the prebuilt binaries from the prebuild directory
8-
* for the current platform and architecture to the build/Release directory.
9-
*
7+
* This script checks for the prebuilt binaries for the current platform and
8+
* architecture. It exits with 0 if prebuilds are found and 1 if not.
9+
*
10+
* If npm_config_build_from_source is set then it removes the prebuilds for the
11+
* current platform so they are not loaded at runtime.
12+
*
1013
* Usage:
1114
* node scripts/prebuild.js
1215
*/
1316

17+
const PREBUILD_DIR = path.join(__dirname, '..', 'prebuilds', `${process.platform}-${process.arch}`);
18+
1419
// Skip copying prebuilds when npm_config_build_from_source is set
1520
if (process.env.npm_config_build_from_source === 'true') {
16-
console.log('\x1b[33m> Skipping prebuild copy because npm_config_build_from_source is set\x1b[0m');
21+
console.log('\x1b[33m> Removing prebuilds and rebuilding because npm_config_build_from_source is set\x1b[0m');
22+
fs.rmSync(PREBUILD_DIR, { recursive: true });
1723
process.exit(1);
1824
}
1925

20-
const PREBUILD_DIR = path.join(__dirname, '..', 'prebuilds', `${process.platform}-${process.arch}`);
21-
const RELEASE_DIR = path.join(__dirname, '../build/Release');
22-
2326
/* Copy prebuild files to build/Release */
2427
console.log('\x1b[32m> Copying prebuilds to release folder...\x1b[0m');
2528
if (!fs.existsSync(PREBUILD_DIR)) {
2629
console.log(` SKIPPED Prebuild directory ${PREBUILD_DIR} does not exist`);
2730
// Exit with 1 to fall back on node-gyp building the native modules
2831
process.exit(1);
2932
}
30-
fs.cpSync(PREBUILD_DIR, RELEASE_DIR, { recursive: true });
33+
// Exit with 0 to skip node-gyp building from source
34+
process.exit(0);

src/conpty_console_list_agent.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,9 @@
66
* single console attached to a process.
77
*/
88

9-
let getConsoleProcessList: any;
10-
try {
11-
getConsoleProcessList = require('../build/Release/conpty_console_list.node').getConsoleProcessList;
12-
} catch (err) {
13-
getConsoleProcessList = require('../build/Debug/conpty_console_list.node').getConsoleProcessList;
14-
}
9+
import { loadNativeModule } from './utils';
1510

11+
const getConsoleProcessList = loadNativeModule('conpty_console_list').module.getConsoleProcessList;
1612
const shellPid = parseInt(process.argv[2], 10);
1713
const consoleProcessList = getConsoleProcessList(shellPid);
1814
process.send!({ consoleProcessList });

src/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
import { ITerminal, IPtyOpenOptions, IPtyForkOptions, IWindowsPtyForkOptions } from './interfaces';
88
import { ArgvOrCommandLine } from './types';
9+
import { loadNativeModule } from './utils';
910

1011
let terminalCtor: any;
1112
if (process.platform === 'win32') {
@@ -48,4 +49,4 @@ export function open(options: IPtyOpenOptions): ITerminal {
4849
* Expose the native API when not Windows, note that this is not public API and
4950
* could be removed at any time.
5051
*/
51-
export const native = (process.platform !== 'win32' ? require('../build/Release/pty.node') : null);
52+
export const native = (process.platform !== 'win32' ? loadNativeModule('pty').module : null);

src/unixTerminal.ts

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,24 +9,11 @@ import * as tty from 'tty';
99
import { Terminal, DEFAULT_COLS, DEFAULT_ROWS } from './terminal';
1010
import { IProcessEnv, IPtyForkOptions, IPtyOpenOptions } from './interfaces';
1111
import { ArgvOrCommandLine } from './types';
12-
import { assign } from './utils';
13-
14-
let pty: IUnixNative;
15-
let helperPath: string;
16-
try {
17-
pty = require('../build/Release/pty.node');
18-
helperPath = '../build/Release/spawn-helper';
19-
} catch (outerError) {
20-
try {
21-
pty = require('../build/Debug/pty.node');
22-
helperPath = '../build/Debug/spawn-helper';
23-
} catch (innerError) {
24-
console.error('innerError', innerError);
25-
// Re-throw the exception from the Release require if the Debug require fails as well
26-
throw outerError;
27-
}
28-
}
12+
import { assign, loadNativeModule } from './utils';
2913

14+
const native = loadNativeModule('pty');
15+
const pty: IUnixNative = native.module;
16+
let helperPath = native.dir + '/spawn-helper';
3017
helperPath = path.resolve(__dirname, helperPath);
3118
helperPath = helperPath.replace('app.asar', 'app.asar.unpacked');
3219
helperPath = helperPath.replace('node_modules.asar', 'node_modules.asar.unpacked');

src/utils.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,23 @@ export function assign(target: any, ...sources: any[]): any {
77
sources.forEach(source => Object.keys(source).forEach(key => target[key] = source[key]));
88
return target;
99
}
10+
11+
12+
export function loadNativeModule(name: string): {dir: string, module: any} {
13+
// Check build, debug, and then prebuilds.
14+
const dirs = ['build/Release', 'build/Debug', `prebuilds/${process.platform}-${process.arch}`];
15+
// Check relative to the parent dir for unbundled and then the current dir for bundled
16+
const relative = ['..', '.'];
17+
let lastError: unknown;
18+
for (const d of dirs) {
19+
for (const r of relative) {
20+
const dir = `${r}/${d}/`;
21+
try {
22+
return { dir, module: require(`${dir}/${name}.node`) };
23+
} catch (e) {
24+
lastError = e;
25+
}
26+
}
27+
}
28+
throw new Error(`Failed to load native module: ${name}.node, checked: ${dirs.join(', ')}: ${lastError}`);
29+
}

src/windowsPtyAgent.ts

Lines changed: 3 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { fork } from 'child_process';
1111
import { Socket } from 'net';
1212
import { ArgvOrCommandLine } from './types';
1313
import { ConoutConnection } from './windowsConoutConnection';
14+
import { loadNativeModule } from './utils';
1415

1516
let conptyNative: IConptyNative;
1617
let winptyNative: IWinptyNative;
@@ -62,31 +63,11 @@ export class WindowsPtyAgent {
6263
}
6364
if (this._useConpty) {
6465
if (!conptyNative) {
65-
try {
66-
conptyNative = require('../build/Release/conpty.node');
67-
} catch (outerError) {
68-
try {
69-
conptyNative = require('../build/Debug/conpty.node');
70-
} catch (innerError) {
71-
console.error('innerError', innerError);
72-
// Re-throw the exception from the Release require if the Debug require fails as well
73-
throw outerError;
74-
}
75-
}
66+
conptyNative = loadNativeModule('conpty').module;
7667
}
7768
} else {
7869
if (!winptyNative) {
79-
try {
80-
winptyNative = require('../build/Release/pty.node');
81-
} catch (outerError) {
82-
try {
83-
winptyNative = require('../build/Debug/pty.node');
84-
} catch (innerError) {
85-
console.error('innerError', innerError);
86-
// Re-throw the exception from the Release require if the Debug require fails as well
87-
throw outerError;
88-
}
89-
}
70+
winptyNative = loadNativeModule('pty').module;
9071
}
9172
}
9273
this._ptyNative = this._useConpty ? conptyNative : winptyNative;

0 commit comments

Comments
 (0)