【若川视野 x 源码共读】第37期 | create-vite

150 阅读1分钟

前提:大佬们的笔记已经写的很好了,我这边只记录下一些自己的难点。

整体思路:主要是根据用户输入选项来复制相关的模板文件,因此知识点主要是命令行交互和文件读取写入的api。

  1. 筛选 + for of 遍历
for (const file of files.filter((f) => f !== 'package.json')) {
    write(file)
  }
  1. 写文件:包装了重写功能,复制文件要考虑是文件夹还是文件

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)
  }
}
  1. 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 })
  }
}
  1. 命令行+交互式的库

读取命令行参数 用到了minimist库,解析args参数

交互式获取参数 用到了prompts

  1. import.meta.url 返回当前模块的 URL 路径
const templateDir = path.resolve( fileURLToPath(import.meta.url), '..', `template-${template}` )

参考资料

  1. juejin.cn/post/713045…
  2. juejin.cn/post/712519…