node.js中实现代码Hot-Reload功能

原文链接: suisuijiang.com

使用过webpack做前端的朋友大概知道, webpack有个dev-server功能, 支持在代码发生改动时自动的重启代码, 简称hot-reload. 这一特性极大地促进了开发效率, 所以下面我们通过编写代码来实现这个特性.

创建开发目录

首先创建一个src目录, 后面我们将监视src目录中的代码改动, 在src目录创建app.js做程序入口:

app.js


console.log('app.js');

使用chokidar监视目录

chokidar是一个小巧的文件监视库, 它可以获取到目录中文件的改动/新增/删除等事件. 在项目根目录创建development.js, development.js代码如下所示:

development.js


'use strict'

const path = require('path');

const chokidar = require('chokidar');

const watcher = chokidar.watch(path.join(__dirname, '/src'));

watcher.on('ready', () => {

        watcher.on('change', (path) => {

                console.log('<---- watched file change, do something ---->');

        });

        watcher.on('add', (path) => {

                console.log('<---- watched new file add, do something ---->');

        });

        watcher.on('unlink', (path) => {

            console.log('<---- watched file remove, do something ---->');

      });

});

执行npm install --save chokidar安装'chokidar'组件, 并执行node development.js运行程序, 尝试修改app.js的内容, 尝试在src目录中新建文件并删除新建的文件, 会看到如下所示输出:

console log


⇒  node development.js

<---- watched file change, do something ---->

<---- watched new file add, do something ---->

<---- watched file remove, do something ---->

引入程序并在发生改动时重启

由于主进程被用来监视文件了, 所以我们要把主程序运行在子进程中, 当代码发生改动时, 我们可以结束这个子进程并创建新的子进程. 创建进程需要使用child_process模块, 代码如下所示:

创建子进程, 启动主程序


let appIns = cp.fork(path.join(__dirname, '../src/app.js'));

发生改动时杀死子进程并重启


appIns.kill('SIGINT');

appIns = cp.fork(require('path').join(__dirname, '../src/app.js'));

监听SIGINT信息, 终止进程


process.on('SIGINT', () => {

      process.exit(0);

});

完整代码如下所示:

development.js


'use strict'

const path = require('path');

const cp = require('child_process');

const chokidar = require('chokidar');

const watcher = chokidar.watch(path.join(__dirname, '/src'));

let appIns = cp.fork(path.join(__dirname, '/src/app.js'));

watcher.on('ready', () => {

      watcher.on('change', (path) => {

            console.log('<---- watched file change, do something ---->');

            appIns = reload(appIns);

      });

      watcher.on('add', (path) => {

            console.log('<---- watched new file add, do something ---->');

            appIns = reload(appIns);

      });

      watcher.on('unlink', (path) => {

            console.log('<---- watched file remove, do something ---->');

            appIns = reload(appIns);

      });

});

process.on('SIGINT', () => {

      process.exit(0);

});

function reload(appIns) {

      appIns.kill('SIGINT');

      return cp.fork(require('path').join(__dirname, '/src/app.js'));

}

执行node development.js运行, 尝试修改app.js, 改为console.log('app.js changed');, 将看到如下输出:

console log


⇒  node development.js

app.js

<---- watched file change, do something ---->

app.js changed

尝试在src目录中创建a.js, 并修改app.js使其输出a.js内容, 这里不在粘贴输出, 请自行尝试.

结语

可以看到该实现方法十分简单, 并且适用于任何node.js开发场景, 譬如常用的express, koa后端接口开发.

感谢您的阅读, 欢迎留言指导讨论.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,238评论 19 139
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 174,336评论 25 709
  • 寂静喜欢,默然相爱。 看着书桌上那一摞未曾寄出的信,想着近日来的事,已经忘了第几个早上早醒,似睡非睡得躺着,开机关...
    不加葱的阳春面阅读 332评论 0 1
  • 引言 房事是大事,一套京沪房产交易,体量相当于一个中小型的企业并购,背后是几代人的血汗,不可不察也。 楼市狂飙,往...
    邓哲阅读 4,343评论 0 16
  • 其实,即使自己不进步,并不是在退,而是别人都在进步,而显得自己退步了。 一个曾经的同事,各方面都不如我,但十几年下...
    奔跑的马齿苋阅读 431评论 0 0