empaquetage du binaire précompilé en app électronique

y a-t-il une bonne solution pour inclure des binaires pré-compilés par des tiers comme imagemagick dans une application électronique? il y a de nœud.les modules js mais ce sont tous des wrappers ou des liens natifs pour les bibliothèques installées à l'échelle du système. Je me demande s'il est possible de regrouper des binaires précompilés dans la distribution.

19
demandé sur Toby 2015-10-15 18:27:10

3 réponses

j'ai trouvé une solution à ce problème, mais je ne sais pas si c'est considéré comme une pratique exemplaire. Je n'ai pas pu trouver de bonne documentation pour inclure des binaires précompilés de tiers, donc je l'ai bricolé jusqu'à ce qu'il fonctionne finalement avec mon binaire ffmpeg. Voici ce que j'ai fait (en commençant par le démarrage rapide de l'électron, noeud.js v6):

méthode Mac OS X

à partir du répertoire app J'ai exécuté les commandes suivantes dans le Terminal pour inclure le binaire ffmpeg comme un module:

mkdir node_modules/ffmpeg
cp /usr/local/bin/ffmpeg node_modules/ffmpeg/
cd node_modules/.bin
ln -s ../ffmpeg/ffmpeg ffmpeg

(remplacez /usr/local/bin/ffmpeg avec votre chemin binaire actuel, téléchargez-le d'ici) placer le lien autorisé electron-packager pour inclure le binaire que j'ai sauvé à node_modules/ffmpeg/.

ensuite pour récupérer le chemin de l'application (de sorte que je puisse utiliser un chemin absolu pour mon binaire... les chemins relatifs ne semblaient pas fonctionner quoi que je fasse) j'ai installé le paquet app-root-dir en lançant la commande suivante:

npm i -S app-root-dir

maintenant que j'avais l'application root directory, je viens d'ajouter le sous-dossier pour mon binaire et je l'ai généré à partir de là. C'est le code que j'ai placé dans renderer.js:.

var appRootDir = require('app-root-dir').get();
var ffmpegpath=appRootDir+'/node_modules/ffmpeg/ffmpeg';
console.log(ffmpegpath);

const
    spawn = require( 'child_process' ).spawn,
    ffmpeg = spawn( ffmpegpath, ['-i',clips_input[0]]);  //add whatever switches you need here

ffmpeg.stdout.on( 'data', data => {
     console.log( `stdout: ${data}` );
    });
   ffmpeg.stderr.on( 'data', data => {
console.log( `stderr: ${data}` );
    });

Méthode Windows

  1. ouvrez votre dossier electron base (electron-quick-start est le nom par défaut), puis allez dans le dossier node_modules. Créez un dossier appelé ffmpeg, et copiez votre binaire statique dans ce répertoire. Note: il doit être la version statique de votre binaire, pour ffmpeg j'ai attrapé le dernière version de Windows build ici.
  2. Pour obtenir le logiciel d'application de chemin (pour que je puisse utiliser un chemin absolu pour mon binaire... les chemins relatifs ne semblaient pas fonctionner quoi que je fasse) j'ai installé le paquet app-root-dir en lançant la commande suivante à partir d'une invite de commande dans mon répertoire app:

     npm i -S app-root-dir
    
  3. dans votre dossier node_modules, naviguez vers le .sous-répertoire bin. Vous avez besoin pour créer un couple de fichiers texte ici pour dire noeud pour inclure le fichier binaire exe que vous venez de copier. Utilisez votre éditeur de texte préféré et créez deux fichiers, l'un nommé ffmpeg avec le contenu suivant:

    #!/bin/sh
    basedir=$(dirname "$(echo "" | sed -e 's,\,/,g')")
    
    case `uname` in
        *CYGWIN*) basedir=`cygpath -w "$basedir"`;;
    esac
    
    if [ -x "$basedir/node" ]; then
      "$basedir/node"  "$basedir/../ffmpeg/ffmpeg" "$@"
      ret=$?
    else
      node  "$basedir/../ffmpeg/ffmpeg" "$@"
      ret=$?
    fi
    exit $ret
    

    et le second fichier de texte, nommé ffmpeg.cmd:

    @IF EXIST "%~dp0\node.exe" (
     "%~dp0\node.exe"  "%~dp0\..\ffmpeg\ffmpeg" %*
    ) ELSE (
       @SETLOCAL
     @SET PATHEXT=%PATHEXT:;.JS;=;%
     node  "%~dp0\..\ffmpeg\ffmpeg" %*
    )
    

ensuite, vous pouvez exécuter ffmpeg dans votre distribution Windows electron (dans renderer.js) comme suit (j'utilise aussi le module app-root-dir node). Notez les guillemets ajoutés au chemin binaire, si votre application est installée dans un répertoire avec des espaces (par exemple C:\Program Files\YourApp) ça ne marchera pas sans ça.

var appRootDir = require('app-root-dir').get();
var ffmpegpath = appRootDir + '\node_modules\ffmpeg\ffmpeg';

const
    spawn = require( 'child_process' ).spawn;
    var ffmpeg = spawn( 'cmd.exe', ['/c',  '"'+ffmpegpath+ '"', '-i', clips_input[0]]);  //add whatever switches you need here, test on command line first
ffmpeg.stdout.on( 'data', data => {
     console.log( `stdout: ${data}` );
 });
ffmpeg.stderr.on( 'data', data => {
     console.log( `stderr: ${data}` );
 });
10
répondu UltrasoundJelly 2017-05-31 16:40:15

Voici une autre méthode, testée avec Mac et Windows jusqu'à présent. Nécessite des "app-root-dir' package, ne requiert pas d'ajouter quoi que ce soit manuellement à node_modules dir.

  1. mettez vos fichiers sous ressources/$os/ $ os"mac","linux", ou "gagner". Le processus de compilation copie les fichiers à partir de ces répertoires selon l'OS cible de compilation.

  2. extraFiles option dans votre construction configs comme suit:

paquet.json

  "build": {
    "extraFiles": [
      {
        "from": "resources/${os}",
        "to": "Resources/bin",
        "filter": ["**/*"]
      }
    ],
  1. Utiliser quelque chose comme ceci pour déterminer la plate-forme actuelle.

obtenir la plate-forme.js

import { platform } from 'os';

export default () => {
  switch (platform()) {
    case 'aix':
    case 'freebsd':
    case 'linux':
    case 'openbsd':
    case 'android':
      return 'linux';
    case 'darwin':
    case 'sunos':
      return 'mac';
    case 'win32':
      return 'win';
  }
};
  1. appeler l'exécutable depuis votre application en fonction de l'env et de L'OS. Ici, je suppose que les versions construites sont en mode production et les versions source dans d'autres modes, mais vous pouvez créer votre propre appel logique.
import { join as joinPath, dirname } from 'path';
import { exec } from 'child_process';

import appRootDir from 'app-root-dir';

import env from './env';
import getPlatform from './get-platform';

const execPath = (env.name === 'production') ?
  joinPath(dirname(appRootDir.get()), 'bin'):
  joinPath(appRootDir.get(), 'resources', getPlatform());

const cmd = `${joinPath(execPath, 'my-executable')}`;

exec(cmd, (err, stdout, stderr) => {
  // do things
});

je pense que j'ai été en utilisant électron-builder en tant que base, la génération de fichiers env est fournie avec elle. En gros, c'est juste un fichier de configuration JSON.

8
répondu tsuriga 2017-07-24 02:28:48

tl; dr:

oui, vous pouvez! mais il exige que vous écriviez votre propre addon autonome qui ne fait aucune supposition sur les bibliothèques système. D'ailleurs, dans certains cas, vous devez vous assurer que votre addon est compilé pour l'exploitation désiré.


brisons cette question en plusieurs parties:

- Addons (modules Natifs):

les Addons sont dynamiquement liés et partagés objet.

en d'autres termes, vous pouvez simplement écrire votre propre addon sans dépendance sur les bibliothèques du système (par exemple en liant statiquement les modules requis) contenant tout le code dont vous avez besoin.

vous devez considérer qu'une telle approche est spécifique à L'OS, ce qui signifie que vous devez compiler votre addon pour chaque OS que vous voulez prendre en charge! (selon les autres bibliothèques que vous pouvez utiliser)

- modules natifs pour électron:

les modules de noeuds natifs sont supportés par Electron, mais puisque Electron utilise une version V8 différente du noeud officiel, vous devez spécifier manuellement l'emplacement des en-têtes D'électron lors de la construction des modules natifs

cela signifie qu'un module natif qui a été construit contre des en-têtes de noeuds doit être reconstruit pour être utilisé à l'intérieur de l'électron. Vous pouvez trouver comment dans les docs électroniques.

- modules de faisceau avec électron app:

je suppose que vous voulez avoir votre application comme un exécutable autonome, sans avoir à installer d'électrons sur leurs machines. Si oui, je peux suggérer à l'aide de électron-emballeur.

6
répondu Yan Foto 2015-10-20 17:29:05