仅在必要时在Node中重建

如果您的项目需要一些时间来准备 – 可能是编译或重写步骤 – 您可能需要等待的时间超过每次加载所需的时间。这让我们在Google的Santa Tracker h上h,我们使用Closure Compiler来构建大多数游戏。关闭是一个伟大的优化者,但它不知道速度。

所以这篇文章的主题是:慢速构建并不好玩,我们将学习如何只在需要时运行它们 ?

钟表原型

每次加载编译资源或手动重新运行脚本时,我们都可以使用NodeJS,而不是构建游戏,场景或代码库。 fs.watch 功能告诉我们我们是否真的需要。

从表面上看,这是一种简单的方法,可以告诉您文件在磁盘上的更改时间。像这样使用它:

常量 FS = 要求'FS'); FS'yourfile.txt' 事件类型 文件名 => {   //'yourfile.txt'发生了什么:¯ _(ツ)_ /¯ }); 

这是一种超级高效的方法,因为它要求您的操作系统在发生变化时通知您(不是相反,您的程序必须经常检查)。

构建用法

假设您正在编译一些Less CSS文件。你通过编译文件来做到这一点, entrypoint.less,有依赖关系:

常量  = 要求'减');  给予`@import'intrypoint.less';`)。然后((产量 => {   安慰信息产量CSS);    //包含导入的所有文件,例如:   // entrypoint.less => main.less => body.less   //将导致('entrypoint.less','main.less','body.less')   常量  = 产量进口; }); 

Less将为我们提供它在构建中使用的简单文件列表。其他一些工具可能会为您提供源映射,该映射还包含原始文件的名称。

如果这些文件中的任何一个发生更改,则最终输出无效,我们应该重建它。在实践中,这只是意味着呼唤 fs.watch 在每个文件上:?

  常量  = 产量进口;   的forEach((文件 => {     FS文件 () => rebuildIsNeededCallback());   }); 

这在技术上有效,但它还不适合整个构建系统。继续阅读 ??

注意事项

fs.watch 它是一个强大的功能,它有一些警告。这些可以归结为几点:

  • 您无法始终确保告知哪个文件已更改
  • 在Linux,macOS等上, fs.watch 跟随被监视文件的inode
    • …如果文件被移动,您将收到有关其新位置变化的通知
    • …如果文件被替换,您将收到一次通知,但不会自动监视新文件
  • 你需要打电话 。关() 结果当你不再需要它时 – 如果你忘了,你的程序将保持开放的听众

在实践中,这些警告意味着您应该使用每次调用 fs.watch 作为一次性暗示某些事情发生了变化。 ?这样想:你不能确定究竟改变了什么,但值得检查

思考的另一个论点 fs.watch 作为一次性:如果你的依赖关系通过添加或删除文件而改变,那么重置所有观察者而不是试图保持最新状态可能更容易。 ?

看助手

让我们把上面的知识放在一起,帮助你在代码发生变化时使代码无效。这就是我们在Santa Tracker中所做的事情;我们保留构建输出,直到它不再有效(因为底层源已经改变)。

?您可能会说“为什么无效,而不仅仅是完全重建?”除非您需要尽可能快地输出,否则每次保存都会运行一个昂贵的编译步骤。

所以 下面的方法将接受路径列表,观察它们,并在其中任何一个更改(或超时通过)时调用回调:

功能 路径 DONE 超时=0 {    观察家;    timeoutId;   常量  = () => {     //为了完成,我们关闭观察者(因为它不清楚     //他们处于什么状态),取消超时回调,     //让用户知道改变了什么。     观察家的forEach((w ^ => w ^());     clearTimeouttimeoutId);     DONE();   };    如果 超时 > 0 {     //如果给出超时,则在超时后'成功'。这是     //对*总是*重建或在一段时间后失效有用。     timeoutId = 的setTimeout 超时);   }   观察家 = 路径地图((p => FSp )); } 

请务必查看代码?,因为我已经留下了一些解释它的功能的评测。让我们把它与上面的Less示例结合起来。

少即是多

那么当依赖关系发生变化时,我们怎样才能使输出无效?

我们可以使用两个方法和一个缓存变量来做到这一点:

  • getCSS 哪个确保了 诺言 包含结果可用;和
  • buildCSS 在需要时实际重建(因为这是 异步,它返回一个 诺言)。
 compileCache;  异步 功能 buildCSS() {   安慰调试'重建CSS ...');   常量 产量 = 等待 给予`@import'intrypoint.less';`);    产量进口 () => {     compileCache = 空值;  //下次强制重建   }, 60 * 1000);    返回 产量CSS; }  //无论什么时候需要CSS,都可以调用getCSS,它始终是最新的 功能 getCSS() {   如果 compileCache {     compileCache = buildCSS();   }   返回 compileCache; } 

当然,这是一个非常简单的示例,只缓存一个结果:如果您想扩展它,您将使用输出字典,如果它们的依赖关系发生变化,每个输出都可以失效。

最后

最后联系起来 getCSS 对于这个世界,我现在为你最喜欢的NodeJS网络服务器添加一个处理程序,这样当我加载时说 /compiled.css,它返回结果 getCSS,确保编译版本始终是最新的。在波尔卡,它可能看起来像:

波尔卡()   得到'/compiled.css' REQ 水库 => {     水库结束getCSS());   }); 

如果您对更多可能需要安装开发服务器的方法感到好奇,请在下面告诉我们 ?

谢谢

如果您直接使用现代盘点系统(或构建工具),那么该工具可能会使用 fs.watch 已经在引擎盖下。然而,我仍然希望你已经学会了如何使用它 fs.watch 改进你的构建系统

暂且不说:我个人已经停止使用类似的构建工具了 咕噜 直接支持自定义构建工具或按需执行编译的Web服务器(由 fs.watch,就像我们在Santa Tracker中所做的那样)。

1?

资讯来源:由0x资讯编译自DEV,原文:https://dev.to/samthor/rebuild-only-when-necessary-in-node-506e ,版权归作者所有,未经许可,不得转载
你可能还喜欢