Node.js:临时文件目录可以用 `fs.mkdtemp` 少踩点

28 次浏览4 条回复

写小脚本时如果要落一点临时文件,别直接拼一个固定目录名,重跑或者并发时容易撞。Node 自带的 fs.mkdtemp 会帮你在前缀后面补随机字符。

环境:Node.js 18+。保存成 mkdtemp-demo.mjs:

import { mkdtemp, writeFile, rm } from 'node:fs/promises'
import { join } from 'node:path'
import { tmpdir } from 'node:os'

const dir = await mkdtemp(join(tmpdir(), 'mesh-'))
const file = join(dir, 'note.txt')

await writeFile(file, 'hello temp\n', 'utf8')
console.log(dir)
console.log(file)

await rm(dir, { recursive: true, force: true })

跑一下:

node mkdtemp-demo.mjs

会打印一个系统临时目录里的随机路径。适合本地构建、压缩前准备文件这类短流程;真要保留结果的话,就别放临时目录里了。

这个细节挺实用。补一句:前缀用 join(tmpdir(), 'mesh-') 这种写法时,最后那个短横线最好留着,生成出来的目录名会更好认一点。

另外清理放在 finally 里会更稳,脚本中间报错也不容易把临时目录留一堆。

还有个小坑:mkdtemp 只负责建最外层那个随机目录,里面如果要写 a/b.txt 这种嵌套路径,还是得先 mkdir(dirname(file), { recursive: true })。

我一般会把临时目录名里塞一点任务前缀,比如 build-、zip-,出问题时看日志也不至于全是随机串。

还可以顺手把权限收紧一点。临时目录里如果会放 token、打包中间产物之类的东西,写文件时别给太宽的 mode。

比如:

await writeFile(file, 'hello temp\n', { encoding: 'utf8', mode: 0o600 })

mkdtemp 解决的是目录名冲突,里面文件的权限和清理时机还是要自己管一下。

这个写法还有个隐含好处:别自己假设临时目录一定在 /tmp。

tmpdir() 会按系统和环境变量取合适的位置,Windows、macOS、Linux 上路径都可能不一样。后面如果要传给别的命令,最好一直用 join(dir, ...) 这种方式拼,日志里也直接打 mkdtemp 返回的完整路径,少踩跨平台路径分隔符的坑。