原文發表於
https://lleohao.github.io/2017/09/02/如何搭建Electron開發環境/
javascript這個項目結構是我在編寫 基於Electron 和 Angular 的七牛文件上傳App 總結出來的css
本文主要介紹如何從零開始搭建高效的Electron開發環境, 主要內容以下:html
經過合理的目錄劃分來組織代碼前端
使用
npm script
簡化開發java如何在渲染進程開發時使用熱更新node
如何在主進程開發時使用自動重啓webpack
如何在主進程開發時使用
Typescript
git如何打包和發佈軟件es6
示例項目地址 https://github.com/lleohao/el...github
發現 http://hao.jser.com/ 這個網站臭不要臉的轉載文章
首先按照常規的方法新建一個項目文件夾(這裏個人示例文件夾叫作electron-base
, 而後使用npm init
初始化目錄。
目前咱們的開發目錄以下:
electorn-base ├── .gitignore - git忽略文件 ├── LICENSE - 開源協議 ├── README.md - 文檔 └── package.json - npm package
Electron 的開發主要分爲兩個部分, 其中主進程(Main Process)主要負責打開頁面和調用系統底層的資源等, 渲染進程(Renderer Process)則是一個普通的網頁窗口.
兩個進程的開發有着不一樣的開發方式, 主進程更像是傳統Node
的開發, 而渲染進程則是普通的前端開發. 同時它們之間又有着能夠共用的部分(如輔助函數、數據模型等), 所以能夠按照下面的方式劃分
electorn-base ├── ... - 省略 └── src - 代碼源文件 ├── main - 主線程代碼 ├── renderer - 渲染線程 └── shared - 公用代碼
接下來運行npm install electron -D
安裝Electron,同時在package.json
添加main
字段, 這表明整個項目的入口文件,這裏咱們先設置爲src/main/main.js
.
順便添加上兩個文件
# src/main.js const { app, BrowserWindow } = require('electron') const path = require('path') const url = require('url') let win function createWindow() { win = new BrowserWindow({ width: 800, height: 600 }) win.loadURL(url.format({ pathname: path.join(__dirname, '../renderer/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() } })
<!-- src/renderer/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 .
(或者是./node_modules/.bin/electron .
)啓動程序
爲了之後方便啓動程序, 將這段命令添加到package.json
中
// package.json 部份內容 "main": "src/main/main.js", "scripts": { "start": "./node_modules/.bin/electron ." }, "devDependencies": { "electron": "^1.7.5" }
渲染線程的開發跟普通的前端開發沒有多大的區別, 爲了開發的效率, 咱們一般會選擇一款前端開發框架, 這裏我選擇的是Angular
, 固然也能夠選擇其餘的框架, 只須要按照下文中的要求修改打包路徑.
這裏我使用Angular-cli
工具來初始化項目
安裝cli工具
`npm install -g @angular/cli`
初始化目錄
` ng new electron-base -sd src/renderer -si -sg -st --routing true --styles scss `
修改.angular-cli.json
"apps": [{ "root": "src/renderer", // 源文件目錄 "outDir": "out/renderer", // 輸出目錄 "baseHref": "./", // 解決打包後沒法加載文件 ... }]
前端開發中, 咱們可使用webpack
享受到自動刷新、熱更新等方便的功能, 那麼在Electron的開發過程咱們如何享受的到這些功能了?這裏咱們只須要簡單的修改下main.js
文件便可
function isDev() { return process.env['NODE_ENV'] === 'development' } function createWindow() { win = new BrowserWindow({ width: 800, height: 600 }) if (isDev()) { // 這裏的url換成你所使用框架開發時的url win.loadURL('http://127.0.0.1:4200'); } else { win.loadURL(url.format({ pathname: path.join(__dirname, '../renderer/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 }) }
開發時咱們仍是按照之前的方式啓動一個webpcak
服務器進行開發, Electron經過HTTP
協議打開頁面, 這樣咱們依舊能夠享受到代碼熱更新等功能.
經過設置環境變量NODE_ENV
來區分開發和生成環境, 在package.json
中添加兩個命令來方便開發
"scripts": { "ng": "ng", // angular alias "start": "NODE_EBV=production ./node_modules/.bin/electron .", // 添加環境變量 "dev:renderer": "ng serve" // 啓動渲染線程開發服務器 },
開發完成後咱們須要將前端的代碼進行代碼打包, 一個好的習慣是將代碼的打包目錄放置在項目的根目錄中, 這裏我將前端的打包目錄設置在out/renderer
中
Angular項目只須要修改.angular-cli.json
中的outDir
字段, 其餘的框架能夠自行修改.
在package.json
中添加打包命令
"scripts": { .... "build:renderer": "ng buidl --prod" // 打包渲染線程代碼 },
主線程的開發如Node
程序的開發沒有多大的區別, 這裏就很少贅述.
雖然Node
對ES6
的支持已經很完善了, 但更新的標準的支持就不怎麼好, 這裏咱們可使用Babel
之類的工具進行來使用最新的語法.
這裏我推薦使用Typescript
, 優勢主要有三個:
靜態檢查, 畢竟是主線程的代碼, 有點錯誤可就是程序直接崩潰的節奏
自動提示, 這個不解釋
編譯方便, 比起Babel
的配置文件, Typescript
的配置要簡單的多
安裝Typescript
運行npm install typescript -D
添加配置文件, 在src
目錄下添加tsconfig.main.json
文件
{ "compilerOptions": { "outDir": "../out", // 輸出目錄, 同渲染線程放在一塊兒 "sourceMap": true, // 調試時須要 "moduleResolution": "node", "emitDecoratorMetadata": true, "experimentalDecorators": true, "target": "es6", // 輸出代碼版本, 因爲在Node中運行, es6沒問題 "module": "commonjs", // module 處理方式 "typeRoots": [ // .d.ts 目錄 "../node_modules/@types" ], "lib": [ // 可選, 添加新的語法支持 "es2017" ] }, "exclude": [ // 排除渲染線程目錄 "renderer" ] }
在package.json
中添加開發和打包命令
"scripts": { ... "dev:main": "tsc -p ./src/tsconfig.main.json -w", // 開發 "build:main": "tsc -p ./src/tsconfig.main.json" // 打包 }
添加啓動配置文件, 項目根目錄新建.vscode
文件夾,在其中新建launch.json
{ // Use IntelliSense to learn about possible Node.js debug attributes. // Hover to view descriptions of existing attributes. // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [{ "type": "node", "request": "launch", "name": "Launch Program", "cwd": "${workspaceRoot}", "runtimeExecutable": "${workspaceRoot}/node_modules/.bin/electron", "program": "${workspaceRoot}/src/main/main.ts", // 你的主文件 "sourceMaps": true, "outFiles": [ "${workspaceRoot}/out/**/*.js" // 你的輸出文件目錄 ], "env": { "NODE_ENV": "development" } }] }
使用組合鍵ctrl + f5
啓動程序
在文件中添加斷點進行調試
咱們的渲染線程能夠作到代碼變動後自動刷新頁面, 在主線程的開發中咱們可使用 nodemon 來實現一樣的功能
安裝nodemon
npm install nodemon -D
修改啓動命令
"scripts": { "start": "nodemon --watch src/main --watch src/shared --exec './node_modules/.bin/electron' ./out/main/main.js" }
之後開發時只須要運行npm start
就可作到主線程的自動刷新
主線程的開發過程咱們可能會使用其餘的構建工具, 這裏咱們同渲染線程同樣, 將主線程的打包文件放在out
目錄中, 至此打包目錄的結構應當以下
out ├── main - 主線程打包文件位置 │ └── main.js - 入口文件 ├── renderer - 渲染線程打包位置 │ ├── .... │ └── index.html - 入口頁面 └── shared - 公用文件 └── utils.js
electron-builder 能夠將咱們的程序打包成可執行文件, 它的配置信息發在package.json
中
這裏配置的是Mac
的打包信息, 具體的能夠自行查閱文檔
{ "main": "out/main/main.js", // 入口文件 "scripts": { ... "pack": "electron-builder -m --dir", // 簡單打包軟件, 用於測試 "dist": "electron-builder -m", // 正式打包軟件 "build": "npm run build:renderer && npm run build:main && npm run dist" // 打包軟件 }, "build": { "appId": "com.lleohao.sample", // 自行修改 "mac": { "category": "public.app-category.productivity" // 自行修改 } } }
運行npm build
便可打包軟件
運行npm run dev:renderer
啓動渲染線程開發
運行npm run dev:main
啓動主線程開發
運行npm start
打開Electron
程序
運行npm build
打包程序