使用过webpack做前端的朋友大概知道, webpack有个dev-server功能, 支持在代码发生改动时自动的重启代码, 简称hot-reload. 这一特性极大地促进了开发效率, 所以下面我们通过编写代码来实现这个特性.
创建开发目录
首先创建一个src
目录, 后面我们将监视src
目录中的代码改动, 在src
目录创建app.js
做程序入口:
app.js
使用chokidar监视目录
chokidar是一个小巧的文件监视库, 它可以获取到目录中文件的改动/新增/删除等事件. 在项目根目录创建development.js
, development.js
代码如下所示:
development.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| '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
1 2 3 4
| ⇒ node development.js <---- watched file change, do something ----> <---- watched new file add, do something ----> <---- watched file remove, do something ---->
|
引入程序并在发生改动时重启
由于主进程被用来监视文件了, 所以我们要把主程序运行在子进程中, 当代码发生改动时, 我们可以结束这个子进程并创建新的子进程. 创建进程需要使用child_process模块, 代码如下所示:
创建子进程, 启动主程序
1
| let appIns = cp.fork(path.join(__dirname, '../src/app.js'));
|
发生改动时杀死子进程并重启
1 2
| appIns.kill('SIGINT'); appIns = cp.fork(require('path').join(__dirname, '../src/app.js'));
|
监听SIGINT信息, 终止进程
1 2 3
| process.on('SIGINT', () => { process.exit(0); });
|
完整代码如下所示:
development.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| '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
1 2 3 4
| ⇒ node development.js app.js <---- watched file change, do something ----> app.js changed
|
尝试在src
目录中创建a.js
, 并修改app.js
使其输出a.js
内容, 这里不在粘贴输出, 请自行尝试.
结语
可以看到该实现方法十分简单, 并且适用于任何node.js开发场景, 譬如常用的express, koa后端接口开发.
感谢您的阅读, 欢迎留言指导讨论.