从事web开发的程序员对前后端分离模式应该不陌生。这也是目前主流的web开发模式。前后端分离模式详见文章《你不得不了解的前后端分离原理!》,笔者在此不做说明。好了,进入正题——Node.js前后端开发新思路。在进入新思路之前,我们需要了解什么是“旧思路”?(注:以下案例均以全栈工程师为例,即前后端代码在一起。)前后端分离开发的总体思路是举一个具体的场景为例:小牛是一名全栈工程师,喜欢前后端全栈开发。干货,前端使用目前主流的Webpack+React全家桶(或Vue全家桶),后端使用express(或Koa)。Mavericks同时启动两个进程(前后端各一个,前后端各一个)。使用nodemon热重启后台服务,使用WebpackProxy转发实现跨域请求,再进行开发。例如:前后端分离的简单案例流程1流程2______________________________||代理||||前端|<---->|节点监控器|后端|||||(cp1)|-----------------------------------如上所示,该模式需要启动两个进程(前端和Nodemon),其中BackEnd程序作为子进程挂载在Nodemon进程上,前端通过Proxy转发与Nodemon进程通信。乍一看,这很美好,但这种模式的缺陷也很容易暴露。传统思维BackEnd的缺陷程序复杂度增加后,启动时间变得不可控,每次热启动后台服务时间过长;开两个进程一定程度上增加了开发成本。那么针对以上问题,就需要介绍一下我们今天的主角了!前后端分离开发的新思路,还是小牛的例子。大牛也使用了和Mavericks一样的前后端技术栈,但是不同的是,大牛没有使用Nodemon来实现后端程序的热重启,而是使用了WebpackHMR(HotModuleReplacement)思想,Node.js中的模块热更新,具体实现使用hot-module-require。示意图如下。前后端在一个进程(同端口),更新的Module通过FsWatcher热替换,而不是完全重启。过程__________________________||文件观察器||前端|+|||Backend|----------------------------核心Node.js端HMR实现思路如下。Node.js端HMR实现思路。首先我们看一个程序的依赖图关系,得到程序的依赖图。js和lib/middleware.js,然后依次递归得到完整的依赖图。算法的具体实现见detect-dep。监控依赖图涉及到的文件需要热更新,所以离不开文件变化的监控,所以监控依赖图中的文件(其实只需要监控本地文件,不包括nodebuiltinmodules和第三方模块)这时候lib/to-array.js文件就变了!以A为入口删除更新模块A缓存(删除require.caches[modulePath]),更新依赖图并发送A更新信号根据依赖图,得到依赖A的模块集合B和回溯到B,重新从0开始执行。第一步需要注意循环依赖的处理。需要保证依赖路径,不要重复进行依赖更新。比如lib/to-array.js,有两条路径:lib/to-array.js->lib/middleware.js->index/js和lib/to-array.js->lib/express-utils。js->lib/middleware.js->index/js以上算法的具体实现可以参考hot-module-require。具体应用代码请参考这里。与传统模式相比,新理念的优势非常突出。优点细化Module更新的粒度,避免不必要的更新开销,大大减少服务更新时间。只有一个进程,一定程度上减少了进程调度。进程切换的代价是和特定场景比较的,比如后端使用的内存。存储用户会话数据。如果使用传统方式开发,每次更新后台代码,都会丢失内存中的用户数据,因此每次都需要重新登录;而在新的方式中,只需要不修改用户登录模块代码,用户不会被重置session数据,即不需要重新登录。Backendentry/\--login-->Common<--某个业务逻辑如上图简单的模块依赖图所示,A->B表示A依赖B,所以上图中Backendentry直接依赖关于“登录”和“某个业务逻辑”,间接依赖于“Common”;这个时候只有我们修改了“登录”或者“常用”的代码,才会触发登录模块的热更新。然而,新方法并非没有缺陷。比如代码模块包含了全局的side-effect代码,可能会出现各种奇怪的问题。扩展使用Node.jsHMR可以实现多种热更新体验,比如热更新代理、热更新mockData、热更新配置文件……,非常酷!相关资料静态依赖分析Node.jsHMR实现Node.jsHMRUsingNode.jsCircularDependenciesintheDevelopmentEnvironment
