Без лишнего шаблона
Если вы новичок в Electron и предпочитаете ReactJS, возможно, вы наткнулись на этот шаблон на GitHub.
Этот шаблон великолепен. Однако в нем слишком много наворотов, в которых я не нуждался. Если вы похожи на меня, я просто хочу оставить свой проект React в Electron и посмотреть, как он работает.
Вот ключевые моменты, если вы хотите этого добиться.
Объединить Electron с приложением Create React или нет?
Если вы решите объединить Electron в CRA, ваш проект будет выглядеть как обычное приложение React, гдеelectron-starter.js
- это точка входа для электрона.
├── Procfile ├── package.json ├── public │ ├── favicon.ico │ └── index.html └── src ├── App.css ├── App.js ├── App.test.js ├── electron-starter.js ├── electron-wait-react.js ├── index.css ├── index.js └── logo.svg
Если это то, что вы ищете, вот подробное руководство о том, как это сделать: Создание приложения Electron с помощью create-react-app »Кристиана Сепульведы.
Но если вы переносите приложение NodeJS на Electron и хотите, чтобы серверная часть (которая теперь является основным кодом процесса) была разделена, вы можете попробовать эту структуру.
├── Procfile ├── app │ ├── config │ ├── events │ ├── libs │ ├── models │ └── views │ ├── js │ │ └── preload.js │ └── react │ ├── README.md │ ├── build │ ├── package.json │ ├── public │ └── src ├── assets │ └── icon.png ├── electron-wait-react.js ├── main.js └── package.json
В этом случае main.js
будет точкой входа, и папка сборки Electron не будет конфликтовать с папкой сборки CRA.
Настройка среды разработки и продукта
Поскольку вы не хотите перезапускать приложение Electron каждый раз, когда вносите изменения, вы можете указать, чтобы Electron использовал URL-адрес webpack-dev-server React.
const { app, BrowserWindow } = require('electron'); const path = require('path'); const url = require('url'); let mainWindow function createWindow () { // Create the browser window. mainWindow = new BrowserWindow({ width: 1024, height: 728 }); const startUrl = process.env.ELECTRON_START_URL || url.format({ pathname: path.join(__dirname, 'app/views/react/build/index.html'), protocol: 'file:', slashes: true }); mainWindow.loadURL(startUrl);
Если в качестве переменной среды используется ELECTRON_START_URL
, он будет использовать этот URL вместо встроенной версии React.
Благодаря упомянутому выше руководству Кристиана вы также можете использовать Foreman для управления и регистрации как Electron, так и React.
Вот здесь и пригодится Procfile
. В свой Procfile
добавьте скрипт npm, который запускает приложение React и приложение Electron:
react: npm run react-start electron: npm run electron-start
И большая часть волшебства происходит в package.json
.
{ "main": "main.js", "scripts": { "start": "nf start -p 3000", "electron-start": "node electron-wait-react", "react-start": "cd ./app/views/react && react-scripts start" }, "devDependencies": { "electron": "^6.0.9", "electron-builder": "^21.2.0", "foreman": "^3.0.1" }, "directories": { "buildResources": "assets", "output": "release" } }
Когда вы запускаете npm start
, он выполняет обе команды в Procfile
на порту 3000.
И вы можете задаться вопросом, что делает electron-wait-react.js
?
Как и в версии Кристиана, я внес небольшую поправку в журнал сообщений из приложения Electron.
Он ждет, пока запустится webpack-dev-сервер React, прежде чем запускать приложение Electron.
const net = require('net'); const port = process.env.PORT ? (process.env.PORT - 100) : 3000; process.env.ELECTRON_START_URL = `http://localhost:${port}`; const client = new net.Socket(); let startedElectron = false; const tryConnection = () => client.connect({port: port}, () => { client.end(); if(!startedElectron) { console.log('starting electron'); startedElectron = true; const { spawn } = require('child_process'); const ls = spawn('npm run electron', [], { shell: true }); ls.stdout.on('data', (data) => { console.log(`${data}`); }); ls.stderr.on('data', (data) => { console.error(`err: ${data}`); }); ls.on('close', (code) => { console.log(`child process exited with code ${code}`); }); }}); tryConnection(); client.on('error', (error) => { setTimeout(tryConnection, 1000); });
Установить домашнюю страницу в React package.json
Если вы создаете приложение и видите пустую страницу, это связано с тем, что React не может найти свои файлы js и CSS. В вашем package.json
приложении React не забудьте добавить:
"homepage": "./"
Используйте nodeIntegration
Наконец, у вас есть React, работающий в Electron, но что, если вы хотите использовать модули Electron внутри React?
После создания окна вы можете добавить nodeIntegration
в webPreferences
.
mainWindow = new BrowserWindow({ width: 1024, height: 728, webPreferences: { nodeIntegration: true, preload: path.join(__dirname, 'app/views/js/preload.js') } });
И в вашем приложении React вы можете потребовать это как таковое:
const { ipcRenderer } = window.require("electron");
Другая потенциальная проблема
Приложение React запрещает доступ к файлам за пределами src. Большинство решений, которые я нашел в Интернете, включают извлечение приложения React и отключение этого правила в webpack.
Но в нашем случае нам нужны были только изображения для отображения в React, поэтому мы сохранили изображение в формате base64, чтобы обойти эту проблему.
Заключение
Спасибо тем, кто создал учебники и сообщения об Electron. Ваш вклад сделал изучение Electron менее пугающим.