隨著JavaScript開源社區(qū)的發(fā)展蒙谓,JavaScript的應用場景越來越廣泛剥啤,到目前為止,JavaScript在Web開發(fā)减余、桌面開發(fā)综苔、APP開發(fā)、服務端開發(fā)方面都可以勝任。
在桌面開發(fā)方面如筛,Electron是我個人最喜歡的解決方案堡牡,它基于HTML、CSS杨刨、JavaScript晤柄,跨平臺崩溪。目前有很多優(yōu)秀的桌面軟件都是使用Electron開發(fā)的:清單
(沒錯吉捶,微軟的VSCode也是Electron開發(fā)的,微軟居然沒用自己的開發(fā)套件角钩,可見Electron的桌面解決方案應該是很優(yōu)秀的赚抡。)
創(chuàng)建一個簡單的桌面應用
前提條件是在開發(fā)環(huán)境必須安裝了NodeJS
- 安裝Electron
npm install electron -g
- 創(chuàng)建一個目錄和必備文件
mkdir hello-world && cd hello-world
touch main.js && touch package.json && touch index.html
- 在package.json文件中寫入
{
"name" : "your-app",
"version" : "0.1.0",
"main" : "main.js"
}
- 在main.js文件中寫入
const {app, BrowserWindow} = require('electron')
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 win
function createWindow () {
// Create the browser window.
win = new BrowserWindow({width: 800, height: 600})
// and load the index.html of the app.
win.loadURL(url.format({
pathname: path.join(__dirname, 'index.html'),
protocol: 'file:',
slashes: true
}))
// Open the DevTools.
win.webContents.openDevTools()
// Emitted when the window is closed.
win.on('closed', () => {
// 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.
win = 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', () => {
// On macOS 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', () => {
// On macOS 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 (win === 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.
- 在index.html中寫入
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Hello World!</title>
</head>
<body>
<h1>Hello World!</h1>
We are using node <script>document.write(process.versions.node)</script>,
Chrome <script>document.write(process.versions.chrome)</script>,
and Electron <script>document.write(process.versions.electron)</script>.
</body>
</html>
在終端運行
electron .
-
你可以看到一個桌面應用程序
第一個應用
Electron詳細文檔可以參看官方文檔
創(chuàng)建一個React項目
用Electron創(chuàng)建一個桌面應用很簡單爬坑,但是用HTML+Javascript肯定會需要用到一些前端庫來輔助開發(fā)。
目前比較主流的前端庫Vue.JS涂臣、AngularJS以及ReactJS盾计。三個庫/框架都很優(yōu)秀,不過我選擇了React肉康。
React創(chuàng)建一個項目其實很繁瑣闯估,因為它用了JSX,所以需要配置Babel吼和、webpack or Browserify
不過好在官方提供了一個工具 Create React App涨薪,可以非常簡單快速的創(chuàng)建React 項目,并且提供了熱調試環(huán)境炫乓。詳細參考官方文檔
簡單的來說刚夺,Create React App 創(chuàng)建了一個React的項目模版、配置末捣,并且提供了一些很方便的腳本命令用于調試和部署React前端程序侠姑。
使用Create React App創(chuàng)建的項目可以通過 npm start
啟動http://localhost:3000/ 服務熱調試;通過npm run build
編譯所有文件放在根目錄下build目錄里箩做。
整合Electron和React
Create React App創(chuàng)建的項目是一個純前端項目莽红,整合React項目和Electron并且保留熱調試和本地包引用需要以下幾個簡單的操作
- 需要在React項目的根目錄(不是src目錄)創(chuàng)建Electron的啟動文件main.js(前文中有詳細內容)
- 在React項目中的package.json文件中增加main字段,值為 "./main.js"
- 修改main.js 中的win.loadURL邦邦,改為
win.loadURL(url.format({
pathname: path.join(__dirname, './build/index.html'),
protocol: 'file:',
slashes: true
}))
到目前為止安吁,在根目錄下運行 electron .就可以啟動React創(chuàng)建的桌面應用了。
但是還有幾個問題
- 資源文件顯示不出來燃辖,在調試面板出現(xiàn)找不到文件的錯誤提示
- 每次都要
npm run build
后才能看到修改項 - 無法獲得系統(tǒng)包鬼店,例如用 os.cpus()無法得到系統(tǒng)cpus信息。
解決這些問題還需要幾個小步驟
修改package.json添加字段
"homepage":"."
默認情況下黔龟,homepage是 http://localhost:3000 ,build后妇智,所有資源文件路徑都是/static
滥玷,而Electron調用的入口是以file:協(xié)議,/staitc就會定位到系統(tǒng)的根目錄去巍棱,所以找不到靜態(tài)文件惑畴。在package.json文件中添加homepage字段并設置為"."后,靜態(tài)文件的路徑就變成了相對路徑拉盾,就能正確的找到了桨菜。main.js啟動頁修改為
http://localhost:3000/
win.loadURL('http://localhost:3000/')
開發(fā)時,啟動nom start
后捉偏,在另一個終端啟動 electron . 這樣在electron中就可以熱調試了
不過編譯后需要改回從build/index.html啟動倒得,這樣很麻煩,可以在package.json中定義個 DEV字段夭禽,設置為 true/false霞掺,然后修改main.js
代碼如下:
const pkg = require('./package.json') // 引用package.json
//判斷是否是開發(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
}))
}
以后運行electron .之前,根據需要修改DEV為true/false就行了
最后讹躯,無論是運行build中的index.html還是http://localhost:3000 都無法通過require調用本地包的菩彬,需要使用window.require。
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
var os = window.require('os') // not be : var os = require('os')
console.log("got:",os.cpus())
class App extends Component {
render() {
return (
<div className="App">
<div className="App-header">
<img src={logo} className="App-logo" alt="logo" />
</div>
CPU count: {os.cpus().length}
</div>
);
}
}
export default App;
使用require
使用window.require
無論啟動頁是 http://localhost:3000/ 還是 build/index.html都有效潮梯。
至此骗灶,整合Electron和React就完成了,整個過程大部分工作都使用React官方和Electron官方提供的工具生成工程項目秉馏,只需要修改幾個配置和入口文件即可耙旦。
總結一下
- 用Create-React-App創(chuàng)建React項目
- 根目錄下創(chuàng)建Electron入口文件 main.js,修改main.js的啟動頁
- 在package.json中添加main字段為"main.js",添加 homepage字段為"."萝究,添加DEV字段為true/false(DEV字段選擇性添加免都,如果你更喜歡修改mian.JS的話)
- 應用本地庫使用window.require替代require
歡迎大家簡書或我的個人博客與我交流