前端脚手架开发练习:一步一坑式学习清单
(从 0 到能跑起来的 CLI,每完成一条打 √)
──────────────────
阶段 1:热身 & 环境
- 全局安装一个现成脚手架(如 @vue/cli、create-react-app)并读完
‐-help
打印出的所有命令。 - 用 npx 调一次
npx create-xxx@latest my-test
,观察它生成了哪些文件。 - 本地装 Node ≥18、npm ≥9,跑通
node -v && npm -v
。 - 学会用 nvm / fnm 切换 Node 版本。
阶段 2:项目骨架
5. 新建文件夹 my-cli
,npm init -y
。
6. 在 package.json 里补一条 "type": "module"
(ESM)。
7. 新建 bin/index.js
,顶部写 #!/usr/bin/env node
,并 chmod +x
给它可执行权限。
8. 在 package.json 加 "bin": { "my-cli": "./bin/index.js" }
,本地 npm link
验证能在任意目录跑 my-cli
。
阶段 3:命令行解析
9. 安装 commander:npm i commander
。
10. 用 commander 写第一个子命令 my-cli create <name>
,能打印出 creating <name>
。
11. 给 create 加 --template
选项,支持 -t
简写,并打印模板名。
12. 用 process.exit(1)
处理非法参数并打印友好提示。
阶段 4:交互式提问
13. 安装 inquirer:npm i inquirer@9
(新版只支持 ESM)。
14. 用 inquirer 问用户:项目名、作者、是否用 TypeScript,结果暂存到变量 answers
。
15. 把问答结果组合成 meta = { projectName, author, useTs }
。
阶段 5:模板引擎
16. 在 templates/
下放两个文件夹 vanilla
和 typescript
,各含 package.json.ejs
。
17. 安装 ejs:npm i ejs
,用它渲染 package.json.ejs
得到真实 package.json
,并写入目标目录。
18. 把模板里出现的 <%= projectName %>
、<%= author %>
替换成问答结果。
阶段 6:文件操作
19. 用 fs-extra
的 copy()
将整个模板目录拷到 ./<projectName>
,同时 .gitignore
模板文件。
20. 在拷贝过程中过滤掉 .ejs
后缀,避免把模板源文件暴露给用户。
21. 创建完目录后输出 ✔ Project created in ./<projectName>
,并提示 cd <projectName> && npm install
.
阶段 7:依赖安装 & git 初始化
22. 用 execa
在目标目录里 npm install
,带 spinner 让用户知道进度(可用 ora
)。
23. 安装成功后自动 git init && git add . && git commit -m "init"
。
24. 提供 --no-git
选项跳过 git 初始化。
阶段 8:配置化(可选)
25. 在 ~/.config/my-cli/config.json
存用户默认偏好(作者名、常用模板)。
26. 第一次运行时若找不到配置就引导用户填写并保存。
27. 支持 --reset
子命令清空配置。
阶段 9:发布 & 测试
28. 用 npm pack
打本地包,手动解压检查文件。
29. 注册 npm 账号,npm publish --access public
发布 0.1.0。
30. 在另一台机器 npx my-cli@latest create hello
跑通全流程。
阶段 10:锦上添花(进阶)
31. 用 chalk 给文字加颜色,用 log-symbols 打 √/×。
32. 写单元测试:用 vitest 测试 commander 的解析、inquirer 的默认值。
33. 在 GitHub Actions 里跑 npm test && npm run build
,发布前自动打 tag。
34. 支持插件机制:扫描 my-cli-plugin-*
,动态加载并追加子命令。
35. 用 update-notifier
提示用户脚手架有新版本。
──────────────────
使用方法
· 以上 35 条每条都很小,建议一天完成 3-5 条。
· 每完成一步就在 README 里打 √,并写一句“我学到了什么”。
· 卡住时直接问:“我在第 X 步遇到 … 报错,如何解决?”