Jsonnet中如何仅导入指定局部变量,避免执行额外代码?
解决Libsonnet导入时自动执行顶层调用的问题
问题原因
Libsonnet的import机制会评估目标文件的所有顶层表达式,最终返回文件最后一个顶层表达式的结果。你的a.libsonnet最后一行是panel.createFromConfig(config),属于顶层执行语句,所以导入时会自动运行这个方法并返回其结果。
解决方案
方案1:直接导出panel对象
修改a.libsonnet,将最后一行改为返回panel,而非执行调用:
local panel = { new(...)::{... }, createFromConfig(config):: this.new(), }; // 将panel作为文件的导出值 panel
这样通过local panel = import 'a.libsonnet'导入时,只会拿到panel对象,不会触发createFromConfig的执行。
如果需要保留原有的执行逻辑(比如单独运行a.libsonnet时生成实例),可以新建一个入口文件(比如main.libsonnet):
local panel = import 'a.libsonnet'; local config = std.extVar('config'); panel.createFromConfig(config)
单独运行时执行jsonnet main.libsonnet即可。
方案2:同一文件兼顾导出与单独运行
如果希望在同一个文件里,既支持导入panel,又能单独运行时执行实例创建,可以借助std.thisFile()和std.masterFile()判断当前文件是否是主运行文件:
local panel = { new(...)::{... }, createFromConfig(config):: this.new(), }; local config = std.extVar('config'); // 仅当当前文件是直接运行的主文件时,执行创建逻辑;否则返回panel if std.thisFile() == std.masterFile() then panel.createFromConfig(config) else panel
这种方式下:
- 直接运行
jsonnet a.libsonnet时,会执行createFromConfig并返回实例 - 通过
import 'a.libsonnet'导入时,只会拿到panel对象
内容的提问来源于stack exchange,提问作者Tomas Wen
相关产品推荐
相关产品推荐

