2020-09-12 13:33:37
在Model Oriented Programming下的webpack HMR(模块热替换)实践
在Model Oriented Programming(重model层设计)的架构下,实现webpack的模块热替换(HMR)需要特别注意model层的稳定性和可替换性。以下是一些关键点和建议,以帮助你在这种架构下舒适地进行HMR。
一、纯函数与HMR
纯函数是HMR的理想选择,因为它们不依赖于外部状态,只根据输入产生输出。在React中,如果使用了react-hooks将数据管道和JSX放在同一个函数中,这可能会阻碍HMR的实现。为了更方便地进行HMR,建议将view部分单独拆出来。此外,react-hooks依赖顺序而非原生的reactive能力,这在一定程度上增加了HMR的复杂性。因此,在model层设计中,更倾向于使用具有reactive能力的库(如mobx、vue/reactivity)来封装reactivity,以实现更灵活的HMR。
二、Full Reactive与HMR
在Full Reactive系统中,当模块发生HMR时,需要通知各个依赖方。不同的框架有不同的实现方式,如Vue的依赖收集、Angular的changeDetect、React的Observable+forceUpdate。在Model Oriented Programming下,确保model层的变化能够正确地通知到依赖的view层或其他逻辑层,是实现HMR的关键。
三、粒度越细越好HMR
虽然“粒度越细越好”这一说法在某些情况下可能过于绝对,但在HMR的上下文中,细粒度的模块确实有助于更精确地替换和更新代码。将大型模块拆分成多个小模块,可以使得HMR更加高效和灵活。
四、API稳定性与HMR
稳定的API对于HMR至关重要。在Model Oriented Programming下,通过采用Clean Architecture等设计模式,可以确保model层的API相对稳定,从而降低HMR的复杂性。稳定的API意味着在HMR过程中,依赖这些API的模块可以更容易地进行替换和更新。
五、Immutability & Observable
在Model Oriented Programming下,实现Immutability和Observable是降低HMR复杂度的有效手段。除了在存储数据和消费数据的末端节点外,避免在任何地方存在mutable对象。这样,当模块发生HMR时,就不会触发整个数据管道的全面重建。同时,保持Observable的API本质上是为了reactivity的归一化,这有助于在HMR过程中保持系统的稳定性和一致性。
六、Entity或Model形态改变与HMR
当Entity或Model的形态发生改变时,通常不能进行HMR。因为此时old state shape已经没有价值,实现old shape到new shape的转换通常也是没有意义的。在这种情况下,可能需要采取其他策略来处理模块的更新和替换,如重新加载整个应用或进行部分页面的刷新。
七、Hooks与HMR
在Model Oriented Programming下,hooks应该被用作注入可复用模块的工具,而不是参与任何逻辑。这意味着hooks应该只包含state$和actions等reactive的IO模块,而不包含具体的业务逻辑。这样的设计有助于在HMR过程中更容易地替换和更新hooks模块。
八、Immutable设计的典范
mobx-state-tree是实现两种immutable设计的典范:reactive fractal model(反应式分形模型)和boxed-value with actions + immutable data(带操作的盒装值与不可变数据)。这种设计使得model层更加稳定且易于进行HMR。通过snapshot(快照)机制,可以轻松地保存和恢复model的状态,从而在HMR过程中保持数据的一致性。
综上所述,在Model Oriented Programming下的webpack HMR实践中,需要特别注意纯函数的使用、Full Reactive的实现、模块粒度的控制、API的稳定性、Immutability与Observable的应用、Entity或Model形态改变的处理、Hooks的正确使用以及Immutable设计的典范等方面。通过遵循这些原则和建议,可以更有效地实现HMR,提高开发效率和用户体验。