Is there a good solution on how to include third party pre compiled binaries like imagemagick into an electron app? there are node.js modules but they are all wrappers or native binding to the system wide installed libraries. I wonder if it's possible to bundle precompiled binaries within the distribution.
Building on the provided answers,
Here's a more concise solution that does not require any external dependencies,
/resources/$os
) where $os
could be mac
, linux
or win
and copy the required binary file there. Lets assume we have a ffmpeg
binary and would like to package it with electron.package.json
and put extraFiles option in your build config as follows: "build": {
"extraFiles": [
{
"from": "resources/${os}", // $os => "mac/linux/win"
"to": "Resources/bin", // for Linux => "resources/bin"
"filter": ["**/*"]
}
],
}
utils.ts
) with a few helper functions// utils.ts
import path from 'path';
import { platform } from 'os';
import { app } from 'electron';
export function getPlatform() {
switch (platform()) {
case 'aix':
case 'freebsd':
case 'linux':
case 'openbsd':
case 'android':
return 'linux';
case 'darwin':
case 'sunos':
return 'mac';
case 'win32':
return 'win';
default:
return null;
}
}
export function getBinariesPath() {
const IS_PROD = process.env.NODE_ENV === 'production';
const { isPackaged } = app;
const binariesPath =
IS_PROD && isPackaged
? path.join(process.resourcesPath, './bin')
: path.join(app.getAppPath(), 'resources', getPlatform()!);
return binariesPath;
}
// "ffmpeg" is the binary that we want to package
export const ffmpegPath = path.resolve(path.join(getBinariesPath(), './ffmpeg'));
main.ts
)// main.ts
import { exec, spawn } from 'child_process';
import { ffmpegPath } from './utils';
// option 1: using exec
exec(`"${ffmpegPath}" -version`, (err, stdout, stderr) => {
console.log('err, stdout, stderr :>> ', err, stdout, stderr);
});
// option 2: using spawn
const ffmpeg = spawn(ffmpegPath, ['-version']);
ffmpeg.stdout.on('data', (data) => {
console.log(`spawn stdout: ${data}`);
});
ffmpeg.stderr.on('data', (data) => {
console.error(`spawn stderr: ${data}`);
});
ffmpeg.on('close', (code) => {
console.log(`spawn child process exited with code ${code}`);
});