Изграждане на приложение на Electron с create-response-app

Не е необходима конфигурация на уебпак или „изваждане“.

Наскоро изградих приложение Electron, използвайки create-response-app . Не трябваше да се занимавам с Webpack или да „изваждам“ приложението си. Ще ви преведа как съм постигнал това.

Бях привлечен от идеята да използвам приложението create-response-app, защото скрива подробностите за конфигурацията на уеб пакета. Но търсенето ми за съществуващи ръководства за използване на Electron и създаване-реакция-приложение заедно не даде никакви плодове, така че аз просто се гмурнах и го разбрах сам.

Ако се чувствате нетърпеливи, можете да се потопите направо и да погледнете кода ми. Ето репозитория на GitHub за приложението ми.

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

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

React е рамката на JavaScript за преглед на Facebook.

JavaScript библиотека за изграждане на потребителски интерфейси - React

JavaScript библиотека за изграждане на потребителски интерфейсиfacebook.github.io

И Electron е рамката на GitHub за изграждане на междуплатформени настолни приложения в JavaScript.

Електрон

Изграждайте приложения за настолни компютри с различни платформи с JavaScript, HTML и CSS. electron.atom.io

Повечето използват webpack за конфигурацията, необходима за разработката на React. webpack е инструмент за конфигуриране и изграждане, който по-голямата част от общността на React възприе алтернативи като Gulp и Grunt.

Режимите на конфигурацията варират (повече за това по-късно) и има много генератори на образци и приложения, но през юли 2016 г. Facebook Incubator пусна инструмент,създайте-реагирайте-приложение . Той скрива по-голямата част от конфигурацията и позволява на разработчика да използва прости команди, като например npm startи npm run buildза стартиране и изграждане на техните приложения.

Какво се изхвърля и защо искате да го избегнете?

create-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. добавете цел за изпълнение, за да стартирате Electron 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 run target (to 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": "./",

Използване на Foreman за управление на реагиращи и електронни процеси

За удобство предпочитам да не

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

Foremen е добър инструмент за управление на процесите. Можем да го добавим,

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); });

(Същност)

ЗАБЕЛЕЖКА: Foreman ще измести номера на порта със 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
АКТУАЛИЗАЦИЯ (1/25/17): Добавих следния раздел в отговор на някои коментари на потребителите (тук и тук). Те се нуждаят от достъп до Electron от приложението за реакция и просто изискване или импортиране извежда грешка. Отбелязвам едно решение по-долу.

Достъп до Electron от React App

Приложението Electron има два основни процеса: хост / обвивката на Electron и вашето приложение. В някои случаи искате да получите достъп до Electron от приложението си. Например, може да искате да осъществите достъп до локалната файлова система или да използвате Electron's ipcRenderer. Но ако направите следното, ще получите грешка

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

Има някои дискусии за тази грешка в различни проблеми с GitHub и Stack Overflow, като този. Повечето решения предлагат промени в конфигурацията на webpack, но това ще изисква изваждане на приложението.

Има обаче просто решение / хак.

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

Обобщавайки

За удобство, тук е GpoHub репо, което има всички промени по-горе, с тагове за всяка стъпка. Но там не е много работа за зареждане на приложение на Electron, което използва create-response-app. (Тази публикация е много по-дълга от кода и промените, които трябва да интегрирате двете.)

И ако използвате приложение за създаване на реакция, може да искате да проверите публикацията ми, тестове за отстраняване на грешки в WebStorm и приложение за създаване на реакция.

Благодаря за четенето. Можете да проверите още от публикациите ми на justideas.io

АКТУАЛИЗИРАНЕ (2/2/17). Читател Карл Витуло предложи да използва npm startвместо npm run devи подаде заявка за изтегляне с промените на GitHub. Тези ощипвания са налични в този клон.