Electron/Nodejs開發筆記-功能問題記錄及指南


這篇隨筆記錄一下electron + vue與nodejs 的一些開發的過程和問題..隨緣更新

最近基於Electron做一個針對UE4應用的進程守護和更新啟動器...

花費大量了時間的處理來UI線程堵塞的問題上了(吐槽感覺Nodejs IO和線程不是hin好用..)

涉及的技術點估計以后不會怎么常用,所以寫篇隨筆整理一下

  electron啟動更新器:

    github: https://github.com/linqingwudiv1/electron-startup

----------------------------------------割-------------------------------------------------------------

 

Electron+ Vue環境:

  Vue環境目前有倆個比較好用的開發環境:

    1.electron-vue:    https://github.com/SimulatedGREG/electron-vue

    2.Vue + Vue CLI Plugin Electron Builder

  區別

    electron-vue 是基於vue-cli 2.0的快速開發框架

    Plugin Electron Builder是vue-cli 3.X的electron 腳手架插件.

  我用的是 Electron Builder...

  Vue cli 3.x版本的Vue + Vue CLI Plugin Electron Builder整合的Electron應用

     插件使用文檔    :  https://github.com/nklayman/vue-cli-plugin-electron-builder

        VS Code 斷點調試配置指南:    https://nklayman.github.io/vue-cli-plugin-electron-builder/guide/recipes.html#table-of-contents

    Electron  Vue DevTools配置指南:https://github.com/vuejs/vue-devtools/blob/dev/packages/shell-electron/README.md

參考:

 

 

 Q.開發記錄:

1.electron的渲染進程xmlhttprequest的cors問題/開啟nodejs和Worker線程等:

  win = new BrowserWindow(
  { 
    width: 800, 
    height: 600, 
    backgroundColor: '#ffffff',
    webPreferences: {
      nodeIntegration: true,
      webSecurity: false, //cors
      nodeIntegrationInWorker: true //
    }
  });

 

 2.Nodejs/electron下 解壓zip

使用 adm-zip-ex解壓實例:

const AdmZip = require('adm-zip-ex');
let zip = new AdmZip("d://Test.zip");
zip.extractAllTo('d:/temp');

 adm-zip-ex單個entry的異步解壓示例:

let zip = new AdmZip('c:temp.zip');
let zipEntries = zip.getEntries(); 
zipEntries.forEach( ( zipEntry:any, index:number ) => 
{
    if ( zipEntry == null ) 
    {
      return;
    }
    const entryPath = join( 'c:/',  zipEntry.entryName);
    if ( zipEntry.isDirectory )
    {
      return;
    }
    let path = dirname( entryPath );
    // unzip entry......
    zip.extractEntryToAsync(zipEntry, path , true, (err:any) =>
    {
      if ( err != undefined )
      {
        console.log(err);
        return;
      }
      //do something.....
    
    });
});

 

3.nodejs怎么進行流文件下載:

  用nodejs的http模塊或electron的net模塊都可以,但是太底層了,建議用 request或request-promise庫,是對於nodejs的網絡模塊封裝的,ts版本:@types/request 文檔:https://github.com/request/request

  http下載文件:

request('http://google.com/doodle.png').pipe(fs.createWriteStream('doodle.png'))

  如果有大文件下載需求,請添加 request-progress-ex模塊,跟request組合使用..  

     https://www.npmjs.com/package/request-progress-ex

  附 request-promise幫助類:

import request, { RequestPromiseOptions } from 'request-promise';

let options:RequestPromiseOptions = {
    baseUrl: process.env.APP_BIZ_BASE_API,
    qs: {
        //access_token: 'xxxxx xxxxx' // -> uri + '?access_token=xxxxx%20xxxxx'
    },
    headers: {
        'User-Agent': 'Request-Promise'
    },
    json: true // Automatically parses the JSON string in the response
};

let services =request.defaults(options);
export default services;

 

 

4.worker_threading(線程):

   https://github.com/wilk/microjob/blob/master/GUIDE.md

5.進程通訊的基本例子

 note:也可以使用remote調用main process進程功能或模塊.但是不推薦這么做,因為破壞了electron的封裝性

    https://electronjs.org/docs/api/ipc-main

 

  remote例子:

import {remote} from 'electron';
const { app } = remote;

 

6.electron 怎么系統托盤app?

例子(typescript):

  Browser事件處理:(close事件可以根據自身情況處理)

  GWin.MainWindow是我自己封裝的BrowserWindow類
        GWin.MainWindow.on('minimize',(ev:any)=>
        {
          if (GWin.MainWindow !=null) { console.log('on minimize...'); GWin.MainWindow.setSkipTaskbar(true); GWin.MainWindow.hide(); } ev.preventDefault(); });
          GWin.MainWindow.on('closed', () => {
            GWin.MainWindow = null
          });
 

  

創建系統托盤 tray類:

  electron:隱藏任務欄條 setSkipTaskbar(true)

  electron:顯示任務欄條setSkipTaskbar(false)

  note:注意new Tray('ico.jpg')時,ico.jpg必須存在,否則托盤圖標將不顯示..無法點擊

      GWin.TrayIcon = new Tray('ico.jpg'); 
      const contextMenu = Menu.buildFromTemplate([ { label: '顯示', //type: 'radio', click:()=> { if(GWin.MainWindow != null) { GWin.MainWindow.show(); GWin.MainWindow.setSkipTaskbar(false); } } }, { label: '退出', //type: 'radio' click:()=> { app.quit(); } } ]) GWin.TrayIcon.setToolTip('更新啟動器'); GWin.TrayIcon.setContextMenu(contextMenu);

 

7.NodeJS從文件中讀取json:

ts

let jsonStr:string = readFileSync('UE/version.json', { encoding: 'utf-8' });

js

let jsonStr = fs.readFileSync('UE/version.json', { encoding: 'utf-8' });

 

8.Electron持久化配置到磁盤文件:

  其實可以用nodejs模塊自己IO到json文件,但是比較麻煩,需要自己封裝接口

  而且已經有相關的electron-store類庫了..

    https://github.com/sindresorhus/electron-store

    typescript 版本:

npm install @types/electron-store

  electron-store 每次set 或get都是從disk文件讀寫配置信息

  簡單的使用示例:(建議寫成這樣的單例)

/**
 * Electron-Store的配置內容
 */
 interface SystemStore {
    CacheDir: string;
}

/**
 *  整個App的全局變量,或函數 
 */
export default class GApp
{

    /** 系統持久化配置實例 */
    private static sysStore?:Store<SystemStore> = undefined;
    
    /** Get 系統持久化配置單例 */
    public static get SystemStore():Store<SystemStore>
    {
      if (GApp.sysStore == undefined)
      {
        GApp.sysStore = new Store<SystemStore>({
          defaults: {
            CacheDir: GApp.RootDir + '/cache/'
          }
        });
      }
      return GApp.sysStore;   
    }
}

 

9.Nodejs獲取指定文件的所在目錄:

import {dirname} from 'path';
let dir = dirname(`d:/test/ttt/helloworld.png`);

 

10.Nodejs遞歸創建目錄:

  nodejs 的mkdir()目前還不能 創建多級路徑...

  如C:/a/b/c 如果C:/a/b 路徑還不存在則報錯.. 

  (v13.x)

實現:

  雖然也可以自己寫遞歸調用mkdir(),

  但還是推薦使用 shelljs 類庫 用mkdir腳本創建路徑...(linux環境需要加 -p)

 

 
          
 import { mkdir } from 'shelljs';
  import {existsSync } from 'fs';
 import {resolve} from 'path';
  if (!existsSync( GApp.SystemStore.get('CacheDir') ) )
  {
    let stdout = mkdir('-p', resolve(`路徑`)).stdout;
  }

 

Q.Electron無邊框模式並自定義標題欄:

官方參考:

https://electronjs.org/docs/api/frameless-window

 

Electron自定義標題欄非常簡單..

Step1:開啟無邊框模式:

let win = new BrowserWindow({ titleBarStyle: 'customButtonsOnHover', frame: false })

Step2:render進程編寫標題欄Div和處理事件

並添加關鍵css

    -webkit-user-select : none;
    -webkit-app-region  : drag;

這兩個css屬性會自動識別為可拖拽區,使之能像標題欄一樣隨意移動窗口..

如:

    <div class="titlebar-btn-group">
      <el-button id="btn-close" size="medium" type="text" icon="el-icon-close"></el-button>
    </div>
    width:150px;
    background: green;
    position  : fixed;
    top:10px;
    right :10px;
    -webkit-user-select : none;
    -webkit-app-region  : drag;
    width:150px;
    background: green;
    position  : fixed;
    top:10px;
    right :10px;
    -webkit-user-select : none;
    -webkit-app-region  : drag;

 

Note:

如果只是希望把菜單欄移到標題欄上,推薦使用:
Electron自定義標題欄 (Custom Title Bar)插件:https://github.com/AlexTorresSk/custom-electron-titlebar

如果只是需要自定義拖拽移動區:

 https://github.com/kapetan/electron-drag


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM