Створення програми Electron за допомогою програми create-response-app

Не потрібна конфігурація веб-пакета або “виймання”.

Нещодавно я створив додаток Electron за допомогою create-response-app . Мені також не потрібно було морочитися з Webpack або "викидати" свій додаток. Я проведу вас через те, як я це зробив.

Мене зацікавила ідея використання програми create-response-app, оскільки вона приховує деталі конфігурації веб-пакета. Але мої пошуки існуючих посібників із використання Electron та програми create-response-app не дали ніяких плодів, тому я просто зайшов і зрозумів це сам.

Якщо ви відчуваєте нетерпіння, ви можете зануритися і подивитися на мій код. Ось репозитарій GitHub для мого додатка.

Перш ніж ми почнемо, дозвольте мені розповісти вам про Electron та React, і чому додаток create-response-є таким чудовим інструментом.

Електрон і реакція

React - це фреймворк JavaScript для перегляду Facebook.

Бібліотека JavaScript для побудови користувальницьких інтерфейсів - React

Бібліотека JavaScript для побудови користувальницьких інтерфейсівfacebook.github.io

А Electron - це фреймворк GitHub для створення крос-платформних настільних додатків у JavaScript.

Електрон

Створюйте настільні додатки для різних платформ за допомогою JavaScript, HTML та CSS. electron.atom.io

Більшість використовують веб-пакет для конфігурації, необхідної для розробки React. webpack - це інструмент конфігурації та побудови, який більшість спільноти React застосувала до альтернатив, таких як Gulp та Grunt.

Накладні витрати на конфігурацію варіюються (про це пізніше), і доступно багато генераторів шаблонів та додатків, але в липні 2016 року Facebook Incubator випустив інструмент,створити-реагувати-додаток . Він приховує більшу частину конфігурації та дозволяє розробнику використовувати прості команди, такі як npm startі npm run buildдля запуску та створення своїх програм.

Що таке викидання і чому ви хочете цього уникати?

app-response-app робить певні припущення щодо типової установки React. Якщо ці припущення не для вас, є можливість вилучити додаток ( npm run eject). Видалення програми копіює всю інкапсульовану конфігурацію create-response-app у ваш проект, надаючи шаблонну конфігурацію, яку ви можете змінити за власним бажанням.

Але це подорож в один бік . Ви не можете скасувати викид і повернутися назад. Було 49 випусків (на цей пост) програми create-response-app, кожна з яких вдосконалювалась. Але для вибраної програми вам доведеться або відмовитись від цих удосконалень, або зрозуміти, як їх застосувати.

Викинута конфігурація складає понад 550 рядків, що охоплюють 7 файлів (станом на цей пост). Я не все це розумію (ну, насправді більшість із них) і не хочу.

Цілі

Мої цілі прості:

  • уникайте викидання програми React
  • мінімізуйте клей, щоб React та Electron працювали разом
  • зберегти за замовчуванням, припущення та домовленості, зроблені Electron, та create-response-app / React. (Це може полегшити використання інших інструментів, які передбачають / вимагають таких умов.)

Основний рецепт

  1. запустити, create-react-appщоб сформувати базовий додаток React
  2. бігти npm install --save-dev electron
  3. додати main.jsз electron-quick-start(ми будемо перейменовувати його на electron-starter.js, для ясності)
  4. змінити виклик до mainWindow.loadURL(in electron-starter.js) для використання localhost:3000(webpack-dev-server)
  5. додати основний запис до package.jsonдляelectron-starter.js
  6. Додати ціль запуску, щоб запустити Електрон package.json
  7. npm start слідом за ним npm run electron

Етапи 1 і 2 досить прості. Ось код для кроків 3 і 4:

const electron = require('electron'); // Module to control application life. const app = electron.app; // Module to create native browser window. const BrowserWindow = electron.BrowserWindow; const path = require('path'); const url = require('url'); // Keep a global reference of the window object, if you don't, the window will // be closed automatically when the JavaScript object is garbage collected. let mainWindow; function createWindow() { // Create the browser window. mainWindow = new BrowserWindow({width: 800, height: 600}); // and load the index.html of the app. mainWindow.loadURL('//localhost:3000'); // Open the DevTools. mainWindow.webContents.openDevTools(); // Emitted when the window is closed. mainWindow.on('closed', function () { // Dereference the window object, usually you would store windows // in an array if your app supports multi windows, this is the time // when you should delete the corresponding element. mainWindow = null }) } // This method will be called when Electron has finished // initialization and is ready to create browser windows. // Some APIs can only be used after this event occurs. app.on('ready', createWindow); // Quit when all windows are closed. app.on('window-all-closed', function () { // On OS X it is common for applications and their menu bar // to stay active until the user quits explicitly with Cmd + Q if (process.platform !== 'darwin') { app.quit() } }); app.on('activate', function () { // On OS X it's common to re-create a window in the app when the // dock icon is clicked and there are no other windows open. if (mainWindow === null) { createWindow() } }); // In this file you can include the rest of your app's specific main process // code. You can also put them in separate files and require them here.

(Суть)

А для кроків 5 і 6:

{ "name": "electron-with-create-react-app", "version": "0.1.0", "private": true, "devDependencies": { "electron": "^1.4.14", "react-scripts": "0.8.5" }, "dependencies": { "react": "^15.4.2", "react-dom": "^15.4.2" }, "main": "src/electron-starter.js", "scripts": { "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test --env=jsdom", "eject": "react-scripts eject", "electron": "electron ." } }

(Суть)

Коли ви виконуєте команди npm на кроці 7, ви повинні побачити таке:

Ви можете внести реальні зміни в код React, і ви побачите, як вони відображаються в запущеному додатку Electron.

Це добре працює для розвитку, але має два недоліки:

  • виробництво не використовуватиме webpack-dev-server. Він повинен використовувати статичний файл зі створення проекту React
  • (мала) неприємність для запуску обох команд npm

Вказівка ​​loadURL у Production і Dev

У розробці змінна середовища може вказувати URL-адресу для mainWindow.loadURL(in electron-starter.js). Якщо env var існує, ми використаємо його; в іншому випадку ми будемо використовувати робочий статичний файл HTML.

Ми додамо ціль запуску npm (до package.json) наступним чином:

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

Оновлення: Користувачам Windows потрібно буде виконати наступне: (завдяки @bfarmilo)

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

В electron-starter.js, ми будемо модифікувати mainWindow.loadURLвиклик наступним чином :

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

(Суть)

З цим виникає проблема: create-react-app(за замовчуванням) створює файл, index.htmlякий використовує абсолютні шляхи. Це не вдасться під час завантаження в Electron. На щастя, є можливість змінити це: встановити homepageвластивість у package.json. (Документація Facebook щодо власності знаходиться тут.)

Отже, ми можемо встановити для цього властивості поточний каталог і npm run buildвикористовуватимемо його як відносний шлях.

"homepage": "./",

Використання Формана для управління реакційними та електронними процесами

Для зручності я вважаю за краще ні

  1. запуск / управління сервером розробників React та процесами Electron (я б скоріше мав справу з одним)
  2. дочекайтеся запуску сервера React dev, а потім запустіть Electron

Формани - хороший інструмент управління процесами. Ми можемо додати це,

npm install --save-dev foreman

і додайте наступне Procfile

react: npm startelectron: npm run electron

(Суть)

Це стосується (1). Для (2) ми можемо додати простий сценарій вузла ( electron-wait-react.js), який чекає запуску сервера React dev, а потім запускає Electron.

const net = require('net'); const port = process.env.PORT ? (process.env.PORT - 100) : 3000; process.env.ELECTRON_START_URL = `//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 exec = require('child_process').exec; exec('npm run electron'); } } ); tryConnection(); client.on('error', (error) => { setTimeout(tryConnection, 1000); });

(Суть)

ПРИМІТКА. Форман компенсує номер порту на 100 для процесів різних типів. (Див. Тут.) Отже, electron-wait-react.jsвіднімається 100, щоб правильно встановити номер порту сервера React dev.

Тепер змініть Procfile

react: npm startelectron: node src/electron-wait-react

(Суть)

Нарешті, ми змінимо цілі запуску, package.jsonщоб замінити electron-devна:

"dev" : "nf start"

А тепер ми можемо виконати:

npm run dev
ОНОВЛЕННЯ (25.01.17): Я додав наступний розділ у відповідь на деякі коментарі користувачів (тут і тут). Їм потрібен доступ до Electron із додатка для реагування, а просте вимагання чи імпорт видає помилку. Я зазначаю одне рішення нижче.

Доступ до Electron із програми React

Додаток Electron має два основні процеси: хост / обгортку Electron та ваш додаток. У деяких випадках вам потрібен доступ до Electron із вашої програми. Наприклад, ви можете отримати доступ до локальної файлової системи або скористатися Electron's ipcRenderer. Але якщо ви зробите наступне, ви отримаєте помилку

const electron = require('electron') //or import electron from 'electron';

Існує певна дискусія щодо цієї помилки в різних питаннях GitHub та Stack Overflow, таких як ця. Більшість рішень пропонують зміни конфігурації веб-пакета, але для цього потрібно вимкнути програму.

Однак є просте обхідне рішення / хак.

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

Підведенню

Для зручності, ось репозитарій GitHub, який містить усі зміни вище, з тегами для кожного кроку. Але тут не так багато роботи для завантаження програми Electron, яка використовує додаток create-response-. (Цей пост набагато довший за код і зміни, необхідні для інтеграції цих двох.)

І якщо ви використовуєте create-response-app, ви можете перевірити мій пост, тести налагодження в WebStorm та create-React-App.

Дякуємо за читання. Ви можете перевірити більше моїх публікацій на justideas.io

ОНОВЛЕННЯ (2/2/17). Читач, Карл Вітулло, запропонував використовувати npm startзамість npm run devі подав запит на вилучення із змінами на GitHub. Ці налаштування доступні в цій гілці.