如何在Nim编译时读取特定后缀名的文件?
解决编译时嵌入带哈希的Angular SPA资源到Nim二进制的问题
方法1:编译时调用系统命令获取文件列表
Nim的compileTime块支持执行外部命令,我们可以通过调用系统的文件遍历命令(如find或ls)来获取资源目录下的文件,避开编译时无法使用的walkFiles:
import std/[os, sequtils, strformat, strutils, osproc] const resourceFolder = "/home/philipp/dev/imagestable/html" # 编译时执行find命令拿到所有文件路径 const applicationFiles = compileTime: let cmdOutput = execProcess(fmt"find {resourceFolder} -type f") cmdOutput.splitLines().filterIt(not it.isWhitespace()) # 遍历文件并嵌入内容 for filePath in applicationFiles: let fileName = filePath.splitPath().tail const fileContent = staticRead(filePath) # 可将文件名与内容关联存储,比如用编译时Table echo fmt"已嵌入文件: {fileName}"
方法2:预生成资源清单模块
写一个独立的Nim脚本,在编译主程序前运行,遍历资源目录生成包含所有文件名和staticRead调用的模块:
- 创建
generate_resources.nim脚本:
import std/[os, sequtils, strformat, strutils] const resourceFolder = "/home/philipp/dev/imagestable/html" const outputModule = "resources.nim" proc main() = var moduleContent = newString() moduleContent.add "import std/strutils\n" moduleContent.add "type Resource = tuple[name: string, data: string]\n" moduleContent.add "const resources: seq[Resource] = @[\n" for filePath in walkFiles(fmt"{resourceFolder}/*"): let fileName = filePath.splitPath().tail moduleContent.add fmt" (name: \"{fileName}\", data: staticRead(\"{filePath}\")),\n" moduleContent.add "]\n" writeFile(outputModule, moduleContent) main()
- 编译主程序前先执行该脚本:
nim c -r generate_resources.nim
- 在主程序中导入生成的模块:
import resources for res in resources: echo fmt"加载资源: {res.name}, 大小: {res.data.len}"
方法3:修改Angular构建配置(备选)
如果允许调整Angular的构建规则,可以修改angular.json关闭文件名哈希,让生成的JS/CSS文件名固定:
{ "projects": { "your-project": { "architect": { "build": { "options": { "outputHashing": "none" } } } } } }
这样就能直接用staticRead读取固定文件名的文件,但会失去哈希带来的缓存优化能力。
内容的提问来源于stack exchange,提问作者Philipp Doerner
相关产品推荐
相关产品推荐

