zoukankan      html  css  js  c++  java
  • Node.js 针对不同平台实现electron的自动重载

    前言

    大前端目前发展处于高度自动化中, webpack-dev-server这样的工具提供了向HTML注入一段监听WebSocket的JavaScript代码来实现前端界面的热加载.
    但是对于electron主进程electron-main来说, 实现这种代码修改立即重启进程的功能是比较难实现的.
    但也不是完全没有办法, 今天, 我们使用Node.js标准模块fs来实现监听源码并自动重启electron进程.

    使用fs.watch()

    fs.watch()函数监听系统文件事件, Linux下无法递归地监听一个目录, 共包括renamechange两种事件, 一次文件读写过程会触发多次change事件.

    fs.watch(dir, { recursive: false }, (event, filename) => {
          // ...根据事件类型和文件名判断是否应该采取何种措施
    });
    

    Windows平台下强制关闭进程: taskkill

    Linux下可以向进程调用kill()函数发送信号, 或者使用pkill -ef electron这样的命令来完成, 而Windows下只能使用taskkill命令:

    > taskkill /IM electron.exe /F
    

    其中IM代表"Image", 映像名称.

    源码auto-reload.js

    /**
     * 针对不同平台实现自动重载.
     * 在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"'`; // 这里或许需要使用exec命令替换父进程, 以直接获取electron进程
            globalThis.electron = child_process.exec(cmd); // Linux下可以记录PID以kill进程, 当然也可以使用"pkill -ef electron"命令
        }
    }
    
    /** 主程序 */
    function main() {
        watch_source_code_file(__dirname, rules); // 监听项目根目录, 不含子目录, 规则在rules中定义
        start_electron();
    }
    
    main();
    
  • 相关阅读:
    python基础_字典_列表_元组考试_day4
    基本数据类型-列表_元组_字典_day4
    python基础-基本数据类型总结_整型(int)_字符型(str)_day3
    python基础-range用法_python2.x和3.x的区别
    python基础--基本数据类型考试_day3
    批量创建文件和修改文件
    批量建立用户及密码
    打印九九乘法表
    Error Code : 1456 Recursive limit 0 (as set by the max_sp_recursion_depth variable) was exceeded for routine pro_app_rs_right_update···
    mysql 创建视图出现1349 View's SELECT contains a subquery in the FROM clause解决办法
  • 原文地址:https://www.cnblogs.com/develon/p/13601555.html
Copyright © 2011-2022 走看看