1. 程式人生 > >electron 打包web應用

electron 打包web應用

時下流行的web app打包工具主要有兩個,一個是國內開發者主導的nw.js,另一個是國外大廠支撐的electron。對比了nw.js以及electron之後還是選擇了electron,原因主要有以下幾點:

  • 1、基於該工具已有廣泛被使用的產品,如:atomvs code等。
  • 2、在開發者中口碑比較好,有大公司參與進來,遇到問題,提個issue能很快得到響應。

下載基於electron打包的HolaStudio

使用webpack編譯專案

HolaStudio離線版本打包的時候需要把伺服器、客戶端打包到一個安裝包內。所以第一步首先要把伺服器程式碼混淆,為接下來打包做準備。

構建工具選擇了webpack, 關於構建工具沒有做很細緻的篩選,因為我都不熟悉:)。所以就聽從朋友建議,選擇了入了webpack的坑。

關於webpack的使用,官方有詳細的文件說明,github自行搜尋。

webpack需要一個配置檔案(webpack.config.js),用來描述專案的環境,以及第三方外掛的整合等資訊:


var webpack = require('webpack');
var path = require('path');
var fs = require('fs-extra');
var packageJSON = fs.readJsonSync('./package.json'
); var nodeModules = {}; fs.readdirSync('./node_modules') .filter(function(x) { return ['.bin', '.npminstall'].indexOf(x) === -1; }) .filter(function(y) { return !(y in packageJSON.devDependencies); }) .forEach(function(mod) { nodeModules[mod] = 'commonjs ' + mod; }); module.exports = { entry: './app.js'
, target: 'node', context: __dirname, node: { __dirname: false, __filename: false }, output: { path: path.join(__dirname, 'output'), filename: 'output.js', externals: nodeModules, }, externals: nodeModules, plugins: [ new webpack.optimize.UglifyJsPlugin({compress: {warnings: false}}), new webpack.IgnorePlugin(/\.(css|less)$/) ] }

簡要的說明:
- entry: 指定專案的入口檔案,即啟動node服務指定的檔案
- target: 指定當前的編譯環境為node, 其他選擇有webwebworker
- context: 指定一個路徑找到entry檔案
- node: 用於指定一些nodejs環境配置 __dirname=false 表示啟用__dirname 變數(預設為’/’), __filename=false 表示啟用__filename 變數(預設為’/index.js’)。
- output: 指定編譯輸出檔案及目錄
- externals: 指定外部依賴庫檔案
- plugins: webpack外掛整合,這裡主要用到了一個混淆外掛

執行 webpack . 會在當前目錄下的output 資料夾得到編譯輸出檔案。

安裝electron以及相關工具

  • 執行命令npm i -g electron-prebuilt 安裝electron

簡要說說關於electron的設計理念:

electron打包的應用分為主程序和渲染程序,渲染程序使用Chromium來展示頁面,主程序以類似建立視窗的方式建立網頁。主程序具備呼叫系統相關服務的功能,主程序和渲染程序之間以程序間通訊的方式互動。 更詳細的electron說明文件.

在打包HolaStudio的過程中,選擇把node服務端程式碼放在主程序,編輯器放在一個渲染程序。

electron專案的構建目錄結構:
圖1

在該目錄下執行electron .即可調式electron應用。

所以在啟動electron應用的過程中,需要啟動node後臺的同時建立一個渲染視窗顯示編輯器。


//處理windows 應用安裝以及更新時刻的預設事件  
if(require('electron-squirrel-startup')) return;

var app = require('app');
var path = require('path');
var electron = require('electron');
var BrowserWindow = require('browser-window');
var globalShortcut = require('global-shortcut');

var mainWindow = null;
var webContents = null;

//所有視窗被關閉
app.on('window-all-closed', function() {
  // 在 OS X 上,通常使用者在明確地按下 Cmd + Q 之前
  // 應用會保持活動狀態
    if(process.platform != 'darwin') {
        app.quit();
    }
});

//當前應用準備退出
app.on('will-quit', function() {
    globalShortcut.unregisterAll();
});

// 當 Electron 完成了初始化並且準備建立瀏覽器視窗的時候
app.on('ready', function() {
    global.mainProcess = app;
    require('./hola_studio.js');
    registerShortcut();
});

//hola_studio 伺服器發出`done`事件後,準備渲染編輯器介面
app.on('done', function(url) {
    var electronScreen = electron.screen;
    var size = electronScreen.getPrimaryDisplay().workAreaSize;
    mainWindow = new BrowserWindow({resizable: true, width: size.width, height: size.height,
        title: 'HolaStudio'});
    mainWindow.loadURL(url);
    webContents = mainWindow.webContents;
    mainWindow.on('closed', function() {
        mainWindow = null;
        webContents = null;
    });
});

//註冊快捷鍵用於開啟開發者工具以及重新整理當前頁面
function registerShortcut() {
    function doRegister(cmd, callback) {
        globalShortcut.register(cmd, callback);
    }

    doRegister('F12', function() {
        var win = BrowserWindow.getFocusedWindow();
        win.webContents.toggleDevTools();
        console.log("toggleDevTools F12");
    });

    //windows 平臺下`F12`按鍵按下收不到訊息(貌似還沒有解決方案),所以寫了一個替代按鍵
    doRegister('F6', function() {
        var win = BrowserWindow.getFocusedWindow();
        win.webContents.toggleDevTools();
        console.log("toggleDevTools F6");
    });

    doRegister('F5', function() {
        var win = BrowserWindow.getFocusedWindow();
        win.reload();
        console.log("refresh");
    });

    return;
}

如果之前有做過MFCQT類GUI的開發,對electron這樣的工作流程一定非常熟悉。

安裝electron-builder工具來編譯安裝包

electron-builder把幾個不同平臺的安裝包編譯工具整合到一起,得到一個統一的介面,方便使用。

electron-builder 建議把構建目錄分為兩層,上面一層主要管理編譯工具、構建所需的資源以及構建的輸出,稱之為dev 目錄。下面一層則為以electron為入口的工程目錄,稱之為app 目錄。

dev目錄預覽:

圖3

app目錄預覽:
圖4

需要做的工作很簡單:
- 安裝構建工具(electron、electron-prebuilder)
- 修改dev目錄下package.json指定編譯指令碼
- 修改app目錄下package.json指定編譯選項
- 執行指令碼編譯安裝包

dev 目錄下package.json預覽:

{
  "name": "HolaStudio",
  "version": "0.0.1",
  "homepage": "http://studio.holaverse.cn",
  "description": "HolaStudio Release Version.",
  "scripts": {
    "dist": "npm run dist:linux && npm run dist:win",
    "dist:osx": "build --platform darwin --arch all -d",
    "dist:win": "build --platform win32 --arch all -d",
    "dist:linux": "build --platform linux --arch all -d"
  },
  "keywords": [
    "HolaStudio"
  ],
  "author": "holaverse Tech Inc.",
  "license": "ISC",
  "devDependencies": {
    "electron-builder": "^2.11.0",
    "electron-prebuilt": "^0.37.2"
  },
  "build": {
    "osx": {
      "title": "HolaStudio",
      "background": "build/background.png",
      "icon": "build/icon.icns",
      "icon-size": 128,
      "contents": [
        {
          "x": 355,
          "y": 125,
          "type": "link",
          "path": "/Applications"
        },
        {
          "x": 155,
          "y": 125,
          "type": "file"
        }
      ]
    }
  }
}
  • scripts欄位指定npm編譯不同平臺的執行指令碼。
  • build指定編譯時載入的資源配置

app 目錄下package.json增加編譯時配置選項(最新版本electron-builder已經把它提出到dev目錄下的package.json)
javascript
"build": {
"asar": false,
"iconUrl": "http://7xsec6.com1.z0.glb.clouddn.com/icon.ico",
"app-bundle-id": "holaverse.studio",
"app-category-type": "public.app-category.productivity"
},

- asar告訴打包工具,不要壓縮資原始檔,因為在HolaStudio執行過程中,需要頻繁改動專案路徑下檔案。
- iconUrl指定windows安裝包icon url
- app-bundle-id/public.app-category.productivity,mac平臺下編譯選項

更詳細的配置文件請看這裡

成功打包了各種平臺的安裝包後,後續需要做的是閱讀electron文件,在有新需求的時候能夠很快的處理掉。