一、Electron是什么
簡單的一句話,就是用html+css+js+nodejs+(Native Api)做兼容多個系統(Windows、Linux、Mac)的軟件。
官網解釋如下(有點像繞口令):
Electron是一個使用 JavaScript、HTML 和 CSS 構建桌面應用程序的框架。 嵌入 Chromium 和 Node.js 到 二進制的 Electron 允許您保持一個 JavaScript 代碼代碼庫并創建 在Windows上運行的跨平臺應用 macOS和Linux——不需要本地開發 經驗。
二、Elemtron流程模型
三、Electron搭建工程,若成功則輸出123
3.1 準備
可參考Electron官網地址
需要node和npm,先檢測是否安裝。
node -v
npm -v
3.2 項目初始化
命令行創建
mkdir my-electron-app && cd my-electron-app
npm init
或者,手動快速創建
package.json文件
{"name": "my-electron-app","version": "1.0.0","description": "test Electron","main": "main.js","author": "Bin9153","license": "MIT"
}
有幾條規則需要遵循:
entry point 應為 main.js.
author 與 description 可為任意值,但對于應用打包是必填項。
3.3 安裝 Electron
npm install --save-dev electron
//或者
npm install electron -D
3.4 配置并啟動
在 package.json配置文件中的scripts字段下增加一條start命令:
{"scripts": {"start": "electron ."}
}
這一步,完整的package.json
{"name": "my-electron-app","version": "1.0.0","main": "main.js","scripts": {"start": "electron ."},"author": "bin9153","license": "ISC","description": "electron test","dependencies": {"electron": "^31.2.0"}
}
代碼解析:
創建main.js。
在main.js里寫入
console.log(123)
再運行!
npm start
注意:
- 先創建main.js,否則報錯
- 如果main.js里沒寫輸出(或其他代碼)則,啟動了運行窗口也不容易看出變化
成功輸出123,工程搭建完成。
四、開始制作程序
4.1 案例1:做一個簡易網頁程序
點擊可以查看,browser-window配置項的開發文檔
在main.js里寫入
const {app, BrowserWindow} = require('electron')app.on('ready', () => {//當app準備好后,執行createWindow創建窗口const win = new BrowserWindow({width: 800,//窗口寬度height: 600,//窗口高度autoHideMenuBar: true,//自動隱藏菜單檔alwaysOnTop: true,//置頂x: 0,//窗口位置x坐標y: 0//窗口位置y坐標})//加載一個遠程頁面win.loadURL('https://blog.csdn.net/qq_33650655/article/details/140353815')
})
運行
npm start
成功顯示頁面。
4.2 案例2:做一個本地程序(不是遠程鏈接頁面,是自己寫的頁面)
4.2.1 是本地程序,所以創建新的頁面
新建pages目錄,創建頁面,這里就像寫前端一樣了。index.html,index.css
index.html里
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>這里是index頁面</title>
</head><body>
<h1>這里是index里的標題
</h1>
</body>
</html>
main.js里引入頁面
const {app, BrowserWindow} = require('electron')app.on('ready', () => {//當app準備好后,執行createWindow創建窗口const win = new BrowserWindow({width: 800,//窗口寬度height: 600,//窗口高度autoHideMenuBar: true,//自動隱藏菜單檔alwaysOnTop: true,//置頂})//引入頁面win.loadFile('./pages/index/index.html')})
運行
npm start
4.2.2 解決內容安全策略
有安全提示
在index.html里加入,如下代碼,內容安全策略警告提示消失。
//electron 提供的配置 成功運行
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'">
//electron 提供的配置2 引入js后也會報錯
<meta http-equiv="Content-Security-Policy" content="default-src none">
//視頻教程里的配置 會報錯
<meta http-equiv="Content-Security-Policy" content="default-src 'self';style-src 'self''unsafe-inline';img-src self'data:;">
//我自己寫的組合的配置更全 加了一個script的限制,有事兒后期再改, 剛試了會報錯,可能哪里沒寫對,先記錄在這里
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self';style-src 'self''unsafe-inline';img-src self'data:;">
關于CSP的詳細說明:MDN內容安全策略詳解 、Electron安全策略規范
4.2.3 增加多系統的兼容代碼
兼容mac(完善窗口行為)
electron文檔:
關閉所有窗口時退出應用 (Windows & Linux)
如果沒有窗口打開則打開一個窗口 (macOS)
在main.js里寫入兼容各個系統平臺的代碼
const {app, BrowserWindow} = require('electron')function createWindow(){//當app準備好后,執行createWindow創建窗口const win = new BrowserWindow({width: 800,//窗口寬度height: 600,//窗口高度autoHideMenuBar: true,//自動隱藏菜單檔alwaysOnTop: true,//置頂})win.loadFile('./pages/index/index.html')
}
app.on('ready', () => {createWindow()//兼容核心代碼 1app.on('activate', () => {if (BrowserWindow.getAllWindows().length === 0) createWindow()})})//兼容核心代碼 2
app.on('window-all-closed', () => {if (process.platform !== 'darwin') app.quit()
})
代碼解析
下面兩句代碼相等
app.on('ready', () => {// 寫核心代碼
})
// 或者
app.whenReady().then(() => {//寫核心代碼
})
4.2.4 配置自動重啟,保存后自動熱更新
npm i nodemon -D
package.json里重寫start
"start": "nodemon --exec electron ."
這樣保存main.js里的內容,就自動熱更新了。
但是更新index.html里的代碼不能熱更新,要加一個nodemon.json,需要手動添加
{"ignore":["node modules","dist"],"restartable":"r","watch":["*.*"],"ext":"html,js,css"
}
增加nodemon.json,
重啟生效
npm start
4.2.5 編寫頁面程序(寫一個應用程序,可以寫入任意文字到hello.text里)
頁面程序要寫在頁面里,那它和主進程的關系如圖
每個頁面程序通過渲染和主進程通信,主進程根據需求調用Native Api來實現功能。
實際,每個頁面和主程序通信時,需要建個橋梁來管理它們的通信,preload.js(自己創建),來管理實現通信。
創建preload.js定義橋梁js
在main.js中定義preload.js為橋梁
main.js代碼:
const {app, BrowserWindow} = require('electron')
const path = require('path')function createWindow(){//當app準備好后,執行createWindow創建窗口const win = new BrowserWindow({width: 800,//窗口寬度height: 600,//窗口高度autoHideMenuBar: true,//自動隱藏菜單檔alwaysOnTop: true,//置頂webPreferences:{ //在main.js中定義preload.js為橋梁preload:path.resolve(__dirname,'./preload.js')}})//引入頁面win.loadFile('./pages/index/index.html')win.openDevTools() //自動打開調試窗口console.log("main.js里的main.js")
}app.on('ready', () => {createWindow()//兼容核心代碼1app.on('activate', () => {if (BrowserWindow.getAllWindows().length === 0) createWindow()})})
創建渲染js
定義渲染js
這是自己整理的,整理了前面45分鐘,再這么整理下去,1000字也不夠用。
下面寫代碼不詳細介紹了。會點前端的能懂一半多代碼。
可以看原來的教程 從45分鐘開始看。視頻教程
直接上代碼。
main.js里的代碼
const {app, BrowserWindow,ipcMain} = require('electron')
const path = require('path')
const fs = require('fs')//寫入文件
function writeFile(_, data) {fs.writeFileSync('D:/hello.txt', data)
}
//讀取文件
function readFile() {const res = fs.readFileSync("D:/hello.txt").toString()return res
}function createWindow() {//當app準備好后,執行createWindow創建窗口const win = new BrowserWindow({width: 800,//窗口寬度height: 600,//窗口高度autoHideMenuBar: true,//自動隱藏菜單檔alwaysOnTop: true,//置頂webPreferences: { //在main.js中定義preload.js為橋梁preload: path.resolve(__dirname, './preload.js')}})ipcMain.on('file-save', writeFile)ipcMain.handle('file-read', readFile)//引入頁面win.loadFile('./pages/index/index.html')win.openDevTools() //自動打開調試窗口console.log("main.js里的main.js")
}app.on('ready', () => {createWindow()//兼容核心代碼1app.on('activate', () => {if (BrowserWindow.getAllWindows().length === 0) createWindow()})})
preload.js里的代碼
const {contextBridge, ipcRenderer} = require('electron')
contextBridge.exposeInMainWorld('myAPI', {version: process.version,saveFile: (data) => {ipcRenderer.send('file-save', data)},readFile() {return ipcRenderer.invoke('file-read')}
})
render.js里的代碼
const btn1 = document.getElementById("btn1")
const btn2 = document.getElementById("btn2")
const btn3 = document.getElementById("btn3")
const input = document.getElementById("inp")
btn1.onclick = () => {alert(myAPI.version)
}
btn2.onclick = () => {myAPI.saveFile(input.value)
}
btn3.onclick = async() => {const res = await myAPI.readFile()alert(res)
}
html里的代碼
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'"><title>這里是index頁面</title>
</head><body>
<h1>歡迎學習Electron開發!!!</h1>
<button id="btn1">點我</button>
<hr/>
<input type="text" id="inp"/>
<button id="btn2">向D盤寫入hello.txt</button>
<hr>
<button id="btn3">讀取hello.txt的內容</button>
</body><script type="text/javascript" src="./render.js"></script>
</html>
目錄結構
備注:
1.代碼稍微有點不一樣
2.目錄結構也有變化,功能是一樣的
五、打包
5.1 使用electron-builder打包,打包時要訪問github
需要修仙術
1.安裝electron-builder:
npm install electron-builder -D
2.在package.json中進行相關配置,具體配置如下:
備注:json文件不支持注釋,使用時請去掉所有注釋。
package.json里的代碼
{"name": "video-tools","version": "1.0.0","main": "main.js","scripts": {"start": "electron .","build": "electron-builder"},"build": {"appId": "com.atguigu.video","win": {"icon": "./logo.ico","target": [{"target": "nsis","arch": ["x64"]}]},"nsis": {"oneClick": false,"perMachine": true,"allowToChangeInstallationDirectory": true}},"devDependencies": {"electron": "^30.0.0","electron-builder": "^24.13.3"},"author": "寶碼香車","license": "ISC","description": "A video processing program based on Electron"
}
根據視頻操作未能完成打包,這種方式在打包時 訪問
github
多次嘗試后,決定放棄
5.2 使用Electron Forge進行打包(使用這種方式打包的)
Electron中文網也推薦使用這種方式。
Electron Forge是從建項目開始配置 的,因為項目已經寫完了,所以從第五步開始。
Electron Forge 從第五步開始的文檔
5.2.1 使用3條命令,完成打包。
1、運行第1條命令
npm install --save-dev @electron-forge/cli
2、運行第2條命令
npx electron-forge import
這時在packgae.json里會增加一些配置。
不用管。
3、直接運行第3條命令
npm run make
打包完成。
5.2.2 打包后的位置,在根項目下的out文件里
打包后的文件,在根項目下的out文件夾里
可運行程序在
my-electron-app\out\make\squirrel.windows\x64
5.2.3 看運行效果,終于完成了。
5.2.4 出現的bug
1.安裝一次后再打開會報錯,
2.直接刪除軟件,目錄在 C:\Users\Administrator\AppData\Roaming
刪除my_electron_app這個文件夾。然后用360安全衛士清理垃圾。然后重啟即可。
其他bug
1.軟件有卡死的現象
2.還會自動重啟
3.軟件關閉后會自動重啟
4.在輸入框中輸入內容,寫入后可能會卡死,第二次可能無法輸入,但可以讀取。
5.啟動時有點卡
六、總結
1.后面有的bug可能與Electron Forge配置有關。有時間試試,找個解決方案。
2.也有可能與main.js寫法有關。
3.打包時刪除main.js里的 win.openDevTools() //自動打開調試窗口
否則軟件會自動打開調試窗口。
4. 代碼倉庫位置 https://gitee.com/electron_9/my-electron-app
終于完成,雖然有bug,但能運行起來了。后續找個更好的解決方案。