azl397985856 / fe-interview

宇宙最强的前端面试指南 (https://lucifer.ren/fe-interview)
Apache License 2.0
2.84k stars 260 forks source link

【每日一题】- 2019-11-21 - 实现热启动 #66

Closed azl397985856 closed 4 years ago

azl397985856 commented 4 years ago

热启动指的是修改文件,APP能够重新加载修改后的文件,然后重新执行。 像nodemon,pm2都有这样的功能。

让你实现一个功能,JS文件被修改之后,能够重新运行被修改的JS文件

提示:

nodejs提供一些api,让你对文件以及文件夹进行监听,eg:

// 监听文件
fs.watchFile('message.text', (curr, prev) => {
  console.log(`the current mtime is: ${curr.mtime}`);
  console.log(`the previous mtime was: ${prev.mtime}`);
});
// 监听文件夹
fs.watch('somedir', (eventType, filename) => {
  console.log(`event type is: ${eventType}`);
  if (filename) {
    console.log(`filename provided: ${filename}`);
  } else {
    console.log('filename not provided');
  }
});

扩展: 如果要优化速度怎么做呢?(比如增量更新或者按需更新)

azl397985856 commented 4 years ago

Two Points

  1. How Can I Know the file is changed. Luckily, NodeJS provide fs.watch API which referred in the problem description.

  2. How Can I restart with the latest content. The solution is simply, We can use child_process.spawn . Keep Only One worker process by Killing the subprocess when we just going to spawn a new one, AKA Singleton . 😄

Usage

nodemon.js:

const { spawn } = require("child_process");
const { watchFile } = require("fs");

const filename = process.argv[1];
let subprocess = null;

console.log("file-changed");

function restart(filename) {
  const subprocess = spawn("node", [filename], {
    detached: true
  });

  subprocess.stdout.on("data", data => {
    console.log(`stdout1: ${data}`);
  });

  return subprocess;
}

watchFile(filename, () => {
  if (subprocess !== null) {
    subprocess.kill("SIGKILL");
  }
  subprocess = restart(filename);
});