论前端如何优雅地实现脚手架(3)
前言:听说不会做脚手架的前端不是好前端,本系列带你从0到1创建一个属于个人的脚手架,适合快速创建模板项目
这一章节你可以学习到:
path
模块的一些路相关路径获取方法fs
模块对文件和文件夹的复制- 相关文件夹和函数的命名方式
1、构建函数
通过第二大章节,我们已经成功采集到用户输入的相关信息,这个时候我们就可以将对应的模板进行生成了。
-
在
src/contain
中创建createProject
函数,同时创建参数类型export interface Choosed { projectName: string; // 项目名 framework: string; // 采用框架 variant: string; // 二次选项 } export function createProject(answer: Choosed) { }
-
在
index.ts
中引入并使用import { getArgs } from "./util.js" import { createProject } from "./contain.js" import startQA from "./create-inquir.js" // 1) 获取参数 const ARGUMENTS = getArgs() process.env.__CREATE_NAME__ = ARGUMENTS[0]; // 2) 初始化项目 async function init() { try { const ANSWERS = await startQA() createProject(ANSWERS as any) } catch (error) { } } init()
2、获取相关路径
-
在
util.ts
创建一个工具函数,用户获取当前工作目录的路径与传参的合并路径,这个函数可以帮助我们拿到用户执行时所在的目录,方便获取模板的生成位置:// 获取当前工作目录的路径与传参的合并路径 export const getPathFromExecRoot = (path: string = ".") => join(process.cwd(), path)
-
在
createProject
中首先获取相关路径:- srcPath:需要 cpoy 的模板
- commonPath:模板项目存储的位置
- destPath:模板输出位置
import { getPathFromExecRoot } from "./util.js" // ... export function createProject(answer: Choosed) { // 1 获取相关路径 const { projectName, variant } = answer const srcPath = getPathFromRoot(`template/${variant}`) const commonPath = getPathFromRoot(`template/common`) const destPath = getPathFromExecRoot(projectName); }
3、构建复制文件夹函数
在 util.js
导出四个新的工具函数:
-
copyFile:将一个文件从 A 复制到 B
这里会判断传入的文件路径是文件夹还是文件,如果文件则直接复制,文件夹则调用下一个函数 copyDir
export const copyFile = (src: string, dest: string) => fs.statSync(src).isDirectory() ? copyDir(src, dest) : fs.copyFileSync(src, dest)
-
copyDir:将一个文件夹从 A 复制到 B
export const copyDir = (srcDir: string, destDir: string, exclude?: string[]) => { // 1 创建目录 fs.mkdirSync(destDir, { recursive: true }) // 2 循环复制 const dirs = fs.readdirSync(srcDir) // 3 循环目录 for (let fileName of dirs) { if (exclude?.includes(fileName)) continue; const destFileName = fileName const srcFile = resolve(srcDir, fileName) const destFile = resolve(destDir, destFileName) copyFile(srcFile, destFile) } }
-
在
createProject
中引入使用export function createProject(answer: Choosed) { // 1 获取相关路径 const { projectName, variant } = answer const srcPath = getPathFromRoot(`template/${variant}`) const commonPath = getPathFromRoot(`template/common`) const destPath = getPathFromExecRoot(projectName); // 复制文件夹 copyDir(commonPath, destPath) copyDir(srcPath, destPath) console.log("================================== 模板生成成功 =================================="); }
4、测试模板输出
随便找个空文件夹即可,输入命令:
test hello-world
选择完成后,模板出现即为成功:
5、总结
通过这一大章的学习,其实我们的脚手架已经基本完成,大家可以思考下剩余的问题:
package.json
中的name
属性如何变成我们设置的项目名?.gitignore
是否可以直接使用,会有什么问题,有没有更巧妙地方式去 copy?- 结尾的完成提示是否可以更好看点?
- ...
这些问题,将会在下一章节中去解决,您可以自行思考或者解决下,敬请期待!
转载自:https://juejin.cn/post/7390447879406649355