創(chuàng)建一個(gè)簡(jiǎn)單的Electron桌面應(yīng)用
在GitHub上有個(gè)
的倉(cāng)庫(kù)覆醇,需要本地計(jì)算機(jī)安裝好Git(比如SourceTree)和Node.js语盈,使用步驟如下:
# 克隆倉(cāng)庫(kù)
git clone https://github.com/electron/electron-quick-start
# 使用命令行進(jìn)入倉(cāng)庫(kù)所在文件夾
cd electron-quick-start
# 安裝依賴(lài)
npm install
# 運(yùn)行應(yīng)用
npm start
Electron詳細(xì)文檔可以參看官方文檔
創(chuàng)建一個(gè)React項(xiàng)目(內(nèi)容引用《深入淺出React和Redux》诊霹,侵刪)
React技術(shù)依賴(lài)于一個(gè)很龐大的技術(shù)棧祷杈,比如智袭,轉(zhuǎn)譯JavaScript代碼需要用到Babel献烦,模塊打包工具又要用到Webpack曙求,定制build過(guò)程需要grunt或者gulp……這些技術(shù)棧都需要各自的配置文件牌借,還沒(méi)有開(kāi)始寫(xiě)一行React相關(guān)代碼度气,開(kāi)發(fā)人員就已經(jīng)被各種技術(shù)名詞淹沒(méi)。
針對(duì)這種情況膨报,React的創(chuàng)建者Facebook提供了一個(gè)快速開(kāi)發(fā)React應(yīng)用的工具磷籍,名叫create-react-app,這個(gè)工具的目的是將開(kāi)發(fā)人員從配置工作中解脫出來(lái)现柠,無(wú)需過(guò)早關(guān)注這些技術(shù)棧細(xì)節(jié)院领,通過(guò)創(chuàng)建一個(gè)已經(jīng)完成基本配置的應(yīng)用,讓開(kāi)發(fā)者快速開(kāi)始React應(yīng)用的開(kāi)發(fā)够吩,并且提供了熱調(diào)試環(huán)境比然。
create-react-app是一個(gè)通過(guò)npm發(fā)布的安裝包,在確認(rèn)Node.js和npm安裝好之后周循,命令行中執(zhí)行下面的命令安裝create-react-app:
npm install --global create-react-app
安裝過(guò)程結(jié)束之后强法,你的電腦中就會(huì)有create-react-app這樣一個(gè)可以執(zhí)行的命令,這個(gè)命令會(huì)在當(dāng)前目錄下創(chuàng)建指定參數(shù)名的應(yīng)用目錄湾笛。
我們?cè)诿钚兄袌?zhí)行下面的命令:
create-react-app test_app
這個(gè)命令會(huì)在當(dāng)前目錄下創(chuàng)建一個(gè)名為test_app的目錄饮怯,在這個(gè)目錄中會(huì)自動(dòng)添加一個(gè)應(yīng)用的框架,隨后我們只需要在這個(gè)框架的基礎(chǔ)上修改文件就可以開(kāi)發(fā)React應(yīng)用迄本,避免了大量的手工配置工作:
在create-react-app命令一大段文字輸出之后硕淑,根據(jù)提示,輸入下面的命令:
cd test_app
npm start
這個(gè)命令會(huì)啟動(dòng)一個(gè)開(kāi)發(fā)模式的服務(wù)器,同時(shí)也會(huì)讓你的瀏覽器自動(dòng)打開(kāi)了一個(gè)網(wǎng)頁(yè)置媳,指向本機(jī)地址http://localhost:3000/ 于樟,顯示界面如下圖所示。
整合Electron和React
Create React App創(chuàng)建的項(xiàng)目是一個(gè)純前端項(xiàng)目拇囊,整合React項(xiàng)目和Electron并且保留熱調(diào)試和本地包引用需要一下幾個(gè)簡(jiǎn)單的操作:
1.需要安裝electron以及增加啟動(dòng)命令
使用命令npm install -save electron安裝electron
在腳本里添加啟動(dòng)命令"electron-start": "electron ."
2. 需要在React項(xiàng)目的根目錄(不是src目錄)創(chuàng)建Electron的啟動(dòng)文件main.js(main.js文件可以直接拷貝electron-quick-start倉(cāng)庫(kù)里的main.js)
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(url.format({
// pathname: path.join(__dirname, 'index.html'),
// protocol: 'file:',
// slashes: true
// }))
mainWindow.loadURL(url.format({
pathname: path.join(__dirname, './build/index.html'),
protocol: 'file:',
slashes: true }));
// 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.
3. 在React項(xiàng)目中的package.json文件中增加main字段迂曲,值為"main.js"
4.修改main.js中的win.loadURL,改為
mainWindow.loadURL(url.format({
pathname: path.join(__dirname, './build/index.html'), protocol: 'file:', slashes: true }))
到目前為止寥袭,在根目錄下運(yùn)行npm run build + npm run electron-start 就可以啟動(dòng)React創(chuàng)建的桌面應(yīng)用了路捧。
運(yùn)行結(jié)果如下:
發(fā)現(xiàn)是一個(gè)內(nèi)容為空的界面,我們還需要做如下修改:
在文件package.json中添加字段 "homepage":"."
原因:默認(rèn)情況下传黄,homepage是http://localhost:3000杰扫,build后,所有資源文件路徑都是/static膘掰,而Electron調(diào)用的入口是file:協(xié)議章姓,/static就會(huì)定位到根目錄去,所以找不到靜態(tài)文件识埋。在package.json文件中添加homepage字段并設(shè)置為"."后凡伊,靜態(tài)文件的路徑就變成了相對(duì)路徑,就能正確地找到了窒舟。
在根目錄下運(yùn)行npm run build + npm run electron-start系忙,運(yùn)行結(jié)果如下:
這樣就結(jié)束了嗎?大家再仔細(xì)回顧下惠豺,我們修改完配置之后運(yùn)行了兩條命令npm run build和npm run electron-start银还,每次都要npm run build后才能看到修改結(jié)果,而前面的內(nèi)容提到過(guò)create-react-app提供了熱調(diào)試環(huán)境耕腾,我們?cè)趺丛贓lectron中使用熱調(diào)試呢见剩?簡(jiǎn)單來(lái)說(shuō)就是代碼的修改能及時(shí)反饋到UI上,不需要做任何額外的操作呢扫俺?
簡(jiǎn)單苍苞。在main.js文件中將啟動(dòng)頁(yè)修改為
win.loadURL('http://localhost:3000/')
開(kāi)發(fā)時(shí),需要啟動(dòng)兩個(gè)終端狼纬,一個(gè)終端啟動(dòng)npm start羹呵, 另一個(gè)終端啟動(dòng)npm run electron-start,這樣在electron中就可以熱調(diào)試了疗琉。
不過(guò)編譯發(fā)布時(shí)需要改回從build/index.html冈欢,這樣很麻煩,可以在package.json中定義個(gè)DEV字段盈简,設(shè)置為true/false凑耻,然后修改main.js太示,代碼如下:
const pkg = require('./package.json') // 引用package.json
//判斷是否是開(kāi)發(fā)模式
if(pkg.DEV) {
win.loadURL("http://localhost:3000/")
} else {
win.loadURL(url.format({
pathname:path.join(__dirname, './build/index.html'),
protocol:'file:',
slashes:true
}))
}
以后運(yùn)行npm run electron-start 之前,根據(jù)需要修改DEV為true/false就行了