electron開發過程中遇到的一些坑

在公司開發的下載器過程中,遇到的一些坑點

electron中彈窗的確認取消以及系統自帶的叉號之間的關係

場景:在用戶退出app時,需要提示用戶是否確認退出,此時彈窗出現,如果點擊確認就繼續退出,執行回調,否則的話,不退出

問題:點擊叉號的時候,回調中返回的值是0,由於代碼中寫的buttons順序爲['確認', '取消'],點擊“確認”的時候對應的response也是0,就導致了點擊“確認”和點擊叉號的行爲一致,這樣的話是不正確的,點擊叉號應該等同於取消退出。

// 問題代碼,點擊確認按鈕會退出,點擊右上角叉號也會退出
dialog.showMessageBox(mainWindow, { buttons: ['確認', '取消'] }, (response) => {      if (reponse === 0) {
    // 執行退出操作
  } 
});
// 修改後代碼,點擊確認退出,點擊右上角叉號不退出
dialog.showMessageBox(mainWindow, { buttons: ['取消', '確認'] }, (response) => {
  if (response === 1) { 
    // 執行確認退出操作
  } 
});

打包後子進程中的代碼沒有執行的問題

場景:在本地開發過程中,使用子進程去下載資源,能夠正常的下載,但是打包之後,發現下載不了,子進程中的事件沒有執行。導致下載流程受阻

問題:electron中使用到子進程的時候,是把子進程當作一個外部依賴來做的,打包後並不會將子進程的代碼打進到包中,需要額外進行配置。
解決方式:對子進程文件進行額外配置

注:本項目腳手架基於electron-vue,配置文件和electron-vue保持相同

  1. 打包配置:asarUnpack 這個配置是用來將子進程中用的一些第三方包進行整理,否則子進程找不到這些包,就跑不起來。子進程中用的第三方包都需要在asarUnpack中進行配置。
    extraResources 這個配置用來將我們的代碼子進程文件所在目錄,打包出來放在一個指定的地方,在代碼中有需要引用子進程文件的地方,就用這個地址去找對應的js文件,因爲開發和打包後的路徑是不一樣的,具體package.json配置如下

        "mac": {
          "icon": "build/icons/icon.icns",
          "extendInfo": {
            "CFBundleURLSchemes": [
              "link"
            ]
          },
          "asarUnpack": [
            "**/node_modules/electron-log/**/*",
            "**/node_modules/unzipper/**/*",
            "**/node_modules/axios/**/*",
            "**/node_modules/archiver/**/*"
          ],
          "extraResources": [
            {
              "from": "src/main",
              "to": "app.asar.unpacked/download"
            }
          ]
        },
        "win": {
          "icon": "build/icons/icon.ico",
          "asarUnpack": [
            "**/node_modules/electron-log/**/*",
            "**/node_modules/unzipper/**/*",
            "**/node_modules/axios/**/*",
            "**/node_modules/archiver/**/*"
          ],
          "extraResources": [
            {
              "from": "src/main",
              "to": "app.asar.unpacked/download"
            }
          ],
          "target": [
            {
              "target": "nsis",
              "arch": [
                "x64"
              ]
            }
          ]
        }
  2. 子進程fork路徑:electron中開發和打包後子進程的fork路徑並不相同,開發時候,可以直接使用當前路徑進行引用,但是打包後子進程js文件直接通過相對路徑就獲取不到了。所以fork子進程的時候路徑需要如下配置,process.resoucesPath: electron中定義的資源目錄的路徑,在打包後子進程js所在的路徑。

    let isDev = process.env.NODE_ENV !== 'production';
    let scriptPath = isDev ? path.join(__dirname, 'child_download_serial.js') : path.join(process.resourcesPath, 'app.asar.unpacked/download/child_download_serial.js');

上面兩步做完了,打包完畢後可以在安裝後的安裝包下看到自己子進程的代碼目錄,此時說明配置成功,並且子進程和主進程能夠正常通信了。Xnip2019-08-01_10-03-38

以上方案在windows下和mac下都適用

子進程中的log輸出不了

場景:想看一下子進程中輸出的log,查看子進程的執行情況

問題:子進程的console在控制檯中看不到,因爲子進程和父進程是分開的,我們只能看到父進程的輸出

解決方式:拿到子進程後,在父進程中監聽子進程的stdout.on('data')事件,這樣在子進程中的所有console.log在父親進程中都會觸發data事件,父進程可以輸出子進程的console內容。注意fork的時候需要給一個silent:true的配置,如果爲 true,則子進程的 stdin、stdout 和 stderr 將會被輸送到父進程,否則它們將會繼承自父進程。同理,也可以監聽子進程的stderr的data事件,可以捕獲到子進程的錯誤

childDownload = fork(scriptPath, [], { silent: true });
childDownload.stdout.on('data', data => {
  console.log('子進程的console', data.toString());
});

electron閃退的問題

場景:在退出軟件的時候,由於代碼原因報了一個錯誤,然後軟件成功關閉,但是當再次手動打開軟件時,出現閃退情況

問題:主進程出錯後,沒有對錯誤進行捕獲,導致再次打開軟件依然有這個錯誤存在,軟件打不開

解決方式:全局進行一個錯誤捕獲,避免某些情況下的錯誤未捕獲導致閃退打不開軟件的問題

// 必要的全局錯誤捕獲
process.on('uncaughtException', error => {
  log.error(error.stack || JSON.stringify(error));
  app.exit();
});

web端喚醒客戶端覆蓋問題

場景:錯題本下載器安裝後,再安裝錯題本logger工具,此時再web中點擊喚醒下載工具,喚醒的是錯題本logger工具

問題:再兩者打包的時候,對應的appId都是相同的,導致後安裝的軟件將前安裝的軟件給頂替了,當再網頁中喚醒的時候,就將替換後的軟件喚醒了

解決方式:package.json中的appId保證唯一性

原文鏈接:https://github.com/chaijinson... 持續更新

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章