在所有的代码设计中,我们都可以渐进增强的思考模式,去指导我们的开发。渐进增强的核心原则是:基础的内容和功能开始,逐层添加表现层和行为层,确保每一层的增强都不会破坏基础层的功能。当增强功能不可用时,核心功能仍然可以正常工作。
按照渐进增强的思路:就是提供一个稳定可靠的核心基线,然后针对不同环境逐层应用功能增强。
这种架构被清晰分为两大层次:
首先是作为我们的“基线功能”的核心包。它必须是环境无关的,确保在任何(甚至是未知的)JavaScript 运行环境中都能稳定工作。
- 它的职责是:
- 提供最基础、最通用的能力:一个标准化的初始化流程。
- 定义一套稳定的数据契约:暴露标准化的数据上报接口。
- 提供扩展能力:建立一个轻量级的插件注册机制。
- 数据缓存队列的接收与消费。
其次就是作为我们的“增强层”的增强包。它们基于核心包提供的基线,针对特定运行环境(如浏览器、Node.js)提供更丰富、更深入的功能。
- 按需加载 (On-demand): 这是渐进增强的直接体现。用户只加载他们需要的“增强层”。
- 浏览器用户:只需引入
browser包。他们获得的是“核心基线 + 浏览器增强”,完全不必担心 Node.js 的perf_hooks代码被打包,实现了产物的轻量化。 - Node.js 用户:同理,他们引入
node包,获得“核心基线 + Node.js 增强”。
- 浏览器用户:只需引入
- 关注点分离 (Separation of Concerns): “基线”和“增强”各司其职。
- 例如数据上报:
- 核心包 (基线): 只负责“接收”符合标准契约的数据。
browser包 (增强): 负责“如何发送”。它利用浏览器独有的fetchAPI 来实现具体的上报逻辑。基线无需关心(也不应该关心)fetch的存在
- 例如数据上报:
在我的代码中,主要是针对浏览器设计了一个增强包,更是一个针对浏览器环境的“开箱即用”的增强插件合集。类似于 babel 的 preset 参数。
- 内置插件增强: 对于浏览器环境,异常监控和性能监控是“标配”而非“可选”。因此,我没有将它们作为可选插件,而是作为“内置增强”直接集成。这保证了用户一旦引入
browser包,就能立即获得核心价值(开箱即用)。 - 可选插件增强:,统计用户基本信息(如 User-Agent、屏幕分辨率等)是一个典型的浏览器端需求。但这个功能并不属于“核心基线”,也不一定在所有场景下都需要。我们可以将其实现为一个独立的浏览器端插件。用户可以“按需选择”是否加载这个插件。它利用插件机制,只需要在初始化 sdk 时,手动传入插件即可。
- 模块化增强: 同时,这些内置增强(如异常模块、性能模块)本身也是解耦的、模块化的。它们各自只做自己的事,单独实现核心包中的接口,遵循了“单一职责”,便于未来的维护和迭代。
这种渐进增强的架构具有极强的可拓展性。
如果未来我们需要支持一个新的平台,我们完全不需要改动现有的核心包或任何适配包。
我们只需要:
- 重用稳定包
- 实现一个新的适配包
这确保新功能的迭代不会对存量用户造成任何影响。