Модуль узла require () из процесса рендеринга Electron, обслуживаемого через HTTP

Обычно в приложении Electron вы можете require узловых модулей как из основного процесса, так и из процесса рендеринга:

var myModule = require('my-module');

Однако это не сработает, если страница была загружена через HTTP, а не из локальной файловой системы. Другими словами, если я открою такое окно:

win.loadURL(`file://${__dirname}/index.html`);

Я могу require узел узла без проблем. Но если вместо этого я открою такое окно:

win.loadURL(`http://localhost:1234/index.html`);

Я больше не могу require узловых модулей на своей веб-странице - я получаю Uncaught Error: Cannot find module 'my-module' в консоли веб-страницы. Есть ли способ использовать модули узлов на странице Electron, обслуживаемой через HTTP?


Небольшой контекст: моя компания создает приложение, которое необходимо разместить как веб-приложение и внутри оболочки Electron. Чтобы упростить и согласовать это в обеих средах, мое приложение Electron запускает локальный веб-сервер и открывает приложение, размещенное на http://localhost:1234. Теперь я хотел бы иметь возможность добавлять в приложение проверку орфографии / варианты правописания с помощью electron-spell-check-provider . Этот модуль необходимо импортировать и инициализировать внутри процесса рендеринга, поэтому я пытаюсь require('electron-spell-check-provider') на своей веб-странице, но это не удается с ошибкой Cannot find module.


person Nathan Friend    schedule 07.09.2016    source источник
comment
Я не уверен, но похоже, что версия http получает другие фактические пути к файлам. Попробуйте изменить оператор require следующим образом: = ›require ('./ electronic-spell-check-provider')   -  person Jordi Flores    schedule 07.09.2016
comment
Вы пробовали: require('electron').remote.require('electron-spell-check-provider')?   -  person ahwayakchih    schedule 31.03.2017
comment
Вы в конце концов поняли это? У меня работает remote.require (), но это не всегда хорошее решение. Есть другой способ сделать это?   -  person logidelic    schedule 25.05.2017


Ответы (3)


Наконец разобрался в этом. В основном процессе найдите абсолютный путь к каталогу node_modules, как в:

var nodeModDir = require.resolve('some-valid-module');
var dirnm      = 'node_modules';
var pos = nodeModDir.lastIndexOf(dirnm);
if(pos != -1)
    nodeModDir = nodeModDir.substr(0, pos+dirnm.length+1);

Теперь получите этот путь к процессу рендеринга через какой-нибудь IPC. Наконец, в рендерере теперь вам может потребоваться использовать абсолютный путь:

var mymod = require(nodeModDir+'some-valid-module');

У меня отлично работает с электроном 1.6.7.

person logidelic    schedule 26.05.2017

Вы можете добавить сценарий предварительной загрузки, который добавляет свойство к глобальной переменной / переменной окна. Я назвал свой appRoot. appRoot просто имеет __dirname значение сценария предварительной загрузки. Затем вам нужно перейти из папки сценария предварительной загрузки в свой модуль. Я просто использую path.join(), чтобы очистить его.
Это похоже на подход @ logidelic, но без необходимости возиться с сообщениями IPC.

main.js

mainWindow = new BrowserWindow({
  webPreferences: {
    preload: 'preload.js'
  }
})

preload.js:

global.appRoot = window.appRoot = __dirname

index.html:

<script>
  const { join } = require('path')
  require(join(appRoot, 'rendererApp'))
</script>
person RoyalBingBong    schedule 19.02.2019
comment
это не сработало для меня. это сделало: `` const path = require ('path') const electronic = require ('electronics') const appPath = electronics.remote.app.appPath const usb = require (path.join (appPath, 'node_modules', ' usb ')) `` - person Brandon Ros; 24.07.2020

Была аналогичная проблема. Попробуйте передать renderer.js через HTTP в своем index.html вот так:

  <script src="/renderer.js"></script>
</body>

Затем, согласно документации, загрузите свой модуль. при использовании удаленного добавления после требования в файле renderer.js.

var spellCheck = require('electron-spell-check-provider').remote;

person ndmweb    schedule 17.12.2016
comment
Что будет содержать рендерер? - person Coder; 16.03.2017