Grafana 插件中的前端 NPM 依赖项
Grafana 中的前端插件有其独特的依赖项,也有在运行时与 Grafana 应用程序共享的依赖项。本文档重点介绍如何处理这些共享依赖项,特别是 @grafana
npm 包。
重要的是要理解,虽然插件在其 package.json
文件中指定了这些依赖项的预期版本,但它们在运行时会动态链接到 Grafana 版本。
动态依赖项链接
插件的 package.json
文件可能引用特定版本的 @grafana
npm 包,例如 @grafana/ui: 9.5.1
。在开发环境(例如开发人员 IDE 或运行单元测试时)中,将使用这个版本的 @grafana/ui
。
然而,当插件安装并在 Grafana 实例中执行时,它会继承 Grafana 应用程序正在使用的 @grafana
包的版本。例如,如果 Grafana 版本是 10.0.0,那么插件将使用 Grafana 应用程序中共享的 @grafana
依赖项的 10.0.0 版本。
这种动态依赖项链接也适用于 create-plugin 提供的 docker 开发环境。当插件在 Grafana 内部运行时,它将继承 Grafana 应用程序中 @grafana
依赖项的版本。
依赖项共享机制
为了促进这种动态依赖项链接,Grafana 使用 SystemJS 加载前端插件代码,并与插件共享部分 Grafana 应用程序的 npm 依赖项。
Grafana 决定共享依赖项有两个原因
- 单例依赖项要求:在某些情况下,运行时只能存在一个依赖项实例。
- 性能优化:共享依赖项可以提高性能,特别是在处理大型依赖项代码库时。
共享依赖项的要求
为了共享依赖项,Grafana 定义了两个关键组件
- Grafana 中的 SystemJS import map:依赖项必须列在 Grafana 应用程序的 SystemJS import map 中。
- 插件构建工具配置:必须在插件的构建工具配置中外部化依赖项,这主要通过 Webpack 完成。
不支持自定义构建工具配置来更改外部依赖项,这样做可能会导致插件加载失败或出现错误。
编译和运行时
当 Grafana 应用程序加载前端时,SystemJS 会注册在 import map 中找到的所有共享依赖项。编译前端插件代码时,Grafana 会确保外部化的依赖项存在于插件运行时环境的作用域内。
当用户导航到需要特定插件的 Grafana 页面时,会发生以下步骤
- SystemJS 延迟加载插件的
module.js
文件。 - SystemJS 实例化
module.js
文件中的代码,确保在执行代码之前,将任何共享依赖项与插件中的外部依赖项引用链接起来。
此过程使 Grafana 能够有效地管理和共享各种插件之间的依赖项,同时确保在运行时使用正确且兼容的共享依赖项版本。