Electron - 跨平台的視窗應用程式
一、Electron介紹
Electron Logo
Electron(原名為Atom Shell)是GitHub開發的一個開源框架。[5]它允許使用Node.js(作為後端)和Chromium(作為前端)完成桌面GUI應用程式的開發。Electron現已被多個開源Web應用程式用於前端與後端的開發,著名專案包括GitHub的Atom和微軟的Visual Studio Code。
由於開發環境就是基於 Node.js,請務必安裝好。
很多知名的桌面應用程式都是使用 Electron 開發的例如:
- Github Desktop
- Discord
- WordPress.com
- Visual Studio Code
- Slack
- Atom
二、專案建立
以下實務操作將建立一個桌面鬧鐘通知應用程式,此範例從此處學習
首先我們建立專案資料夾,並初始化:
mkdir electron-alarm-clock && cd electron-alarm-clock
npm init -y
- 你可以直接手動新增資料夾,然後進入(可以不用這麼工程師的方式)
- 進入專案後使用終端機輸入 npm init -y 進行初始專案(-y 是將詢問的條件通通默認 yes)
安裝 electron:
npm install --save--dev electron
- --save-dev 會將指定套件存於 package.json 的 devDependencies
- 因為 electron 只有開發階段才需要用到,因此只需要 --save--dev
在 package.json 修改程式進入點位置:
在 main 的部分,將 index.js 改為 main.js。
在 script 的部分,新增 start。
[ package.json ]
[ package.json ]
{
"name": "electron-alarm-clock",
"version": "1.0.0",
"description": "",
"main": "main.js",
"scripts": {
"start": "electron ."
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"electron": "^1.8.4"
}
}
新增檔案 main.js:
[ main.js ]const {
app,
BrowserWindow,
} = require('electron')
const path = require('path')
const url = require('url')
app.on('ready', createWindow)
app.on('window-all-closed', () => {
// darwin = MacOS
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', () => {
if (win === null) {
createWindow()
}
})
function createWindow() {
// Create the browser window.
win = new BrowserWindow({
width: 400,
height: 400,
maximizable: false,
webPreferences: {
nodeIntegration: true
}
})
win.loadURL(url.format({
pathname: path.join(__dirname, 'index.html'),
protocol: 'file:',
slashes: true
}))
// Open DevTools.
// win.webContents.openDevTools()
// When Window Close.
win.on('closed', () => {
win = null
})
}
在 main.js 中我們指定畫面來源為 index.html,
[ index.html ]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Electron</title>
</head>
<body>
<h1>Hello Electron</h1>
<p>Node Version:
<script>document.write(process.versions.node)</script>
</p>
<p>Chrome Version:
<script>document.write(process.versions.chrome)</script>
</p>
<p>Electron Version:
<script>document.write(process.versions.electron)</script>
</p>
</body>
</html>
在 script 中,我們可以調用 node.js 的物件,在這邊我們範例使用 process。運行結果:
npm start
以上我們完成了基本的環境與專案建立。
三、鬧鐘提醒程式開發
這邊基本上可以自行開發創作,
以下功能會進行時間的偵測,並透過 Notification 進行提醒。
元素布置
首先放置「顯示當前時間的元素」、「可輸入時間的輸入方塊」,
以及載入畫面端主程式 app.js
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Electron</title>
</head>
<body>
<h1>Hello Electron</h1>
<p>Node Version:
<script>document.write(process.versions.node)</script>
</p>
<p>Chrome Version:
<script>document.write(process.versions.chrome)</script>
</p>
<p>Electron Version:
<script>document.write(process.versions.electron)</script>
</p>
<hr>
<div class="now-time"></div>
<input type="text" class="alarm-time">
<script src="app.js"></script>
</body>
</html>
顯示時間並不斷地更新
在時間操作上,我們使用套件 moment.js ⏱,比較方便操作。
npm install --save moment
[ app.js ]
const moment = require('moment')
const elNow = document.querySelector('.now-time')
const elAlarm = document.querySelector('.alarm-time')
elAlarm.addEventListener('change', onAlarmTextChange)
let time = moment()
let nowTime
let alarmTime
/** Set Time */
const now = moment(time).format('HH:mm:ss')
nowTime = now
elNow.innerText = now
const alarm = moment(time).add(5, 'seconds').format('HH:mm:ss')
alarmTime = alarm
elAlarm.value = alarm
timer()
/** Now Time */
function timer() {
time = moment().format('HH:mm:ss')
/** Set Now */
nowTime = time
elNow.innerText = time
setTimeout(() => {
timer()
}, 1000)
}
/**
* Save To Global Variable,
* Can't Read Dom In Minimize Status.
* @param {event} event
*/
function onAlarmTextChange(event) {
alarmTime = event.target.value
}
- 提醒時間:預設當前時間過後 5 秒
- nowTime:把當前時間存成全域變數
- alarmTime:把提醒時間存成全域變數
可以看到不斷地更新當前時間。
npm start
提醒時間
判斷時間如果符合提醒,就跳出通知。
[ app.js ]
判斷時間如果符合提醒,就跳出通知。
[ app.js ]
/** Now Time */
function timer() {
time = moment().format('HH:mm:ss')
/** Set Now */
nowTime = time
elNow.innerText = time
check()
setTimeout(() => {
timer()
}, 1000)
}
/** Check Time */
function check() {
const diff = moment(nowTime, 'HH:mm:ss').diff(moment(alarmTime, 'HH:mm:ss'))
if (diff === 0) {
alert('wake up!')
}
}
npm start
通知訊息
通知的部分,因為在 Windows10 好像 Notification 會有點失效問題 😪,
在這邊選用一個套件 node-notifier 來進行通知。
npm install --save node-notifier
[ app.js ]
const notifier = require('node-notifier')
const path = require('path')
/** Check Time */
function check() {
const diff = moment(nowTime, 'HH:mm:ss').diff(moment(alarmTime, 'HH:mm:ss'))
if (diff === 0) {
const msg = "It's" + alarmTime + ". Wake Up!"
/** const msg = `It's ${alarmTime}. Wake Up!` */
notice(msg)
}
}
/**
* System Notification
* @param {string} msg
*/
function notice(msg) {
/** https://github.com/mikaelbr/node-notifier */
notifier.notify({
title: 'Alarm Clock',
message: msg,
icon: path.join(__dirname, 'clock.ico'),
sound: true,
})
}
四、程式編譯
將程式編譯成 exe,我們使用 electron-packager,在 package.json 中,新增封裝指令 build:
npm install electron-packager --save-dev
[ package.json ]
{
"scripts": {
"start": "electron .",
"build": "electron-packager . AlarmClock --out AlarmClock --overwrite --platform=win32 --arch=x64 --icon=clock.ico --prune=true --squirrel-install --ignore=node_modules/electron-* --electron-version=1.7.9 --ignore=AlarmClock-win32-x64 --version-string.CompanyName=Robby --version-string.ProductName=AlarmClock",
},
}
- electron-packager . AlarmClock:把當前目錄 . 打包起來,並將應用程式命名 AlarmClock
- --out AlarmClock:輸出資料夾於 AlarmClock,產出後預設資料夾為 AlarmClock-win32-x64
- --overwrite:如果已經存在資料夾和檔案,會進行覆寫
- --platform=win32:平台為 Windows(Mac: darwin, Linux: linux)
- --arch=x64:應用程式 64位元(ia32, all)
- --icon=clock.ico:應用程式 ICON
- --ignore=node_modules/electron-*:忽略的檔案
- --electron-version=1.7.9:electron 的核心版本
- --version-string.CompanyName=Robby:軟體公司名稱(顯示於軟體資訊中)
- --version-string.ProductName=AlarmClock:軟體名稱(顯示於軟體資訊中)
試著編譯看看。
npm run build
應用程式就可以直接執行了!
留言
張貼留言