Загрузка Nodejs модуля во время выполнения в электронном приложении - PullRequest
1 голос
/ 16 июня 2020

В настоящее время я играю с electron, используя vue-cli-plugin-electron-builder вместе с простым проектом vue. Это проект https://github.com/nklayman/vue-cli-plugin-electron-builder.

   vue create my-project
   cd my-project
   vue add electron-builder
   npm run electron:serve

Моя цель - добавить простую архитектуру, подобную плагинам. Приложение выполняет только базовую функциональность, но может быть расширено с помощью «плагинов». Следовательно, эти плагины не включены в сборку, но будут загружены во время выполнения электронным. Я бы предпочел, чтобы эти плагины просто вели себя как модули узлов (module.exports =) со своими собственными зависимостями (возможно, с файлом package. json внутри). Я бы нашел эти плагины в app.getPath('userData') + '/Plugins.

Я рассмотрел несколько подходов к решению этой проблемы:


1. Использование модуля Nodejs vm

Сначала я попытался использовать модуль Nodejs vm для чтения и выполнения скрипта из внешнего файла во время выполнения. Пока он отлично работает, хотя я не смог бы использовать внешние зависимости внутри этих загруженных скриптов. Если я хочу использовать внешние зависимости внутри скриптов плагина, эти зависимости должны быть заранее включены в электронную сборку. Как-то побеждает всю цель наличия плагинов ... возможны только базовые модули vanilla js + nodejs.


2. используя global.require

Я видел это решение в другом ответе SO.

Они говорят использовать global.require, но выдает ошибку global.require is not a function. Решение сначала выглядело многообещающим, но почему-то я не могу заставить его работать.


3. просто используйте require

Конечно, мне пришлось попробовать. Когда я пытаюсь require внешний модуль из не-проекта местоположения, он не может найти модуль, даже если путь правильный. Опять же, путь, по которому я пытаюсь найти модуль, должен находиться в app.getPath("userData"), а не в каталоге проектов root. Однако когда я нахожу плагины внутри каталога root проекта, он включается в сборку. Это снова противоречит цели наличия плагинов.


Цель

Пока я не нашел жизнеспособного решения этой проблемы. Я просто хочу, чтобы мое электронное приложение было расширяемым с помощью модулей базовых c узлов во время выполнения (для упрощения следуя заранее определенной схеме). Конечно, есть atom, созданный с помощью электронов, использующий собственный apm менеджер для установки и загрузки плагинов, но это кажется слишком сильным. Для меня достаточно иметь только файлы плагинов, расположенные локально, создание publi c "торговой площадки" не является целью. Кроме того, это нормально, если приложение должно перезагружаться / перезапускаться для загрузки плагинов.

Есть идеи?

1 Ответ

2 голосов
/ 16 июня 2020

После все большего количества исследований я наткнулся на 2 пакета:

оба интегрируют npm для программной обработки установки пакета во время выполнения. Я остановился на live-plugin-manager, так как он лучше документирован и даже позволяет установку пакетов из локальной файловой системы.

Pro

Мне удалось интегрировать систему прямо из коробки в приложение vanilla electronic. Работает как шарм.

Минусы

. Я не смог использовать его внутри шаблона vue electron (вроде того, который, как я сказал, я использовал в OP), поскольку веб-пакет мешает require среда. Но у этого есть решение.

Обновление : мне удалось заставить его работать в конечном итоге внутри связанного с веб-пакетом электронного vue шаблона. Я случайно перепутал import и require. Следующий код работает для меня с использованием live-plugin-manager

// plugin-loader.js
const path = require('path');
const { PluginManager } = require('live-plugin-manager');
const pluginInstallFolder = path.resolve(app.getPath('userData'), '.plugins');
const pluginManager = new PluginManager();

module.exports = async (pkg) => {
  // installs pkg from npm
  await pluginManager.install(pkg);
  const package = pluginManager.require(pkg);
  return package
}
// main.js
const pluginLoader = require('./plugin-loader');
pluginLoader("moment").then((moment) => {
   console.log(moment().format());
})

. Это установит «моментальный» пакет из npm во время выполнения в локальный каталог и загрузит его в приложение, не связывая его с исполняемые файлы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...