这个系列我们前面已经有两篇了:
阿里 ice.work 探秘系列第二篇 ice-plugin
2020 年第二天来篇 ice.work 探秘系列开篇
这篇我们来看看 ice-s 如何监控 ice-config.js 文件的变化
拆解一下上面的问题:
1、文件类型的内容变化
2、需要找到一个钩子来监控
那很简单,如果你对 nodejs 第三方包积累不多的化,其实就是看看核心模块 fs 的 api 有没有类似的:
官方文档:
https://nodejs.org/dist/latest-v12.x/docs/api/fs.html
fs.watch(filename[,options][,listener])
fs.watchFile(filename[,options],listener)
两个常规的 api:fs.watch 和 fs.watchFile
那熟悉或者自己积累过一些第三方的 nodejs 工具包的化,就会知道有一个:
chokidar
Aneat wrapper around Node.js
fs.watch / fs.watchFile / FSEvents.
它也提到了原生 api 的一些问题:
Node.js fs.watch:
Doesn't report filenames on MacOS.
Doesn't report events at all when using editors
like Sublime on MacOS.
Often reports events twice.
Emits most changes as rename.
Does notprovide an easy way torecursively watch filetrees.
Node.js fs.watchFile:
Almost as bad at event handling.
Also does not provide any recursive watching.
Results in high CPU utilization.
Chokidar resolves these problems.
好,有了这些基本知识之后,我们看一下 ice-s 的源码部分:
第一步:
引入 chokidar 工具包
constchokidar = require( 'chokidar')
找到 ice-config.js 文件:
这里一般都会用到核心模块:path
constpath = require( 'path')
通过 resolve 拼接路径:
constconfigPath = path.resolve(rootDir,'ice.config.js')
然后就是调用 chokidar 的 api 了,查看文档
chokidar.watch( '.'). on( 'all',( event,path) => {
console.log( event,path);
});
那对应我们这里:其实也一样,chikidar.watch
letwatcher = nul
watcher = chokidar.watch(configPath,{ignoreInitial: true})
关于 ignoreInitial 的配置:
默认 false
ignoreInitial (default: false).
If settofalsethenadd/addDir eventsarealso emitted formatching paths whileinstantiating the watching aschokidar discovers these filepaths ( beforethe ready event). 然后可以监控:change 事件
watcher.on( 'change',=> { })监控 error 事件:
watcher.on( 'error',( error) => { })那如果 ice-config.js 文件变化了会发生什么?
其实就是以下 3 件事情:关闭监控、重置变量、调用 process.send
server.closeserver= nullprocess.send({ type: 'RESTART_DEV'}) 好了,一起再看看所有源码:
lib/plugins/devWatcher/index.js
constpath = require( 'path'); constchokidar = require( 'chokidar'); letserver = null; letwatcher = null;
module.exports = ( { onHook,log,context }) => { const{ command,rootDir } = context; // watch ice.config.js in dev modeif(command === 'dev') { // setup watch// check watcher in case of reRun pluginsif(!watcher) { constconfigPath = path.resolve(rootDir,'ice.config.js'); watcher = chokidar.watch(configPath,{ignoreInitial: true,});
constonUserChange = => { console.log( 'n'); log.info( 'ice.config.js has been changed'); if(!server) { log.error( 'dev server is not ready'); } else{ server.close;server = null; log.info( 'restart dev server'); process.send({ type: 'RESTART_DEV'}); }};
watcher.on( 'change',=> { // apply hook when user config is changedonUserChange;});
watcher.on( 'error',( error) => { log.error( 'fail to watch file',error); process.exit( 1); });}
onHook( 'afterDevServer',( devServer) => { server = devServer;});}};返回搜狐,查看更多
责任编辑:

京公网安备
11010202010575号
加载中,请稍侯......