本文最后更新于:2023年10月10日 晚上
环境配置 安装node
首先安装node
官方下载最新版本:https://nodejs.org/en/download 官方下载历史版本:https://nodejs.org/en/download/releases 根据系统下载相应系统的 node 文件,选择 LTS 版本 Windows 下载 64 位 Windows Installer (.msi)
,MAC 下载 node-v18.18.0.pkg
安装好了执行以下命令查看 node 版本和 npm 版本
1 2 3 4 5 ➜ electron_demo node -v v16.13.2 ➜ electron_demo npm -v 8.1.2 ➜ electron_demo
安装electron
新建一个文件夹electron_demo
,进入文件夹npm init -y
1 2 3 4 5 6 7 8 9 10 11 12 { "name" : "electron_demo" , "version" : "1.0.0" , "description" : "" , "main" : "index.js" , "scripts" : { "test" : "echo \"Error: no test specified\" && exit 1" } , "keywords" : [ ] , "author" : "" , "license" : "ISC" }
安装electron
1 2 3 4 npm install --save-dev electron yarn add --dev electron
增加运行命令
1 2 3 4 } "scripts" : { "dev" : "electron ." }
新建主进程 index.js 任何 Electron 应用程序的入口都是 main 文件。 这个文件控制了主进程,它运行在一个完整的 Node.js 环境中,负责控制您应用的生命周期,显示原生界面,执行特殊操作并管理渲染器进程
新建 index.html
1 2 3 4 5 6 7 8 9 10 11 12 13 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" /> <meta name ="viewport" content ="width=device-width, initial-scale=1.0" /> <title > hello world</title > </head > <body > <h1 > hello world</h1 > <h2 > 首次加载</h2 > <script src ="./renderer.js" > </script > </body > </html >
新建 index.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 const { app, BrowserWindow } = require ("electron" );const path = require ("node:path" );const createWindow = ( ) => { const mainWindow = new BrowserWindow ({ width : 800 , height : 600 , webPreferences : { preload : path.join (__dirname, "preload.js" ), }, }); mainWindow.loadFile ("index.html" ); }; app.whenReady ().then (() => { createWindow (); app.on ("activate" , () => { if (BrowserWindow .getAllWindows ().length === 0 ) createWindow (); }); }); app.on ("window-all-closed" , () => { if (process.platform !== "darwin" ) app.quit (); });
新建 preload.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 window .addEventListener ("DOMContentLoaded" , () => { const replaceText = (selector, text ) => { const element = document .getElementById (selector); if (element) element.innerText = text; }; for (const dependency of ["chrome" , "node" , "electron" ]) { replaceText (`${dependency} -version` , process.versions [dependency]); } });
自动重启
并修改 package.json 文件
1 2 3 4 5 6 ..."scripts" : { "test" : "echo \"Error: no test specified\" && exit 1" , "dev" : "nodemon --exec electron ." }, ...
然后添加 nodemon.json 配置文件
1 2 3 4 5 6 7 8 9 10 11 12 { "ignore" : [ "node_modules" , "dist" ] , "colours" : true , "verbose" : true , "watch" : [ "*.*" ] , "ext" : "html,js,css" }
主进程设置窗口的位置,并且让窗口置顶,这样不会遮挡vscode编辑器和位置
1 2 3 4 5 6 7 8 9 10 11 12 const mainWindow = new BrowserWindow ({ width : 800 , height : 600 , alwaysOnTop : true , x : 1200 , y : 100 , webPreferences : { preload : path.join (__dirname, "preload.js" ), }, });
安全策略 因为 Electron 项目可以执行javascript代码,也可以访问用户电脑的文件系统,所以访问任何不受信任的内容都可能带来安全隐患。
错误报告
CSP 内容安全策略(CSP) 是应对跨站脚本攻击和数据注入攻击的又一层保护措施。 我们建议任何载入到Electron的站点都要开启。
1 2 3 4 <meta http-equiv ="Content-Security-Policy" content ="default-src 'self'; script-src 'self'" /> <meta http-equiv ="Content-Security-Policy" content ="default-src 'self' *.tanghailong.com; script-src '*.pythl.com'" />
打包分发应用程序 最快捷的打包方式是使用 Electron Forge 。
1 2 3 4 5 6 7 8 9 10 11 12 13 npm install --save-dev @electron-forge/cli ➜ electron_demo npx electron-forge import ✔ Checking your system ✔ Locating importable project ✔ Processing configuration and dependencies ✔ Installing dependencies ✔ Copying base template Forge configuration ✔ Fixing .gitignore ✔ Finalizing import › We have attempted to convert your app to be in a format that Electron Forge understands. Thanks for using Electron Forge!
使用 Forge 的 make 命令来创建可分发的应用程序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 ➜ electron_demo git:(master) ✗ npm run make > electron_demo@1.0.0 make > electron-forge make ✔ Checking your system ✔ Loading configuration ✔ Resolving make targets › Making for the following targets: zip ✔ Running package command ✔ Preparing to package application ✔ Running packaging hooks ✔ Running generateAssets hook ✔ Running prePackage hook ✔ Packaging application ✔ Packaging for arm64 on darwin [2s] ✔ Running postPackage hook ✔ Running preMake hook ✔ Making distributables ✔ Making a zip distributable for darwin/arm64 [8s] ✔ Running postMake hook › Artifacts available at: /Users/wslh/electron_demo/out/make ➜ electron_demo git:(master) ✗ npm run make > electron_demo@1.0.0 make > electron-forge make ✔ Checking your system ✔ Loading configuration ✔ Resolving make targets › Making for the following targets: zip ✔ Running package command ✔ Preparing to package application ✔ Running packaging hooks ✔ Running generateAssets hook ✔ Running prePackage hook ✔ Packaging application ✔ Packaging for arm64 on darwin [2s] ✔ Running postPackage hook ✔ Running preMake hook ✔ Making distributables ✔ Making a zip distributable for darwin/arm64 [7s] ✔ Running postMake hook › Artifacts available at: /Users/wslh/electron_demo/out/make
最后 package.json 内容如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 { "name" : "electron_demo" , "version" : "1.0.0" , "description" : "" , "main" : "index.js" , "scripts" : { "test" : "echo \"Error: no test specified\" && exit 1" , "dev" : "electron-forge start" , "package" : "electron-forge package" , "make" : "electron-forge make" } , "keywords" : [ ] , "author" : "" , "license" : "ISC" , "devDependencies" : { "@electron-forge/cli" : "^6.4.2" , "@electron-forge/maker-deb" : "^6.4.2" , "@electron-forge/maker-rpm" : "^6.4.2" , "@electron-forge/maker-squirrel" : "^6.4.2" , "@electron-forge/maker-zip" : "^6.4.2" , "@electron-forge/plugin-auto-unpack-natives" : "^6.4.2" , "electron" : "26.3.0" } , "dependencies" : { "electron-squirrel-startup" : "^1.0.0" } }
项目目录结构如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ➜ electron_demo git:(master) ✗ tree -L 3 -I "node_modules" . ├── forge.config.js ├── index.html ├── index.js ├── out │ ├── electron_demo-darwin-arm64 │ │ ├── LICENSE │ │ ├── LICENSES.chromium.html │ │ ├── electron_demo.app │ │ └── version │ └── make │ └── zip ├── package-lock.json ├── package.json └── preload.js
打开打包的软件
调试配置 下面介绍在vscode中调试electron项目,微软有一个仓库 vscode-recipes 提供了vscode的 launch.json 常用开发语言的配置。
首先在 vscode 中创建 launch.json 文件,Mac(commad+shift+d),windows(ctrl+shift+d),选择 node
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 { "version" : "0.2.0" , "configurations" : [ { "type" : "node" , "request" : "launch" , "name" : "Electron: Main" , "runtimeExecutable" : "${workspaceFolder}/node_modules/.bin/electron" , "runtimeArgs" : [ "--remote-debugging-port=9223" , "." ] , "windows" : { "runtimeExecutable" : "${workspaceFolder}/node_modules/.bin/electron.cmd" } } , { "name" : "Electron: Renderer" , "type" : "chrome" , "request" : "attach" , "port" : 9223 , "webRoot" : "${workspaceFolder}" , "timeout" : 30000 } ] , "compounds" : [ { "name" : "Electron: All" , "configurations" : [ "Electron: Main" , "Electron: Renderer" ] } ] }
多进程模型 Electron 将使用两种类型的进程:主进程ipcMain 和 渲染器进程ipcRenderer 。
主进程 每个 Electron 应用都有一个单一的主进程,作为应用程序的入口点。 主进程在 Node.js 环境中运行,这意味着它具有使用 Node.js API 的能力。
主进程的主要目的是使用 BrowserWindow 模块创建和管理应用程序窗口。
渲染器进程 每个 Electron 应用都会为使用 BrowserWindow
打开的窗口生成一个单独的渲染器进程。
默认情况下渲染进程与主进程使用 preload.js预加载做为通信桥梁。
预加载脚本 预加载(preload)脚本包含了那些执行于渲染进程中,且先于网页内容开始加载的代码 。这些脚本虽运行于渲染器的环境中,却因能访问有限的 Node.js、Electron高级权限。
因为Electron项目与其他桌面应用是有区别的,他具有浏览器的特性,所以开放主进程的node.js给渲染进程,是有安全隐患的。默认electron是不会开放高级权限给渲染进程,而是要求开发者自行决定渲染进程可以使用哪些主进程任务,这块功能就要在预加载脚本中完成。
预加载脚本像一个桥接器,用于渲染脚本renderer.js与main.js脚本的连接。
d