你的webpack/browserify watch 远程同步文件失效了吗?

最近在项目上捯饬js模块化的东西,选来选去还是选择了gulp+webpack这种方式,因为我已经用gulp做了一些css的相关工作,gulp用起来更像是在编程,感觉自己的掌控力会更大,所以并没有一下子都投入到现在相当火的webpack中去(webpack更像是基于配置的东西,初看起来各种概念、配置和插件让人眼花缭乱,如果要实现些特殊需求可能需要对其有更深的理解,所以在功力不够的时候,在目前的阶段上我选在了以上方案)。

这里不谈方案的具体内容,谈一下让我极其郁闷的遇到的一个问题,就是不管我用browerify的watchify还是webpack自带的增量watch功能,当文件变化的时候竟然不更新!!!!!

我解决问题的思路如下:

  1. 首先我尝试检查配置,确定输入和出入都没有任何异常,和官网文档对比也没有不同之处,然后我就特别纳闷是什么原因。。。

  2. 突然想到会不会是因为我的文件更改是在本机上,然后利用sftp同步到远程虚拟机上的时候出了问题(工程化环境我上维护在了远程虚拟机上),所以我就直接上虚拟上修改文件试了一下,bingo。。watch成功了。。。

  3. 然后我想一定是和底层文件传输和watch的监听方式有关,奈何自己对底层。。(知识的多样性是多么重要啊),然后就google之。。。都很少有内容提到这些,还好在对比了几篇文章后,找到了解决方案就是:给webpack加上如下配置(很意外,browerify的watchify也有类似的poll配置,但是应该是有bug,并不起作用。。这也让我放弃了它。。。如果有人知道为什么可以给我留言,谢谢啦)

watchOptions: {
  poll: true
}
  1. 问题虽然解决了,但是我心里还是疑问的啊,为啥啊为啥啊,本地监听就可以,远程同步就监听不到呢?又搜了圈google,解释的就更少了。。。还好找到一篇,大致解决了我的困惑,翻译如下:

首先让我们分析下watch是如何在本地linux上工作的:

  • 启动webpack --watch, 此时使用了inotify去管理监听文件改动
  • 你在本地用编辑器编辑文件后保存
  • inotify监听到改动的文件然后通知给webpack
  • webpack进行了增量编译工作

然后让我们分析下watch在远程同步文件下是如何工作的:

  • 启动webpack --watch, 此时使用了inotify去管理监听文件改动
  • 你在开发机上用编辑器编辑文件后保存,文件改动了
  • 改动的文件远程同步到linux上通过NFS
  • 远程linux上什么都没发生。。。监听失败。。。

所以这是为什么呢?
去看下wikipedia:

通过inotify的进行的通知需要系统内核得知所有相关的文件系统的事件,然而不适用于一些network filesystems比如NFS...

结论:inotify不支持远程watch,介于时间原因我就没有再往系统原因上深究了。。。不过还好,大致明白了为啥有这个坑啊。。

所以使用polling,就是轮询策略,webpack会每隔一些时间去检查文件是否改动,相当于从被动触发变成了主动请求,虽然这不是让人很满意的解决方案,但至少简单可行啊!~

福利1:

如果使用了karma和webpack,添加如下内容到 karma.conf.js:

webpackMiddleware: {
     watchOptions: {
       poll: true
     }
   }

福利2:减少CPU的峰值

如果polling引起了CPU的峰值,那就把poling的值设高。把polling:true改为 polling: 300(300ms) or polling: 400(400ms) 直到这个问题得到缓解。

ps: 最近开始健身了,身体好了不少,广大程序员们一定要注意身体啊,这才是本钱!~