go list -json 怎样查看包包含的嵌入文件
我第一次给静态资源检查器接入 Go 包时,原本想扫描源码里的 //go:embed,很快就遇到两个麻烦:模式不等于最终文件,而且测试包里的资源很容易被漏掉。更稳妥的入口是让 go list -json 直接输出包元数据。
先给结论:EmbedPatterns 记录普通包声明过的嵌入模式,EmbedFiles 记录这些模式实际匹配到的文件;测试代码则分别看 TestEmbed* 和 XTestEmbed*。用字段选择器请求这六组字段,就能把结果交给检查脚本。
官方文档:https://pkg.go.dev/cmd/go
先分清你要找的是模式,还是文件
这两个字段看起来相近,但用途不同。模式回答“源码声明了什么”,文件回答“工具链解析后认为哪些文件被包含”。例如 web/* 是模式,web/index.html 和 web/app.css 才是匹配文件。

如果检查器只关心“有哪些资源会进入包”,优先读取 EmbedFiles;如果还要提示模式过宽、模式变更或测试覆盖范围,再同时保留 EmbedPatterns。
先准备一个包含普通资源和测试资源的包
为了看清字段分组,可以准备一个很小的目录。普通包、同包测试和外部测试分别放一个嵌入声明:
package assets import "embed" // 普通包资源由 embed.FS 持有,供正式代码读取。 //go:embed web/* var WebFiles embed.FS
package assets import _ "embed" // 同包测试资源会进入 TestEmbedPatterns 和 TestEmbedFiles。 //go:embed testdata/internal.txt var internalFixture string
package assets_test import _ "embed" // 外部测试包资源会进入 XTestEmbedPatterns 和 XTestEmbedFiles。 //go:embed testdata/external.txt var externalFixture string
这里的重点不是变量最后怎样使用,而是三类源文件的边界:普通 Go 文件、包内的 _test.go 文件,以及包外测试包的 _test.go 文件。
用 go list -json 查看普通包的嵌入文件
在模块根目录执行下面的命令。字段选择器让输出聚焦在嵌入信息,避免把依赖列表等无关包元数据一并交给后续脚本:
# 只请求六组嵌入字段,包路径按实际目录替换 go list -json=EmbedPatterns,EmbedFiles,TestEmbedPatterns,TestEmbedFiles,XTestEmbedPatterns,XTestEmbedFiles ./assets
普通包至少会关注下面两组字段。实际 JSON 中没有内容的字段可能不会出现,因此消费端不要把“字段缺失”直接当作错误:
{
"EmbedPatterns": ["web/*"],
"EmbedFiles": [
"web/app.css",
"web/index.html"
]
}
EmbedFiles 是相对包目录的文件名列表,适合做资源清单、许可证扫描或发布前的静态检查。它不是运行时读取结果,也不替代 embed.FS 的访问逻辑。
测试资源要看 TestEmbed 和 XTestEmbed
这是我后来补检查器时最容易漏掉的一点。包内测试文件产生 TestEmbedPatterns 与 TestEmbedFiles;外部测试包产生 XTestEmbedPatterns 与 XTestEmbedFiles。它们不会自动合并到普通包的 EmbedFiles 中。

想快速确认三组文件,可以把输出保留为 JSON,再按字段读取。不要只搜索所有文件名,因为同名资源可能来自不同测试组:
# 保存包元数据,后续脚本按字段区分正式资源与测试资源 go list -json=EmbedPatterns,EmbedFiles,TestEmbedPatterns,TestEmbedFiles,XTestEmbedPatterns,XTestEmbedFiles ./assets > package-embed.json
如果你的工具只需要打印摘要,也可以用模板减少人工阅读量:
# 只打印三类实际文件,空切片会保持为空
go list -f '{{.EmbedFiles}} {{.TestEmbedFiles}} {{.XTestEmbedFiles}}' ./assets
把 JSON 接入资源检查器时,按字段做三层判断
我会把检查逻辑拆成三步:先判断包是否成功加载,再收集普通包资源,最后按需追加两类测试资源。这样既不会把加载错误伪装成“没有嵌入”,也能让调用方选择是否纳入测试文件。
type EmbedInventory struct {
EmbedFiles []string
TestEmbedFiles []string
XTestEmbedFiles []string
}
// mergeFiles 只合并已经由 go list 解析出的文件名,不重新扫描源码。
func mergeFiles(info EmbedInventory, includeTests bool) []string {
files := append([]string{}, info.EmbedFiles...)
if !includeTests {
return files
}
files = append(files, info.TestEmbedFiles...)
files = append(files, info.XTestEmbedFiles...)
return files
}
上面这个结构只展示消费端的边界。真实调用还应保留 go list 的退出状态和标准错误:包加载失败、嵌入模式找不到匹配文件时,应该报告失败原因,而不是生成一个空清单。
几个容易误判的边界
| 现象 | 应该怎样理解 |
|---|---|
| 只有 EmbedPatterns,没有 EmbedFiles | 先检查字段是否被请求;若请求了文件字段,再看模式是否匹配到文件。 |
| 普通包清单为空 | 可能只是该包没有正式资源,不代表测试资源也为空。 |
| 测试文件没有出现在 EmbedFiles | 读取 TestEmbedFiles 或 XTestEmbedFiles,按测试包类型分别处理。 |
| 命令直接失败 | 保留 stderr 和退出码;模式无匹配文件属于输入或包状态问题,不应静默吞掉。 |
还有一个实际取舍:发布清单通常只收集 EmbedFiles,测试报告则可以把两类测试字段并入结果。把这两个用途分开,输出会更容易读,也不容易把测试夹具误打进正式资源包。
最后的使用判断
如果目标是查看 Go 包到底包含哪些嵌入文件,优先记住这一条命令:
# 让 go 命令负责解析 embed 模式,再输出可供脚本消费的 JSON go list -json=EmbedPatterns,EmbedFiles,TestEmbedPatterns,TestEmbedFiles,XTestEmbedPatterns,XTestEmbedFiles ./assets
只看正式资源时读 EmbedFiles;要覆盖测试夹具,再读 TestEmbedFiles 和 XTestEmbedFiles。对我来说,这比手工扫描 //go:embed 更稳定,因为“声明的模式”和“实际匹配的文件”都由同一个包加载过程给出。
相关问题:
- 为什么不能只读取 EmbedPatterns? 因为模式是声明,文件清单才是解析后的具体结果。
- 测试资源为什么要分两组? Go 区分包内测试文件和外部测试包,列表字段也保持了这个边界。
- 是否应该把测试文件发布出去? 通常不应该;让检查器用开关决定是否把测试字段纳入分析。
magisk能做什么不能做什么?Android定制工具的功能边界与合规使用说明
- 上一篇
- magisk能做什么不能做什么?Android定制工具的功能边界与合规使用说明
- 下一篇
- Go csv.Reader TrimLeadingSpace 处理字段前导空格的规则与引号边界
-
- Golang · Go教程 | 1小时前 | 命令行 · go · 工程实践 · go generate Go代码生成 go generate -run 生成指令筛选
- go generate -run 怎样只执行指定生成指令
- 453浏览 收藏
-
- Golang · Go教程 | 1小时前 | go · go test -json TestEvent Go测试事件 BuildEvent FailedBuild
- go test -json 输出怎样区分测试事件和构建事件
- 173浏览 收藏
-
- Golang · Go教程 | 1小时前 | 基准测试 · testing · 性能 · Go教程 · GOMAXPROCS RunParallel Go testing.B.SetParallelism 并行基准 IO吞吐
- Go testing.B.SetParallelism 提高 IO 型并行基准吞吐的配置方法
- 404浏览 收藏
-
- Golang · Go教程 | 1小时前 |
- Go testing.T.Cleanup 多次注册时为什么按逆序执行
- 309浏览 收藏
-
- Golang · Go教程 | 1小时前 |
- Go flag.FlagSet 怎样让参数错误返回给调用方
- 273浏览 收藏
-
- Golang · Go教程 | 1小时前 | flag · go ·
- Go flag.BoolFunc 怎样处理重复出现的布尔开关
- 246浏览 收藏
-
- Golang · Go教程 | 1小时前 | 反射 · Go教程 · database/sql · Go database/sql Rows.Scan ColumnType ScanType 动态查询导出
- Go database/sql ColumnType.ScanType 怎样支持动态查询导出
- 381浏览 收藏
-
- Golang · Go教程 | 1小时前 | flag · go · Go flag.TextVar encoding.TextUnmarshaler
- Go flag.TextVar 怎样复用类型的文本解析逻辑
- 479浏览 收藏
-
- Golang · Go教程 | 1小时前 | go · []byte · database/sql ·
- Go database/sql Scan 得到的 []byte 为什么不能直接长期保存
- 343浏览 收藏
-
- Golang · Go教程 | 1小时前 | 数据库 · Go教程 · database/sql · Go database/sql rows NextResultSet SQL结果集
- Go database/sql 怎样依次读取多个 SQL 结果集
- 456浏览 收藏
-
- Golang · Go教程 | 1小时前 |
- Go xml.Decoder.DecodeElement 怎样读取嵌套节点
- 436浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- PubMedQA
- 深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
- 446次使用
-
- H2O EvalGPT
- H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
- 517次使用
-
- LMArena
- LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
- 532次使用
-
- HELM
- 深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
- 478次使用
-
- MMBench
- MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
- 303次使用
-
- 接口返回 200 但前端仍报错怎么办:从响应格式到跨域一步步排查
- 2026-06-14 332浏览
-
- 图片上传后页面显示裂图怎么办:从资源路径到缓存刷新完整排查
- 2026-06-16 467浏览
-
- Go map 并发写 panic 怎么办:从共享 map 到可控写入路径
- 2026-06-30 123浏览
-
- golang生成JSON以及解析JSON
- 2023-01-17 329浏览
-
- Go如何实现json字符串与各类struct相互转换
- 2023-01-07 377浏览

