原文鏈接: suisuijiang.com
使用過webpack做前端的朋友大概知道, webpack有個(gè)dev-server功能, 支持在代碼發(fā)生改動(dòng)時(shí)自動(dòng)的重啟代碼, 簡稱hot-reload. 這一特性極大地促進(jìn)了開發(fā)效率, 所以下面我們通過編寫代碼來實(shí)現(xiàn)這個(gè)特性.
創(chuàng)建開發(fā)目錄
首先創(chuàng)建一個(gè)src
目錄, 后面我們將監(jiān)視src
目錄中的代碼改動(dòng), 在src
目錄創(chuàng)建app.js
做程序入口:
app.js
console.log('app.js');
使用chokidar監(jiān)視目錄
chokidar是一個(gè)小巧的文件監(jiān)視庫, 它可以獲取到目錄中文件的改動(dòng)/新增/刪除等事件. 在項(xiàng)目根目錄創(chuàng)建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 ---->');
});
});
執(zhí)行npm install --save chokidar
安裝'chokidar'組件, 并執(zhí)行node development.js
運(yùn)行程序, 嘗試修改app.js
的內(nèi)容, 嘗試在src
目錄中新建文件并刪除新建的文件, 會(huì)看到如下所示輸出:
console log
? node development.js
<---- watched file change, do something ---->
<---- watched new file add, do something ---->
<---- watched file remove, do something ---->
引入程序并在發(fā)生改動(dòng)時(shí)重啟
由于主進(jìn)程被用來監(jiān)視文件了, 所以我們要把主程序運(yùn)行在子進(jìn)程中, 當(dāng)代碼發(fā)生改動(dòng)時(shí), 我們可以結(jié)束這個(gè)子進(jìn)程并創(chuàng)建新的子進(jìn)程. 創(chuàng)建進(jìn)程需要使用child_process模塊, 代碼如下所示:
創(chuàng)建子進(jìn)程, 啟動(dòng)主程序
let appIns = cp.fork(path.join(__dirname, '../src/app.js'));
發(fā)生改動(dòng)時(shí)殺死子進(jìn)程并重啟
appIns.kill('SIGINT');
appIns = cp.fork(require('path').join(__dirname, '../src/app.js'));
監(jiān)聽SIGINT信息, 終止進(jìn)程
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'));
}
執(zhí)行node development.js
運(yùn)行, 嘗試修改app.js
, 改為console.log('app.js changed');
, 將看到如下輸出:
console log
? node development.js
app.js
<---- watched file change, do something ---->
app.js changed
嘗試在src
目錄中創(chuàng)建a.js
, 并修改app.js
使其輸出a.js
內(nèi)容, 這里不在粘貼輸出, 請(qǐng)自行嘗試.
結(jié)語
可以看到該實(shí)現(xiàn)方法十分簡單, 并且適用于任何node.js開發(fā)場景, 譬如常用的express, koa后端接口開發(fā).
感謝您的閱讀, 歡迎留言指導(dǎo)討論.