- 本文参加了由公众号@若川视野 发起的每周源码共读活动,点击了解详情一起参与。
- 这是源码共读的第37期,链接:juejin.cn/post/712519…
前提:大佬们的笔记已经写的很好了,我这边只记录下一些自己的难点。
整体思路:主要是根据用户输入选项来复制相关的模板文件,因此知识点主要是命令行交互和文件读取写入的api。
- 筛选 + for of 遍历
for (const file of files.filter((f) => f !== 'package.json')) {
write(file)
}
- 写文件:包装了重写功能,复制文件要考虑是文件夹还是文件
const write = (file, content) => {
const targetPath = renameFiles[file]
? path.join(root, renameFiles[file])
: path.join(root, file)
if (content) {
fs.writeFileSync(targetPath, content)
} else {
copy(path.join(templateDir, file), targetPath)
}
}
function copy(src, dest) {
const stat = fs.statSync(src)
if (stat.isDirectory()) {
copyDir(src, dest)
} else {
fs.copyFileSync(src, dest)
}
}
/**
* @param {string} srcDir
* @param {string} destDir
*/
function copyDir(srcDir, destDir) {
fs.mkdirSync(destDir, { recursive: true })
for (const file of fs.readdirSync(srcDir)) {
const srcFile = path.resolve(srcDir, file)
const destFile = path.resolve(destDir, file)
copy(srcFile, destFile)
}
}
- emptyDir:递归删除文件夹,相当于
rm -rf xxx
function emptyDir(dir) {
if (!fs.existsSync(dir)) {
return
}
for (const file of fs.readdirSync(dir)) {
fs.rmSync(path.resolve(dir, file), { recursive: true, force: true })
}
}
- 命令行+交互式的库
读取命令行参数 用到了minimist库,解析args参数
交互式获取参数 用到了prompts
- import.meta.url 返回当前模块的 URL 路径
const templateDir = path.resolve( fileURLToPath(import.meta.url), '..', `template-${template}` )
参考资料