脚本架功能需求分析
概述
本节分析脚手架(Scaffold/CLI)的功能需求,理解脚手架的本质——通过 Node.js 脚本自动化项目初始化流程,替代手动操作。
脚手架的本质
核心定义
脚手架 = Node.js 环境执行的 JS 脚本 + 文件系统操作 + 命令行交互
用户输入命令 → Node.js 执行脚本 → 操作文件系统 → 生成项目模板
text
解决的痛点
| 问题 | 传统方式 | 脚手架方式 |
|---|---|---|
| 跨平台脚本 | Linux Shell 和 Windows BAT 语法不同 | Node.js 跨平台统一 |
| 项目初始化 | 手动创建目录、复制文件、安装依赖 | 一条命令自动完成 |
| 模板管理 | 手动下载/解压 | 内置模板或远程拉取 |
| 配置定制 | 逐个文件修改 | 交互式问答自动配置 |
| 规范统一 | 因人而异 | 脚本保证一致性 |
功能需求拆解
核心功能
CLI 工具功能架构
├── 参数解析
│ ├── 位置参数(项目名)
│ ├── 短选项(-t)
│ └── 长选项(--template)
├── 交互式问答
│ ├── 模板选择
│ ├── 项目名称
│ └── 覆盖确认
├── 模板管理
│ ├── 本地模板(内置)
│ ├── 远程模板(Git 仓库)
│ └── 模板渲染(变量替换)
├── 文件操作
│ ├── 目录创建
│ ├── 文件拷贝
│ └── 内容替换
└── 后续操作
├── 依赖安装
├── Git 初始化
└── 提示信息
text
命令行参数解析工具对比
| 工具 | 体积 | 特点 | 适用场景 |
|---|---|---|---|
| minimist | ~1KB | 极简,只解析参数 | 轻量 CLI |
| prompts | ~10KB | 美观的交互式问答 | 需要用户交互的 CLI |
| commander | ~30KB | 完整的命令行框架 | 多命令 CLI |
| yargs | ~80KB | 功能最丰富 | 复杂 CLI 应用 |
| inquirer | ~100KB | 多种交互类型 | 高度交互式 CLI |
文件操作工具
| 工具 | 用途 |
|---|---|
fs-extra | 增强的文件系统操作 |
glob | 文件模式匹配 |
handlebars / ejs | 模板变量渲染 |
pacote | 从 npm/Git 下载包 |
download-git-repo | 下载 Git 仓库 |
脚手架开发流程
最小闭环
// cli.ts - 最小可用的脚手架
import minimist from 'minimist'
import prompts from 'prompts'
import fs from 'fs-extra'
import path from 'path'
async function main() {
// 1. 解析参数
const argv = minimist(process.argv.slice(2))
const projectName = argv._[0]
// 2. 交互式选择
const { template } = await prompts({
type: 'select',
name: 'template',
message: '选择项目模板',
choices: [
{ title: '基础模板', value: 'base' },
{ title: '管理后台', value: 'admin' },
{ title: 'CDN 模板', value: 'cdn' }
]
})
// 3. 确定目标路径
const targetDir = path.resolve(process.cwd(), projectName || 'my-project')
// 4. 检查目录是否存在
if (fs.existsSync(targetDir)) {
const { overwrite } = await prompts({
type: 'confirm',
name: 'overwrite',
message: '目录已存在,是否覆盖?'
})
if (!overwrite) process.exit(0)
}
// 5. 拷贝模板
const templateDir = path.resolve(__dirname, `templates/${template}`)
await fs.copy(templateDir, targetDir)
// 6. 完成
console.log(`\n项目创建成功: ${targetDir}`)
console.log(`\n cd ${projectName}`)
console.log(` npm install`)
console.log(` npm run dev\n`)
}
main()
typescript
完整功能规划
// package.json bin 配置
{
"name": "create-my-app",
"bin": {
"create-my-app": "./dist/cli.mjs"
}
}
typescript
# 使用方式
npx create-my-app my-project
# 或
npm create my-app my-project
bash
跨平台兼容性
| 问题 | Linux/macOS | Windows | Node.js 解决方案 |
|---|---|---|---|
| 路径分隔符 | / | \ | path.join() |
| 换行符 | \n | \r\n | os.EOL |
| 环境变量 | $VAR | %VAR% | process.env |
| 脚本执行 | .sh | .bat | Node.js 脚本 |
| 权限管理 | chmod | 无 | fs.chmod() |
小结
- 脚手架本质是 Node.js 脚本 + 文件操作 + 命令行交互
- 核心功能包括参数解析、交互问答、模板管理和文件操作
- 推荐工具组合:minimist(参数解析)+ prompts(交互问答)+ fs-extra(文件操作)
- Node.js 天然跨平台,解决了传统 Shell 脚本的兼容性问题
- 开发脚手架时先实现最小闭环,再逐步扩展功能
↑