Дружим Create-React-App и Electron

Дружим Create-React-App и Electron

  1. Запускаем create-react-app
npx create-react-app nazvanie_projecta

2. Входим в папку

cd nazvanie_projecta

3. Устанавливаем Electron

npm install electron --save-dev

4. В корень добавляем папку electron в нем файл main.js, типовой для electron

5. Изменяем в нем открытие файла на открытие localhost:3000

mainWindow.loadURL('http://localhost:3000');

6. В файл package.json добавляем: в scripts:

"electron": "electron ."

И добавляем строчку: “main”:

"main": "electron/main.js"

а также productNam:

"productName": "Пример приложения Electron Create React"

должно получиться примерно так:

{
  "name": "nazvanie_projecta",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@testing-library/jest-dom": "^4.2.4",
    "@testing-library/react": "^9.5.0",
    "@testing-library/user-event": "^7.2.1",
    "react": "^16.13.1",
    "react-dom": "^16.13.1",
    "react-scripts": "3.4.1"
  },
  "main": "electron/main.js",
  "productName": "Пример приложения Electron Create React",
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject",
    "electron": "electron ."
  },
  "eslintConfig": {
    "extends": "react-app"
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  },
  "devDependencies": {
    "electron": "^9.1.1"
  }
}

Далее можно выполнить команду npm start, после того как запустится можно выполнить команду npm electron – уже работает. Едем дальше!

Для того чтобы правильно открывалось и в продакшн и в разработке

Нам нужно чтобы, при разработке использовался localhost:3000, а в продакшн ссылался на собранный файл html

Соответственно меняем файл main.js, добавляя строку:

  const startUrl = process.env.ELECTRON_START_URL || url.format({
    pathname: path.join(__dirname, '../index.html'),
    protocol: 'file:',
    slashes: true
  });
  mainWindow.loadURL(startUrl);

Весь файл main.js, может выглядеть примерно так:

// Модули для управления приложением и создания окна
const {app, BrowserWindow} = require('electron')
const path = require ('path');
const url = require ('url');
require('./ipcmain');

function createWindow () {
  // Создаем окно браузера.
  const mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      nodeIntegration: true
    }
  })

  // и загрузить index.html приложения.
  //mainWindow.loadFile('index.html')

  const startUrl = process.env.ELECTRON_START_URL || url.format({
    pathname: path.join(__dirname, '../index.html'),
    protocol: 'file:',
    slashes: true
  });

  mainWindow.loadURL(startUrl);
  // mainWindow.loadURL('http://localhost:3000');

  // Отображаем средства разработчика.
  // mainWindow.webContents.openDevTools()
}

// Этот метод вызывается когда приложение инициализируется
// и будет готово для создания окон.
// Некоторые API могут использоваться только после возникновения этого события.
app.whenReady().then(() => {
  createWindow()
  
  app.on('activate', function () {
    // На MacOS обычно пересоздают окно в приложении,
    // после того, как на иконку в доке нажали и других открытых окон нету.
    if (BrowserWindow.getAllWindows().length === 0) createWindow()
  })
})

// Выйти когда все окна закрыты
app.on('window-all-closed', function () {
  // Для приложений и строки меню в macOS является обычным делом оставаться
  // активными до тех пор, пока пользователь не выйдет окончательно используя Cmd + Q
  if (process.platform !== 'darwin') app.quit()
})

// В этом файле вы можете включить остальную часть основного процесса вашего приложения
//  Вы также можете поместить их в отдельные файлы и подключить через require.

В файле package.json в scripts изменяем строку start – для того чтобы не запускался в браузере

"start": "export BROWSER=none && react-scripts start"

Для винды она будет выглядеть так:

"start": "set BROWSER=none && react-scripts start"

В файл package.json добавляем строку в scripts

"electron-dev": "ELECTRON_START_URL=http://localhost:3000 electron ."

Для винды это можно сделать так:

”electron-dev”: "set ELECTRON_START_URL=http://localhost:3000 && electron .”

Также в package.json, добавляем строку:

"homepage": "./",

Теперь запуск проекта для разработки будет такими двумя командами:

npm start
npm run electron-dev

Доступ к Electron из приложения в React

Добавляем такой код в приложение React:

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

После этого можно пользоваться ipcRender.

Соответственно после этого в браузере перестает работать, а работает только через Electron.

Билдим все это хозяйство в продакшн

Для начала запускаем build react

npm run build

Добавляем в package.json в scripts:

"build-electron": "mkdir build/electron && cp -r electron/. build/electron",

Для винды это будет так:

"build-electron": "mkdir build/electron && robocopy electron build/electron /S"

Запускаем этот скрипт:

npm run build-electron

Устанавливаем electron-builder

npm install --save-dev electron-builder

Добавляем еще строку в package.json в scripts

"package": "electron-builder build --mac --win -c.extraMetadata.main=build/electron/main.js --publish never"

Также добавляем в package.json

  "build": {
    "files": [
      "build/**/*",
      "node_modules/**/*"
    ],
    "publish": {
      "provider": "github",
      "repo": "electron-cra-example",
      "owner": "johndyer24"
    }
  }

Добавляем иконку приложения

Для добавления иконки приложения, копируем файл icon.png в папку build размером 512 на 512 пикселей.

Подробнее можно почитать здесь https://www.electron.build/icons

В файл package.json добавляем строку icon в build

"icon": "build/icon.png"

Итого файл package.json получается примерно такой:

{
  "name": "dp-upravlenie-postgres",
  "version": "0.1.0",
  "private": true,
  "homepage": "./",
  "dependencies": {
    "@testing-library/jest-dom": "^4.2.4",
    "@testing-library/react": "^9.5.0",
    "@testing-library/user-event": "^7.2.1",
    "pg": "^8.3.0",
    "react": "^16.13.1",
    "react-dom": "^16.13.1",
    "react-redux": "^7.2.0",
    "react-scripts": "3.4.1",
    "redux": "^4.0.5",
    "redux-thunk": "^2.3.0"
  },
  "author": {
    "name" : "Дмитрий Поляков",
    "email": "info@polyakovdmitriy.ru",
    "url": "https://polyakovdmitriy.ru"
  },
  "main": "electron/main.js",
  "productName": "ДП - Управление базами PostgreSql",
  "scripts": {
    "start": "export BROWSER=none && react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject",
    "electron": "electron .",
    "electron-dev": "ELECTRON_START_URL=http://localhost:3000 electron .",
    "build-electron": "mkdir build/electron && cp -r electron/. build/electron",
    "package": "electron-builder build --mac --win -c.extraMetadata.main=build/electron/main.js --publish never"
  },
  "eslintConfig": {
    "extends": "react-app"
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  },
  "devDependencies": {
    "electron": "^9.1.1",
    "electron-builder": "^22.7.0",
    "redux-logger": "^3.0.6"
  },
  "build": {
    "win" : {
      "icon" : "build/icon.ico"
    },
    "mac" : {
      "icon" : "build/icon.png"
    },
    "files": [
      "build/**/*",
      "node_modules/**/*"
    ],
    "publish": {
      "provider": "github",
      "repo": "electron-cra-example",
      "owner": "johndyer24"
    }
  }
}

Запускаем:

npm run package

Проект создастся в папке dist. Можно пробовать устанавливать и запускать!

Оставить комментарий