1. 程式人生 > 實用技巧 >Node.js 針對不同平臺實現electron的自動過載

Node.js 針對不同平臺實現electron的自動過載

原始碼

/**
 * 針對不同平臺實現自動過載.
 * 在Windows平臺下通過使用taskkill /IM electron.exe /F命令強制關閉electron程序.
 */
const fs = require('fs');
const child_process = require('child_process');
const _ = require('lodash');

const rules = [
    { event: 'change', test: /^.*\.js$/ },
];

/**
 * 監聽原始碼檔案事件
 * @param {String} dir 要監聽的目錄, 子目錄下的檔案不會被監聽
 * @param {Array} rules 規則陣列, 每個規則是包含了"事件名"字串和"檔名"正則表示式兩個欄位的物件: { event, test }
 */
function watch_source_code_file(dir, rules) {
    // 遞迴地監視僅在Windows和OSX系統上支援。 這就意味著在其它系統上要使用替代方案。
    fs.watch(dir, { recursive: true }, (event, filename) => {
        rules.forEach(it => {
            if (event === it.event && it.test.test(filename)) {
                _handler(event, filename); // 如果原始碼發生了變化, 則執行_handle()函式的相關邏輯
            }
        });
    });

    // 一次"儲存檔案"的操作可能觸發多次"change"事件, 因此使用Lodash提供的函式去抖動功能
    const _handler = globalThis._handler || (globalThis._handler = _.debounce(handler, 800, { leading: true, trailing: false, }));
}

/** 編碼electron主程式相關檔案變化應該執行的操作 */
function handler(event, filename) {
    reload_electron();
}

/** 重啟electron主程式, 請呼叫者捕獲異常 */
function reload_electron() {
    try {
        kill_electron();
    } catch (error) {
        console.error(error);
        console.log('未能成功關閉electron程序, 或electron程序不存在');
    }
    start_electron();
}

/** 不同平臺下關閉electron程序的實現 */
function kill_electron() {
    if (process.platform.match(/^win.*/)) { // Implement this on Windows OS
        // child_process.execSync(`taskkill /PID electron.exe /F`);
        child_process.execSync(`taskkill /IM electron.exe /F`);
    } else if (process.platform.match(/^linux.*/)) { // Implement this on Linux OS
        globalThis.electron && globalThis.electron.kill();
    }
}

/** 不同平臺下啟動electron程序的實現 */
function start_electron() {
    if (process.platform.match(/^win.*/)) { // Implement this on Windows OS
        const cmd = `start cmd /c electron "${__dirname}/main.js"`;
        child_process.exec(cmd);
    } else if (process.platform.match(/^linux.*/)) { // Implement this on Linux OS
        const cmd = `bash -c 'electron "${__dirname}/main.js"'`;
        globalThis.electron = child_process.exec(cmd); // Linux下可以記錄PID以kill程序, 當然也可以使用"pkill -ef electron"命令
    }
}

/** 主程式 */
function main() {
    watch_source_code_file(__dirname, rules); // 監聽專案根目錄, 不含子目錄, 規則在rules中定義
    start_electron();
}

main();