Skip to content

Commit 0a7a8cb

Browse files
committed
[Demo][Electron] Load prebuilt binaries at runtime
1 parent bc78bfa commit 0a7a8cb

11 files changed

Lines changed: 139 additions & 48 deletions

File tree

demo/electron/car/README.md

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,14 @@ npm run build
6666
npm install
6767
```
6868

69-
3. **Rebuild native modules for Electron:**
69+
3. **Native modules — no manual rebuild needed:**
7070

71-
```bash
72-
npm run rebuild
73-
```
71+
rclnodejs ships prebuilt binaries for Electron and selects the matching one at
72+
runtime from `ROS_DISTRO` + Linux codename + architecture, so just make sure
73+
ROS 2 is sourced (next step) before launching. Do not run `electron-rebuild`
74+
against rclnodejs — it recompiles from source and bypasses the prebuilt binary.
75+
The Forge `rebuildConfig` in `package.json` already excludes `rclnodejs` from
76+
the automatic rebuild step.
7477

7578
4. **Start the demo:**
7679
```bash
@@ -291,13 +294,12 @@ Extend the joystick commands by modifying the switch statement in `main.js` and
291294
- Ensure ROS2 is properly sourced before running npm start
292295
- Check that rclnodejs is built correctly
293296

294-
2. **Native Module Rebuild Issues**
295-
296-
```bash
297-
npm run rebuild
298-
# or manually:
299-
./node_modules/.bin/electron-rebuild
300-
```
297+
2. **Native module fails to load**
298+
- Ensure ROS 2 is sourced so rclnodejs can match its prebuilt binary
299+
(`ROS_DISTRO` must be set; prebuilt binaries are provided for Ubuntu).
300+
- As a last resort, force a from-source rebuild by setting
301+
`RCLNODEJS_FORCE_BUILD=1` before `npm start` (needs a compiler toolchain and
302+
network access).
301303

302304
3. **Topic Not Appearing**
303305
- Verify ROS2 daemon is running: `ros2 daemon status`

demo/electron/car/package.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
"main": "main.js",
66
"scripts": {
77
"start": "electron-forge start",
8-
"rebuild": "electron-rebuild",
98
"package": "electron-forge package",
109
"make": "electron-forge make"
1110
},
@@ -39,6 +38,11 @@
3938
"unpack": "**/node_modules/rclnodejs/**"
4039
}
4140
},
41+
"rebuildConfig": {
42+
"ignoreModules": [
43+
"rclnodejs"
44+
]
45+
},
4246
"makers": [
4347
{
4448
"name": "@electron-forge/maker-squirrel",

demo/electron/manipulator/README.md

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,17 +34,27 @@ An interactive Electron application demonstrating a two-joint robotic manipulato
3434
npm install
3535
```
3636

37-
3. **Rebuild native modules for Electron**:
37+
3. **Source your ROS 2 environment** (required so the matching prebuilt binary is selected):
38+
3839
```bash
39-
npm run rebuild
40+
source /opt/ros/$ROS_DISTRO/setup.bash # or your ROS 2 installation path
4041
```
4142

43+
rclnodejs ships prebuilt native binaries for Electron, so no compilation is needed.
44+
The binary is selected at runtime from `ROS_DISTRO`, the Linux distro codename, and
45+
the CPU architecture, so `ROS_DISTRO` must be set before launching the app. If no
46+
matching prebuilt binary is available for your platform, rclnodejs falls back to
47+
building from source.
48+
49+
> Note: do not run `electron-rebuild` against rclnodejs — it recompiles the addon
50+
> from source and bypasses the prebuilt binary. The Electron Forge `rebuildConfig`
51+
> in `package.json` already excludes `rclnodejs` from the automatic rebuild step.
52+
4253
## 📜 Available Scripts
4354

4455
- **`npm start`** - Launch the application in development mode
4556
- **`npm run package`** - Package the application into a standalone executable folder
4657
- **`npm run make`** - Create platform-specific installers (requires system tools like `zip`, `dpkg`)
47-
- **`npm run rebuild`** - Rebuild native modules after dependency changes
4858

4959
## 🚀 Quick Start
5060

@@ -54,9 +64,9 @@ An interactive Electron application demonstrating a two-joint robotic manipulato
5464
npm start
5565
```
5666

57-
-**No ROS2 environment required**
58-
-**Works without external setup**
67+
-**No ROS2 topic publishing required**
5968
-**Pure visualization and manual control**
69+
- ⚠️ ROS 2 must still be sourced so the prebuilt native binary is selected (otherwise rclnodejs builds from source)
6070
- ⚠️ No ROS2 topic publishing (local mode only)
6171

6272
### Option 2: Manual ROS2 Setup (Recommended for ROS2 Integration)
@@ -308,7 +318,7 @@ manipulator/
308318
2. **Build errors with Electron**
309319

310320
- This demo currently uses Electron 40.1.0
311-
- If you change Electron or other native-module dependencies, rerun `npm run rebuild`
321+
- rclnodejs loads its prebuilt Electron binary at runtime; if it fails to load, ensure ROS 2 is sourced so the matching prebuild is selected. To force a from-source rebuild of rclnodejs, set `RCLNODEJS_FORCE_BUILD=1`
312322
- The versions recorded in `package.json` and `package-lock.json` are the tested baseline for this demo
313323

314324
3. **No ROS2 messages received**

demo/electron/manipulator/package.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
"main": "main.js",
66
"scripts": {
77
"start": "electron-forge start",
8-
"rebuild": "electron-rebuild",
98
"package": "electron-forge package",
109
"make": "electron-forge make"
1110
},
@@ -43,6 +42,11 @@
4342
"unpack": "**/node_modules/rclnodejs/**"
4443
}
4544
},
45+
"rebuildConfig": {
46+
"ignoreModules": [
47+
"rclnodejs"
48+
]
49+
},
4650
"makers": [
4751
{
4852
"name": "@electron-forge/maker-squirrel",

demo/electron/topics/README.md

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,13 @@ A minimal Electron application demonstrating basic ROS2 topic communication usin
4545
npm install
4646
```
4747

48-
4. **Rebuild rclnodejs for Electron**:
49-
```bash
50-
./node_modules/.bin/electron-rebuild
51-
```
48+
4. **Native modules — no manual rebuild needed**:
49+
50+
rclnodejs ships prebuilt binaries for Electron and picks the matching one at
51+
runtime from `ROS_DISTRO` + Linux codename + architecture (ROS 2 was sourced in
52+
step 2). Do not run `electron-rebuild` against rclnodejs — it recompiles from
53+
source and bypasses the prebuilt binary; the Forge `rebuildConfig` already
54+
excludes `rclnodejs`.
5255

5356
## 🚀 Running the Demo
5457

demo/electron/topics/package.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
"main": "main.js",
66
"scripts": {
77
"start": "electron-forge start",
8-
"rebuild": "electron-rebuild",
98
"package": "electron-forge package",
109
"make": "electron-forge make"
1110
},
@@ -36,6 +35,11 @@
3635
"unpack": "**/node_modules/rclnodejs/**"
3736
}
3837
},
38+
"rebuildConfig": {
39+
"ignoreModules": [
40+
"rclnodejs"
41+
]
42+
},
3943
"makers": [
4044
{
4145
"name": "@electron-forge/maker-squirrel",

demo/electron/turtle_tf2/README.md

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -86,13 +86,13 @@ The demo uses the following key dependencies:
8686
npm install
8787
```
8888

89-
3. **Rebuild native modules**:
89+
3. **Native modules — no manual rebuild needed**:
9090

91-
```bash
92-
npm run rebuild
93-
```
94-
95-
This step is crucial for ensuring that rclnodejs and other native dependencies are properly compiled for your system.
91+
rclnodejs ships prebuilt binaries for Electron and selects the matching one at
92+
runtime from `ROS_DISTRO` + Linux codename + architecture, so make sure ROS 2 is
93+
sourced (next step) before launching. Do not run `electron-rebuild` against
94+
rclnodejs — it recompiles from source and bypasses the prebuilt binary; the Forge
95+
`rebuildConfig` in `package.json` already excludes `rclnodejs`.
9696

9797
4. **Source ROS2 environment**:
9898

@@ -111,7 +111,7 @@ The demo uses the following key dependencies:
111111

112112
### Method 1: Complete Demo
113113

114-
Start the full demo with all components (ensure you have run `npm install && npm run rebuild` first):
114+
Start the full demo with all components (ensure you have run `npm install` first):
115115

116116
```bash
117117
# Source ROS2 first
@@ -345,14 +345,14 @@ You can observe the following behavior by:
345345
- Try restarting the Electron application
346346

347347
6. **"electron: not found" or native module errors**
348-
- Make sure you ran `npm run rebuild` after `npm install`
348+
- Make sure ROS 2 is sourced so rclnodejs can match its prebuilt binary (`ROS_DISTRO` must be set; prebuilt binaries are provided for Ubuntu)
349349
- Ensure Node.js version is compatible (20.20.2 or higher)
350-
- Try deleting `node_modules` and running `npm install && npm run rebuild` again
350+
- Try deleting `node_modules` and running `npm install` again; to force a from-source rebuild of rclnodejs set `RCLNODEJS_FORCE_BUILD=1`
351351

352352
7. **"THREE is not defined" or script loading errors**
353353
- Ensure Three.js is properly installed: `npm install three@0.155.0`
354354
- Check that `node_modules/three/build/three.min.js` exists
355-
- If issues persist, try reinstalling: `rm -rf node_modules && npm install && npm run rebuild`
355+
- If issues persist, try reinstalling: `rm -rf node_modules && npm install`
356356

357357
8. **WSL (Windows Subsystem for Linux) specific issues**
358358
- Install audio libraries: `sudo apt install libasound2t64 libasound2-dev`

demo/electron/turtle_tf2/main.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,12 @@
1313
const { app, BrowserWindow, ipcMain } = require('electron');
1414
const rclnodejs = require('rclnodejs');
1515

16+
// Allow WebGL to work on systems without a usable GPU (e.g. WSL2, headless,
17+
// or VMs) where Chromium blocklists hardware WebGL. Without this, the 3D
18+
// renderer fails to create a WebGL context and the visualization cannot start.
19+
app.commandLine.appendSwitch('ignore-gpu-blocklist');
20+
app.commandLine.appendSwitch('enable-unsafe-swiftshader');
21+
1622
let mainWindow;
1723
let turtleTf2Nodes = {};
1824

demo/electron/turtle_tf2/package.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
"main": "main.js",
66
"scripts": {
77
"start": "electron-forge start",
8-
"rebuild": "electron-rebuild",
98
"package": "electron-forge package",
109
"make": "electron-forge make"
1110
},
@@ -42,6 +41,11 @@
4241
"unpack": "**/node_modules/rclnodejs/**"
4342
}
4443
},
44+
"rebuildConfig": {
45+
"ignoreModules": [
46+
"rclnodejs"
47+
]
48+
},
4549
"makers": [
4650
{
4751
"name": "@electron-forge/maker-squirrel",

demo/electron/turtle_tf2/renderer.js

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,27 @@ document.addEventListener('DOMContentLoaded', function () {
5555
versionDiv.innerText = 'Electron: ' + process.versions.electron;
5656
document.body.appendChild(versionDiv);
5757

58-
initializeScene();
59-
setupEventListeners();
60-
setupKeyboardControls();
58+
// Register ROS2 status listeners first so the loading screen always reflects
59+
// initialization progress, even if 3D scene setup fails below.
6160
setupROSListeners();
6261

62+
try {
63+
initializeScene();
64+
setupEventListeners();
65+
setupKeyboardControls();
66+
} catch (err) {
67+
console.error('Failed to initialize 3D scene:', err);
68+
const loadingScreen = document.getElementById('loading-screen');
69+
if (loadingScreen) {
70+
const loadingText = loadingScreen.querySelector('div:last-child');
71+
if (loadingText) {
72+
loadingText.textContent =
73+
'Failed to initialize 3D view (WebGL unavailable): ' + err.message;
74+
loadingText.style.color = '#ff4444';
75+
}
76+
}
77+
}
78+
6379
updateStatus();
6480

6581
// Don't automatically hide loading screen - wait for ROS2 initialization

0 commit comments

Comments
 (0)