使用go:embed时如何按文件扩展名匹配文件?
Go embed按文件扩展名匹配的可行方案
你尝试用//go:embed dir/*{.js,tsx}这种写法无法生效,本质是因为go:embed内部依赖的path.Match不支持shell风格的大括号扩展语法。下面是几种可行的解决方案:
1. 显式声明多扩展名匹配规则
直接通过多个匹配路径声明,这是最直接的方案:
package main import "embed" //go:embed dir/*.js dir/*.tsx var MyFs embed.FS
path.Match支持*.ext这种单扩展名通配模式,多个路径可以写在同一条//go:embed指令中,用空格分隔。
2. 嵌入整个目录后运行时过滤
先嵌入目标目录下的所有内容,再在运行时遍历文件系统,筛选出符合扩展名要求的文件:
package main import ( "embed" "io/fs" "path/filepath" ) //go:embed dir/* var MyFs embed.FS // getMatchingFiles 筛选出dir目录下的.js和.tsx文件 func getMatchingFiles() ([]string, error) { var matchedFiles []string err := filepath.WalkDir("dir", func(path string, d fs.DirEntry, err error) error { if err != nil { return err } // 跳过目录 if d.IsDir() { return nil } ext := filepath.Ext(path) if ext == ".js" || ext == ".tsx" { matchedFiles = append(matchedFiles, path) } return nil }) return matchedFiles, err }
这种方案适合需要匹配的扩展名较多的场景,缺点是会将整个目录内容嵌入二进制,可能增加体积。
3. 借助go generate自动生成匹配规则
如果需要匹配的扩展名或文件路径非常复杂,可以写一个辅助脚本(比如Go程序或Shell脚本),提前遍历目录收集符合条件的文件路径,然后自动生成包含//go:embed指令的代码文件:
- 编写
generate_embed.go脚本,遍历目录筛选文件,输出包含//go:embed的代码 - 在主文件中添加
//go:generate go run generate_embed.go指令 - 执行
go generate自动生成嵌入规则
这种方案灵活性最高,但需要额外的脚本开发成本。
内容的提问来源于stack exchange,提问作者Christian Stewart
相关产品推荐
相关产品推荐

