阿里 ice.work 探秘系列第三pian

这个系列我们前面已经有两篇了:

阿里 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;});}};返回搜狐,查看更多

责任编辑:

排行榜

  • 日排行
  • 原创