使用nodejs编写go的重载功能(内涵node的child_process与fs)下

69 阅读2分钟

接着上文,最大坑也纠结了我很久的坑

在此最大的坑是当你修改文件监听调用一次start()函数表面上是重启了,实际上该run 出的main.exe程序并没有结束

image.png

在go run 之后如果你设置的是 r.Run(":port") 会弹出防火墙 显示一个路径 C:\users\14199\appdata\local\temp\go-build2396350469\b001\exe\main.exe

探索该路径会找到exe文件

image.png

go run 之后会自动生成一个go-buildxxxx文件夹 在这个文件夹在有exe文件 而启动的正事这个程序 当你调用start()你会发现文件内容并没有修改 因为该文件并没有删除

在正常的ctrl c之后该文件夹会被自动删除 所以我们需监听到改动之后 关闭该进程 在启动该进程

function debound(e, f) {
  if (time) return
  time = true
  setTimeout(() => { 
    time = false
  }, 100)
  //执行杀死main 进程的cmd指令
  exection('taskkill /f /im main.exe /t')
    start()
}

taskkill为window 杀死进程的命令 /f为强行终止 /imw为指定终止的映像名称 main.exe就是名称拉 最后/t终止其子进程

接下来记录走向的歪路

1.当初还想用node fs模块直接遍历递归直接删除该exe文件

2.直接调用processID.kill()方法

第二个错误点在于exec生成的是cmd进程 关闭cmd 进程够go run 的main进程依然没有关闭

exec与execFile api区别也在于此 后者不会创建一个cmd进程

最终代码

const fs = require("fs");
const path = require("path");
const { exec } = require("child_process");
//获取当前文件夹路径
let filePath = path.join(__dirname, "./");
//防抖参数
let time = false;
//exec 的cmd进程对象
let processID = null;
//执行进程
function exection(cmd) {
  return exec(cmd, (err, stdout, stderr) => {
    if (err) {
      // start()
      console.log(stderr);
      return;
    }
    console.log(stdout);
  });
}
//启动
function start() {
  processID = exection("go run .");
  processID.stderr.on("data", (chunk) => {
    console.log(chunk);
  });
  processID.stdout.on("data", (chunk) => {
    console.log(chunk);
  });
}
function debound(e, f) {
  if (time) return;
  time = true;
  setTimeout(() => {
    time = false;
  }, 100);
  //执行杀死main 进程的cmd指令
  exection("taskkill /f /im main.exe /t");
  start();
}
start();
//监听文件
fs.watch(filePath, { recursive: true }, (eventType, fileName) => {
  if (eventType === "change") {
    debound(eventType, fileName);
  }
});