Electron: Требование электрона вне main.js вызывает TypeError

Созданный на 22 сент. 2016  ·  82Комментарии  ·  Источник: electron/electron

  • Электронная версия: 1.3.5
  • Операционная система: Mint 17

Привет

Я использую Electron с React.js и babelify среди других плагинов (список внизу).
Попытка использовать require('electron') , например, для получения доступа к BrowserWindow электрона, приводит к тому, что консоль показывает следующую ошибку:
index.js:4 Uncaught TypeError: fs.readFileSync is not a function

Однако я могу использовать const electron = require('electron'); в main.js. Что бы это ни стоило, я также использую watchify, чтобы упаковать все в пакет js.

Вот полный список зависимостей в моем package.json:

"devDependencies": {
        "axios": "^0.9.1",
        "babel-preset-es2015": "^6.6.0",
        "babel-preset-react": "^6.5.0",
        "babelify": "^7.2.0",
        "classnames": "^2.2.3",
        "electron": "^1.3.5",
        "electron-reload": "^0.2.0",
        "jquery": "^2.2.3",
        "react": "^0.14.8",
        "react-autocomplete": "^1.0.0-rc2",
        "react-dom": "^0.14.7",
        "react-sound": "^0.4.0",
        "soundmanager2": "^2.97.20150601-a"
    },
blockeneed-info ❌

Самый полезный комментарий

Для тех, кто столкнется с этой проблемой в будущем и читает эту ветку, использование window.require вместо require является одной из возможностей избежать конфликта между функциями электрона и браузера require .

Все 82 Комментарий

index.js:4 Uncaught TypeError: fs.readFileSync не является функцией

Можете ли вы включить сюда строку 4 из index.js ? Или более полная трассировка стека?

Я полагаю, что это относится к index.js электрона, который сам находится в узлах-модулях проекта. Вот содержимое этого файла:

var fs = require('fs')
var path = require('path')

module.exports = path.join(__dirname, fs.readFileSync(path.join(__dirname, 'path.txt'), 'utf-8'))

Вся трассировка стека указывает на конфликт с React.js:

Stack trace

Что произойдет, если вы запустите require('fs').readFileSync на вкладке «Консоль» инструментов разработчика?

Похоже, что модуль узла electron-prebuilt (файл, который вы вставили) оказывается в вашем упакованном приложении, что, я не думаю, вам нужно, поскольку вместо этого он должен использовать встроенный electron require.

@nukeop Как вы запускаете свое приложение? Ваш стартовый скрипт должен выглядеть так.

"scripts": {
  "start": "electron ."
}

У меня такое чувство, что вы пытаетесь запустить свой main.js с узлом

node main.js

Что не сработает

Что произойдет, если вы запустите require('fs').readFileSync на вкладке "Консоль" инструментов разработчика?

Сразу после появления этой ошибки я могу запустить require('fs').existsSync в консоли, чтобы распечатать определение функции. Тоже работает до ошибки.

Похоже, что предварительно собранный электронный модуль узла (файл, который вы вставили) оказывается в вашем упакованном приложении, что, я не думаю, вам нужно, поскольку вместо этого он должен использовать встроенный электронный запрос.

У меня есть экземпляр watchify, работающий в фоновом режиме, когда я разрабатываю, который постоянно обновляет мой пакет. Я определил его в разделе сценариев package.json следующим образом:

"watch": "watchify app/app.js -t babelify -o public/js/bundle.js --debug --verbose"

Любой совет, как избежать связывания electron-prebuilt ?

@nukeop Electron поддерживает внутреннюю поддержку, поэтому вам не нужно использовать браузер.

Насколько мне известно, если вы хотите использовать браузер, вы должны исключить «электрон».

Интересно, может быть, watchify/browserify все портит? До сих пор это работало нормально.

Теперь я не уверен, как запустить программу без него.

Буквально просто беги

electron .

Из вашей основной папки приложения вам не нужно ничего связывать при использовании Electron, так как он имеет внутреннюю среду полного узла.

_Я собираюсь закрыть это, так как это проблема Browserify_

Это то, что я делал все это время, упаковывая программу в один файл .js, который включается в простой файл html с:

  <script src="public/js/bundle.js">
  </script>

И все работает, за исключением случаев, когда я использую require. Это проблема взаимодействия между двумя модулями.

Если я не упакую всю программу в пакет, у меня не будет простого способа ее запустить, так как мой main.js только запускает электрон и загружает html-файл, который включает пакет.

@nukeop Процесс рендеринга внутри Electron также имеет доступ к полной среде node/commonjs, поэтому вам не нужно ничего связывать.

Если я не упакую всю программу в пакет, у меня не будет простого способа ее запустить, так как мой main.js только запускает электрон и загружает html-файл, который включает пакет.

Я не уверен, что понимаю здесь, любой скрипт, который вы загружаете в свой HTML-файл, имеет полную среду commonjs и поэтому может использовать require для загрузки дополнительных файлов без каких-либо браузеров.

Для тех, кто столкнется с этой проблемой в будущем и читает эту ветку, использование window.require вместо require является одной из возможностей избежать конфликта между функциями электрона и браузера require .

FWIW, я столкнулся с той же проблемой, пытаясь использовать электрон в процессе рендеринга с приложением create-реагировать, которое использует веб-пакет в бэкэнде вместо браузера. window.require , кажется, тоже решает это для меня, хотя я не совсем понимаю, почему.

Изменить : я понял, почему :-) Мы хотим require electron во время выполнения из среды nodejs, предоставляемой во время выполнения, а не из среды nodejs, используемой во время компиляции веб-пакетом. По умолчанию глобальные переменные привязаны к window , а компиляция веб-пакета игнорирует глобальную переменную window — следовательно, window.require работает.

Другой способ заставить webpack игнорировать глобальное имя — использовать комментарий вроде /*global Android*/ в JS-файле. В другом проекте, использующем приложение, созданное CRA, в Android WebView, я использовал описанное выше, чтобы получить доступ к объекту Java, доступному для JS, через интерфейс JavaScript, предоставляемый Webview.

@nukeop - спасибо за ваш последний пост; Это мне очень помогло. window.require сработало для меня.

да, исправлена ​​моя проблема с созданием приложения / веб-пакета.
изменять

import electron, { ipcRenderer } from 'electron'

к

const electron = window.require("electron")

@srinathh , как вы выставляете / загружаете свое приложение CRA в качестве средства визуализации в своем основном? вы строите сначала (и изменяете пути статических ресурсов html)

Да, мой рабочий процесс в настоящее время заключается в том, чтобы в основном запускать npm run build с помощью сценариев CRA, а затем запускать вывод в папке build с помощью электрона. Вам не нужно вручную изменять пути к статическим ресурсам. В сценариях package.json для CRA вам просто нужно установить homepage таким образом, и пути будут установлены соответствующим образом.

    "homepage": "./"

Кроме того, у меня есть main.js и package.json для электронного приложения в папке public . Таким образом, запуск сборки автоматически копирует их, и вы можете просто запустить electron build/ , чтобы запустить свое приложение.

На самом деле я хотел бы иметь возможность делать npm start с электроном для разработки, но я так и не понял, как это сделать. Я предполагаю, что мне придется сделать eject и изменить сценарий вручную.

Если вы хотите увидеть пример настройки — посмотрите https://github.com/srinathh/snippetfu .

Я использую не Electron, а Node-Webkit (nw.js).
Использование window.require также решило мою проблему. Большое спасибо за это!

@nukeop window.require помог и мне, большое спасибо! 🎉

@nukeop У меня такая же ошибка, но она решена с помощью трюка window.require, большое спасибо!

window.require действительно решил проблему fs.existsSync is not a function , но привел к другой ошибке: window.require не является функцией. Как мне это решить?

@steric85 вы используете браузер, бабел или веб-пакет? вам может понадобиться транспилировать ваш код

@Alxmerino Я использую веб-пакет.

убедитесь, что вы компилируете свой код

@steric85 steric85 , я столкнулся с window.require is not a function в машинописном тексте, мне удалось исправить это следующим образом:

declare global {
  interface Window {
    require: any;
  }
}

const electron = window.require('electron');

Я использую описанный выше метод для доступа к ipcRenderer из электрона в моем приложении Angular, но обнаружение изменений Angular не работает, когда я обновляю Observable с помощью обработчика сообщений ipcRenderer.
Это потому, что Angular не знает, что ipcRenderer является EventEmitter и что ему нужно запускать обнаружение изменений, когда приходят события ipcRenderer?

в Angular 2 я вызывал applicationRef.tick() , чтобы явно указать angular обновить свое состояние. https://angular.io/api/core/ApplicationRef

Я столкнулся с проблемой, очень похожей на @nukeop и @srinathh : я настроил свой проект Electron + React + Webpack, следуя этому руководству по статье , где автор в конце упоминает трюк с window.require . Я только require('electron') два места в моем проекте; в точке входа для Electron и в классе контроллера JavaScript, который требуется для некоторых компонентов React. В моем файле точки входа Electron я просто делаю const electron = require('electron'); , так как он должен работать в основном процессе (правильно?), а в моем классе контроллера я делаю const Electron = window.require('electron').remote; , за которым следует const Jsonfile = Electron.require('jsonfile'); , что и должно быть способом сделать это, поскольку он выполняется в процессе рендеринга. Но я получаю ту же ошибку, что и @nukeop ("TypeError: fs.ExistsSync не является функцией") в шестой строке в node_modules/electron/index.js, которая выглядит так:

var fs = require('fs')
var path = require('path')

var pathFile = path.join(__dirname, 'path.txt')

if (fs.existsSync(pathFile)) {
  module.exports = path.join(__dirname, fs.readFileSync(pathFile, 'utf-8'))
} else {
  throw new Error('Electron failed to install correctly, please delete node_modules/electron and try installing again')
}

Я попытался удалить node_modules/electron и снова установить.
Я использую Electron 1.7.5 на macOS 10.12.6 и запускаю свой проект, используя npm run dev в качестве настройки, описанной в статье.

Обновлять; Я нашел require , вызвавший мою ошибку, я попытался сделать require('electron-react-devtools') в своем React index.js. Изменение его на const ReactDevtools = Electron.require('electron-react-devtools'); остановило ошибки, но теперь кажется, что я не могу вызвать .inject() в экземпляре ReactDevtools («это не функция»), но это может не обсуждаться здесь .

@steric85 Это потому, что вы запускаете приложение в среде веб-страницы => вы должны запускать приложение в среде Electron (среда Nodejs)

  • require('electro') => Webpack свяжет электронный модуль с bundle.js => электрон использует модуль fs => Webpack не понимает
  • window.require('electro') => Webpack будет игнорировать функцию запроса
  • В среде веб-страницы window.require будет неопределенным.
  • В среде nodejs будет работать window.require
    => Откройте свое приложение в окне Electron (не в окне браузера, например Chrome, Firefox и т. д.).

Я все еще получаю window.require is not a function . Я использую Electron с React Starter Kit (https://github.com/kriasoft/react-starter-kit). Все работает хорошо, кроме этого.

Я настроил свое приложение Electron для загрузки моего приложения из Интернета, поэтому приложение не работает локально:
https://gist.github.com/holgersindbaek/68f6db82f507967a51ca75c527faeff6

Что я пытаюсь сделать, так это вызвать ipcRenderer в одном из моих файлов React. Я не уверен, возможно ли это вообще, когда мое приложение загружается из Интернета. Какие-либо предложения?

@holgersindbaek Вы не должны просматривать свое приложение в браузере, таком как Chrome, Firefox и т. Д. Оно не будет работать, потому что это среда веб-страницы.
Вы должны просматривать свое приложение в окне Electron.

Да, но я использую Electron таким образом, что загружаю свое приложение с веб-сайта при каждом запуске. По сути, я показываю веб-сайт в своем электронном приложении. См. вышеуказанный файл. Я просто хочу убедиться, что я действительно ничего не могу сделать?!

Electron может загружать любые URL-адреса. Чтобы загрузить URL-адрес, вы должны использовать эту функцию mainWindow.loadURL(url)
=> В электронном окне этот URL-код javascript может получить доступ к require, ipc и т. д.

В порядке. Я попробую это.

window.require на электроне не сработало, но window.require на fs сработало.

Не совсем уверен, почему. Но это работает, и, поскольку это небольшой личный проект, я не собираюсь настаивать на этом.

Спасибо @nukeop

Привет, это мой package.json, я использую webpack, ни один из них не решил мою проблему, есть ли у кого-нибудь решение? После того, как я использую window.require, я получил ошибку «окно не определено»

'использовать строгий';

var электрон = требуется('электрон')
вар приложение = электрон.приложение;
var BrowserWindow = electronic.BrowserWindow;
вар основное окно = ноль;

app.on('готово', функция() {
mainWindow = новое окно браузера ({ширина: 800, высота: 600});

mainWindow.loadURL('file://' + __dirname + '/index.electron.html');

mainWindow.webContents.openDevTools();

});

Я использую машинопись, и мне пришлось использовать

const electron = (<any>window).require("electron");

чтобы мой рендерер мог общаться с моим main. Надеюсь, это поможет кому-то.

Это сработало для меня.
Например, если вы хотите потребовать удаленный доступ, то

объявить константное окно: любое;
const {удаленный} = window.require('электрон');

Привет, спасибо, чувак.

Вс, 3 декабря 2017 г., 21:29, Michael - ሚካኤል ሰልጠነ <
уведомления@github.com> написал:

Это сработало для меня.
Например, если вы хотите потребовать удаленный доступ, то

объявить константное окно: любое;
const {удаленный} = window.require('электрон');


Вы получаете это, потому что вы прокомментировали.
Ответьте на это письмо напрямую, просмотрите его на GitHub
https://github.com/electron/electron/issues/7300#issuecomment-348801405 ,
или заглушить тему
https://github.com/notifications/unsubscribe-auth/ARDyd4c3aOkMbb058xklujMMbnmaoxKGks5s8uGVgaJpZM4KDU6t
.

@solominh Спасибо за ваши объяснения здесь . Однако у меня такая же конфигурация, как у @holgersindbaek , какая среда является сценарием предварительной загрузки в веб-просмотре?

Информация:

  • Моя электронная запись работает mainWindow.loadURL(url) , где URL-адрес — это локальный index.html.
  • Этот index.html имеет <webview>
  • В веб-просмотре есть поле preload , которое загружает inject.js, и этот скрипт выполняет window.require('electron').

Примечания:

  • Если я использую const electron = require('electron') , у меня возникает ошибка fs.readFileSync is not a function
  • Если я использую const electron = window.require('electron') , у меня возникает ошибка window.require is not a function .
  • inject.js поставляется через веб-пакет (можно вставить конфигурацию, если это необходимо).

РЕДАКТИРОВАТЬ: Решено для меня с помощью <webview nodeintegration="true"> и window.require. Оставив записку здесь для дальнейшего использования.

window.require сработало для меня! Спасибо, парни!

https://imgur.com/a/ekWwD

сообщение об ошибке в браузере, когда я попробовал это

Забыл вернуть nodeIntegration: false , что отключает даже window.require().. . глупая ошибка. Надеюсь, это избавит кого-то от часа исследований.

@phil294 Спасибо, чувак! вы действительно сэкономили час исследований.

Привет @micsel ,
Я включил объявление const window: any;
но выдает синтаксическую ошибку.
Есть идеи, почему?

Я, поставь объявлять const window: any; вверху, сразу после импорта.

Если вы получаете, что window.require не является функцией, и вы используете Angular-CLI, используйте следующее для создания экземпляра интерфейса Window:

./src/typings.d.ts

declare var window: Window;
interface Window {
    require: any;
}

Затем вы можете использовать это, чтобы включить электрон:
const { ipcRenderer } = window.require('electron');

если вы используете angular 2+ в электронном приложении, импортируйте библиотеку «ngx-electron» и используйте ее в any.componets.ts.

import { ElectronService } from 'ngx-electron';

//constructor
constructor(
    private elt: ElectronService
  ){
  var fs = this.elt.remote.require('fs');
}

Я использую реакцию js с электроном, и когда я запускаю эту строку в терминальный запуск запуска пряжи, она выдает мне ошибку Uncaught Type Error: window.require не является функцией, я не использую машинописный текст, как объявить окно в React Js

Люди, которые все еще сталкиваются с проблемой, каким-то образом выполнение window.require() нарушает согласованность использования операторов import в кодовой базе. Простая альтернатива — установить для веб-пакета target значение electron-renderer . Если вы используете приложение Create React , извлечение может привести к беспорядку. Следовательно, вы можете использовать этот пакет, который подключает веб-пакет за вас, и вы можете использовать, например, import fs from 'fs' в своих компонентах React (или любом другом модуле node), счастливо в своей жизни :)

В Windows с Vue CLI 3, window.require будет работать, но потребует полного пути вместо относительного пути из «node_modules/».

Но, как и в случае с React, веб-пакет можно правильно настроить для Vue, отредактировав vue.config.js. «Требовать» будет работать как положено.

vue.config.js:

module.exports = {
    configureWebpack: config => {
      if (process.env.NODE_ENV === 'production') {
        config.output.publicPath = `${process.cwd()}/dist/`
      }
      config.target = 'electron-renderer'
    }
  }

router.js (это просто пример, он будет работать в любом другом файле vue js)

const Store = require("electron-store");
const store = new Store();

_Я почти не хочу добавлять это, но это сэкономило бы мне час или два отладки._

Мне пришлось rm -rf node_modules && npm install решить эту проблему. Затем я смог удалить window из window.require , и все снова заработало. Надеюсь, это поможет кому-то еще.

@cperthuis Я просто хочу сказать СПАСИБО!! Ха-ха, я даже не использую Vue, но логическое мышление привело меня к выводу, что я могу изменить свой webpack.config.js, чтобы иметь целевое свойство :)
image
РАБОТАЕТ КРАСИВО.

Привет,

window.require работает в среде локального сервера разработки, но не работает в рабочей среде после сборки приложения React в уменьшенный HTML-файл.

function createWindow() {
  win = new BrowserWindow({
    width: 1280,
    height: 720,
    icon: path.join(__dirname, 'assets/icons/png/64x64.png'),
    webPreferences: {
      nodeIntegration: true,
      preload: __dirname + '/preload.js'
    }
  })

  win.setPosition(0, 0)

  win.loadURL(isDev ? 'http://localhost:3000' : `file://${path.join(__dirname, 'build/index.html')}`)
}

Он работает с localhost:3000 но не с file://${path.join(__dirname, 'build/index.html')}

https://imgur.com/EE7jxZq

@cperthuis , ваше исправление сработало для неизвлеченного приложения CRA с использованием «react-app-rewired». Спасибо.
image

С Create-React-App 2 вы можете использовать модуль craco npm:

https://www.npmjs.com/package/@craco/craco

Измените react-scripts на craco в вашем package.json

craco.config.js

module.exports = {
    webpack: {
        configure: {
            target: 'electron-renderer'
        }
    }
};

И у вас будет доступ к вашему контексту Electron следующим образом:

import Electron from 'electron';
const { dialog } = Electron.remote;

@Maxou44, спасибо за совет о craco и электроне. Это как раз то, что мне было нужно. Если кто-то ищет пример...

https://github.com/wwlib/craco-electron-пример

@wwlib Нет проблем, рад видеть, что это помогло вам 🥳

Забыл вернуть nodeIntegration: false , что отключает даже window.require().. . глупая ошибка. Надеюсь, это избавит кого-то от часа исследований.

Большое спасибо.

Обратите внимание, что если вы загружаете удаленный контент, важно установить для параметра nodeIntegration значение false: https://electronjs.org/docs/tutorial/security#2 -disable-nodejs-integration-for-remote. -содержание

Привет,
У меня такая же ошибка. При использовании window.require ошибка Uncaught TypeError: fs.readFileSync is not a function исправлена, но я столкнулся с другой ошибкой Uncaught TypeError: window.require is not a function .

Есть ли какие-либо предложения о том, как это исправить. Я использую браузер на узле js.

Для тех, кто все еще застрял на этом: вы получите ошибку window.require is not a function , если вы явно не объявите nodeIntergation как true при объявлении своего BrowserWindow :

new BrowserWindow({
    webPreferences: {
      nodeIntegration: true,
    }
});

Единственное достаточно хорошее решение, которое я нашел, следующее:

  1. установить как пакет зависимостей разработчика react-app-rewired
  2. Используйте этот модуль для внедрения пользовательской конфигурации Webpack без eject -ing CRA:
 "scripts": {
   ...
    "start": "react-app-rewired start",
  },
  1. и добавьте файл config-overrides.js с соответствующим содержимым:
module.exports = function override (config, env) {
  config.target = 'electron-renderer'
  return config;
}

Спасибо: комментарию @Lilanga, комментарию @agrublev и создателям react -app-rewired .

Обновлено:
Собственно 2-я версия как сделать то же самое: https://www.codementor.io/randyfindley/how-to-build-an-electron-app-using-create-react-app-and-electron-builder-ss1k0sfer

Обновлено2:
@nukeop Я удалил некоторые вводящие в заблуждение утверждения из-за нехватки времени, чтобы следить за дебатами о том, почему не использовать Browserify или почему его использовать, и не могу сейчас записать подробное объяснение того, что я имел в виду. Но я сохраню личное мнение относительно того, что «просто используйте window.require , чтобы решить проблему» кажется очень ненадежным.

Неправильно как?

Это приложение React, которое должно работать внутри среды Electron, а не наоборот.

Какие?

_Я почти не хочу добавлять это, но это сэкономило бы мне час или два отладки._

Мне пришлось rm -rf node_modules && npm install решить эту проблему. Затем я смог удалить window из window.require , и все снова заработало. Надеюсь, это поможет кому-то еще.

Вау.. Перепробовал ВСЕ в этой теме и пропустил ваш повтор, потому что нет голосов.. Все еще получил window is not a function ..
удалил и переустановил node_modules и все заработало.

PS: вам все еще нужно сделать все решения, но если вы все сделали
и все равно переустановить node_modules

Ты спас мой день , @joshuapinter !

Используя приложение response-create-app, я обнаружил те же ошибки.
Решение до сих пор было:
const electron = window.require("electron") в электронной части BrowserWindow добавьте nodeIntegration:true следующим образом.
mainWindow = new BrowserWindow({ width: 900, height: 680, webPreferences: { webSecurity: false, nodeIntegration: true } });

Единственное достаточно хорошее решение, которое я нашел, следующее:

  1. установить как пакет зависимостей разработчика react-app-rewired
  2. Используйте этот модуль для внедрения пользовательской конфигурации Webpack без eject -ing CRA:
 "scripts": {
   ...
    "start": "react-app-rewired start",
  },
  1. и добавьте файл config-overrides.js с соответствующим содержимым:
module.exports = function override (config, env) {
  config.target = 'electron-renderer'
  return config;
}

Спасибо: комментарию @Lilanga, комментарию @agrublev и создателям react -app-rewired .

Обновлено:
Собственно 2-я версия как сделать то же самое: https://www.codementor.io/randyfindley/how-to-build-an-electron-app-using-create-react-app-and-electron-builder-ss1k0sfer

Обновлено2:
@nukeop Я удалил некоторые вводящие в заблуждение утверждения из-за нехватки времени, чтобы следить за дебатами о том, почему не использовать Browserify или почему его использовать, и не могу сейчас записать подробное объяснение того, что я имел в виду. Но я сохраню личное мнение относительно того, что «просто используйте window.require , чтобы решить проблему» кажется очень ненадежным.

Это сработало для меня. Спасибо

Проблема с window.require в том, что он работает только для пакета верхнего уровня.
например, если я использую fs напрямую, это работает. Но если я использую пакет, который зависит от fs , я все равно получаю исключение.

window.require у меня не работает, когда я вызываю функцию внутри приложения React. Я получил «TypeError: window.require не является функцией».

App.js :
```javascript
импортировать React, {useEffect, useState} из 'реагировать';
импортировать './App.css';

const ipcRenderer = window.require('электрон').ipcRenderer;

приложение функции () {

useEffect( () => {

    ipcRenderer.on('ping', (event, message) => { console.log(message) });

}, []);

return (
<div className = 'App'>
    <div className = 'Header-Arrow'></div>
    <div className = 'Box'>
        <p>Press ⌘ + ⇧ + 4</p>
    </div>
</div>
);

}

экспортировать приложение по умолчанию;
````

Переменная главного окна на Main.js :
```javascript
// Создаем окно браузера.
mainWindow = новое окно браузера({
всегдаВверху: правда,
кадр: ложный,
полноэкранный: ложь,
прозрачный: правда,
titleBarStyle: 'customButtonsOnHover',
показать: ложь,
ширина: 300,
высота: 350,
веб-настройки: {
интеграция узла: правда,
предварительная загрузка: __имя_каталога + '/preload.js'
}
});

``` ** Preload.js`**:

javascript window.ipcRenderer = require('electron').ipcRenderer;

Что мне не хватает?

Итак, проблема решена. Я отвечаю сам себе, потому что, возможно, кому-то это может быть полезно (я застрял на несколько часов). Если у вас есть файл Preload.js , вам не нужно снова вызывать window.require('electron').ipcRenderer из Àpp.js (рендерера); вы вызываете переменную напрямую как window.ipcRenderer следующим образом:

App.js :

````javascript
импортировать React, {useEffect, useState} из 'реагировать';
импортировать './App.css';

приложение функции () {

useEffect( () => {

    window.ipcRenderer.on('ping', (event, message) => { console.log(message) });

}, []);

return (
<div className = 'App'>
    <div className = 'Header-Arrow'></div>
    <div className = 'Box'>
        <p>Press ⌘ + ⇧ + 4</p>
    </div>
</div>
);

}

экспортировать приложение по умолчанию;
````

Переменная главного окна на Main.js :
javascript // Create the browser window. mainWindow = new BrowserWindow({ alwaysOnTop: true, frame: false, fullscreenable: false, transparent: true, titleBarStyle: 'customButtonsOnHover', show: false, width: 300, height: 350, webPreferences: { nodeIntegration: true, preload: __dirname + '/preload.js' } });
Preload.js :

javascript window.ipcRenderer = require('electron').ipcRenderer;

После запуска приложения из командной строки окно, сгенерированное процессом React, выдаст ошибку (ipcRenderer не определен). Игнорируй это. Окно, сгенерированное процессом Electron (основное приложение), будет работать нормально.

С Create-React-App 2 вы можете использовать модуль craco npm:

https://www.npmjs.com/package/@craco/craco

Измените react-scripts на craco в вашем package.json

craco.config.js

module.exports = {
    webpack: {
        configure: {
            target: 'electron-renderer'
        }
    }
};

У меня были проблемы, когда require("fs") а также window.require("fs") . Спасибо @Maxou44 за представление CRACO в этом обсуждении.

Чтобы решить проблему, я внес 3 изменения в свой проект:

  1. Использовал CRACO, как предложил @Maxou44.
  2. В public/main.js (некоторые могли назвать этот файл как electronic.js) изменено
    new BrowserWindow({ width: 1200, height: 800 })
    к
    new BrowserWindow({ width: 1200, height: 800, webPreferences: { nodeIntegration: true } })
  3. Заменены const fs = require("fs") на const fs = require("electron").remote.require("fs")

Обратитесь к этому репозиторию git от @wwlib для получения дополнительных разъяснений https://github.com/wwlib/cra-craco-electron-example

Прочитал всю ветку сверху донизу, ничего не помогло.
ЗА ИСКЛЮЧЕНИЕМ, метод @Saroopashree выше. Спасибо @Saroopashree за то, что поделились решением.
Я думаю, поскольку реакция и веб-пакет несколько изменились с начала потока, приведенные выше решения устарели. Я могу ошибаться, конечно, но использование вышеуказанного метода сработало.
Вот что я сделал:

  1. Пробежал npm install craco -D
  2. Создайте файл конфигурации craco.config.js и вставьте следующий код
    module.exports = { webpack: { configure: { target: 'electron-renderer' } } };
  3. Обновлен new BrowserWindow({ width: 1200, height: 800, webPreferences: { nodeIntegration: true } }) в main.js. Конечно, с разной шириной и высотой.
  4. Запустил npm start , чтобы запустить сервер разработки для реагирующего приложения, созданного с помощью create-реагировать-приложение. Это открыло вкладку с теми же ошибками. И я снова почувствовал усталость.
  5. Запустил npm run electron для запуска электронного приложения.
    И Виола!!! Я смог просмотреть страницу.

Так что спасибо @Saroopashree.

Если вы пытаетесь получить доступ к «электрону» или другому его компоненту внутри компонента/класса реакции, попробуйте следующее: #336757899

Спасибо @tumbledwyer за публикацию ссылки на решение, которое работает для меня:

Обновлено:
Собственно 2-я версия как сделать то же самое: https://www.codementor.io/randyfindley/how-to-build-an-electron-app-using-create-react-app-and-electron-builder-ss1k0sfer

Решение от Рэнди Финдли:
Теперь, если вам нужно получить доступ к модулю fs , как это сделал я, вы быстро столкнетесь с ошибкой Module not found

Во-первых, установите Rescripts .

yarn add @rescripts/cli @rescripts/rescript-env --dev

Затем измените теги scripts в package.json с этого...

"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",

к этому

"start": "rescripts start",
"build": "rescripts build",
"test": "rescripts test",

Теперь добавьте новый файл с именем .rescriptsrc.js со следующим содержимым:

module.exports = [require.resolve('./.webpack.config.js')]

Наконец, добавьте еще один новый файл с именем .webpack.config.js со следующим содержимым:

// define child rescript
module.exports = config => {
  config.target = 'electron-renderer';
  return config;
}

Теперь вы можете использовать модуль fs , не беспокойтесь.

То, что указал @ledleds , сработало для меня, используя CRA с typscript и Electron. Тогда дело в том, что я объявил webPreferences следующим образом:

    webPreferences: {
      preload: path.join(__dirname, 'preload.js')
    },

так что это, кажется, перезаписывает/устанавливает для nodeIntegration значение false, поэтому установка для него значения true и перезапуск приложения решили проблему (вы должны перезапустить приложение, чтобы загрузить окно Electron с этой конфигурацией)

установка для nodeIntegration значения true, как это

    webPreferences: {
      preload: path.join(__dirname, 'preload.js'),
      nodeIntegration: true
    },

Для тех, кто все еще застрял на этом: вы получите ошибку window.require is not a function , если вы явно не объявите nodeIntergation как true при объявлении своего BrowserWindow :

new BrowserWindow({
    webPreferences: {
      nodeIntegration: true,
    }
});

Реакция-приложение-перемонтировано

Это было единственное хорошее решение, которое я нашел с точки зрения масштабируемости, я не думаю, что кому-то следует полагаться на window.require.

Почему window.require не масштабируется?

Для тех, кто борется с этой или подобными проблемами и использует Vue и vue-electron-builder, см. здесь

Для тех, кто все еще борется с этим, особенно в отношении выхода из электронного приложения с помощью кнопки реакции, пожалуйста, читайте дальше.

Мне помогло следующее:

  1. Когда вы объявляете свое окно, убедитесь, что вы установили nodeIntegration: true , так как в настоящее время по умолчанию это false из соображений безопасности. Обычно это делается в файле electron.js .

  2. Как уже упоминал @packetstracer : _ вам нужно перезапустить приложение, чтобы загрузить окно Electron с этой конфигурацией_

mainWindow = new BrowserWindow({
//...
  webPreferences: {
    nodeIntegration: true,
  },
});
  1. Также в вашем electron.js поместите следующий оператор вверху, чтобы гарантировать, что ipcMain будет прослушивать событие _"close-me"_:
const { ipcMain } = require("electron");
ipcMain.on("close-me", (evt, arg) => {
  app.quit();
});
  1. В компоненте реакции, где находится ваша кнопка _"close"_, добавьте следующий оператор window.require после вашего импорта. Обычный require не сработал:
const ipcRenderer = window.require("electron").ipcRenderer;
  1. А чтобы закрыть приложение, вызовите следующий оператор. Он должен отправить событие _"close-me"_ в ipcMain:
<Button label="close" onClick={(e) => ipcRenderer.send("close-me")} />

Не стесняйтесь комментировать и оставлять отзывы. Я все еще новичок в электронике.
Я знаю, что контекст с кнопкой выхода не связан, но я не смог найти более подходящую тему. Пожалуйста, не стесняйтесь указать мне на другую более подходящую тему, если она есть.

Моя конфигурация:

"electron": "9.2.0",
"electron-builder": "22.8.0",
"electron-packager": "15.0.0",

решил для меня!! Спасибо @nukeop

`
`

Кто-нибудь знает, как настроить правильный тип в машинописном тексте?

у меня на данный момент следующее

export const electron = window.require('electron').remote

Я хотел бы что-то вроде

export const electron = window.require('electron').remote as ElectronType

поэтому IDE знает, как автозаполнять электронный API.

@timsamart это работает. Спасибо, это экономит мне дни работы. 🤣

Проведя много часов, пробуя буквально все вышеперечисленное, я пропустил часть на случай, если вы используете BrowserView , точно так же, как BrowserWindow вам нужно явно включить node.js:

     new BrowserView({ // is a BrowserView not a BrowserWindow
        webPreferences: {
          nodeIntegration: true,
        },
      })
Была ли эта страница полезной?
0 / 5 - 0 рейтинги