前言:

在前端开发中,重复搭建项目环境是个低效的事儿。要是团队技术栈固定(比如 React + AntD + Zustand + TS ),每次从零开始配路由、状态管理、UI 组件,既耗时又容易出错。这时候,自定义 CLI 脚手架 就派上大用场了 —— 一行命令就能生成标准化项目,直接进入业务开发!

本文就带你从 0 到 1 开发一套 React 脚手架 CLI,实现 “拉取模板 + 初始化 Git + 自动装依赖” 全流程,让项目搭建像 “搭积木” 一样简单 ✨

一、需求拆解:脚手架要解决什么问题?

我们的目标是做一个 “开箱即用” 的 React 脚手架,核心功能:

  1. 模板一键拉取:从 GitHub 仓库拉取包含 React 路由、AntD 组件、Zustand 状态管理的项目模板。
  2. 自动初始化流程:无需手动 git initnpm install,工具自动完成。
  3. 开发命令指引:安装完直接提示启动命令,无缝衔接开发。

二、技术选型:哪些工具能帮我们实现?

  • commander:解析命令行参数(定义 create <projectName> 命令)。
  • download-git-repo:从 Git 仓库下载模板(支持 GitHub、GitLab 等)。
  • child_process:Node.js 内置模块,执行终端命令(如 git initnpm install)。

三、代码实现:一步步打造 CLI 工具

1. 初始化项目 & 安装依赖

# 新建脚手架项目目录
mkdir react-scaffold-cli
cd react-scaffold-cli# 初始化 package.json
npm init -y# 安装核心依赖
npm install commander download-git-repo

2. 编写 CLI 核心逻辑(cli.js

#!/usr/bin/env node
const { program } = require("commander");
const download = require("download-git-repo");
const path = require("path");
const { execSync } = require("child_process");// 定义命令:react-scaffold create <projectName>
program.command("create <projectName>").description("创建 React + AntD + Zustand + TS 项目").action((projectName) => {// 1. 配置模板仓库 & 目标路径const repo = "github:jackywq/react-antd-zustand-scaffold#main"; const targetPath = path.join(process.cwd(), projectName); // 2. 从 Git 拉取模板download(repo, targetPath, {}, (err) => {if (err) {console.error("❌ 模板下载失败:", err);return;}console.log("✅ 模板下载完成!");try {// 3. 初始化 Git 仓库(解决 husky 依赖 .git 问题)console.log("📦 初始化 Git 仓库...");execSync(`cd ${projectName} && git init`, { stdio: "inherit" });// 4. 自动安装依赖console.log("📦 开始安装依赖...");execSync(`cd ${projectName} && npm install`, { stdio: "inherit" });// 5. 提示启动命令console.log("✅ 依赖安装完成!");console.log(`✅ 项目创建成功,可执行:cd ${projectName} && npm run start`);} catch (installErr) {console.error("❌ 依赖安装失败:", installErr);}});});// 解析命令行参数,触发对应逻辑
program.parse(process.argv);

3. 代码逐行解析

(1)基础配置:让脚本可执行
#!/usr/bin/env node

这行是 Shebang 声明,告诉系统 “用 Node.js 运行这个脚本”,这样我们就能直接用 react-scaffold create ... 调用,无需手动输入 node cli.js

(2)依赖引入:工具的 “左臂右膀”
const { program } = require("commander"); // 解析命令行参数
const download = require("download-git-repo"); // 拉取 Git 模板
const path = require("path"); // 处理文件路径
const { execSync } = require("child_process"); // 执行终端命令
  • commander:让我们能定义 create 命令,解析用户输入的 projectName
  • download-git-repo:从 GitHub 仓库下载模板代码(一行代码实现 git clone 功能)。
  • child_process:执行 git initnpm install 等终端命令,自动化初始化流程。
(3)命令定义:告诉用户怎么用
program.command("create <projectName>").description("创建 React + AntD + Zustand + TS 项目").action((projectName) => { ... });
  • command("create <projectName>"):定义 create 命令,<projectName> 是用户要创建的项目名称(必填)。
  • description(...):添加命令描述,执行 react-scaffold --help 时会显示。
  • action(...):命令的 “执行逻辑”,用户输入 create my-app 时,就会触发这里的代码。
(4)核心流程:项目创建全自动化
// 模板仓库地址(替换成你自己的 GitHub 仓库!)
const repo = "github:jackywq/react-antd-zustand-scaffold#main"; 
// 目标路径:当前目录 + 项目名(如 ./my-app)
const targetPath = path.join(process.cwd(), projectName); 
  • repo:格式是 github:用户名/仓库名#分支,指定从哪拉取模板。
  • targetPath:计算项目要创建的路径(比如用户当前在 ~/projects,执行 create my-app 就会生成 ~/projects/my-app)。
download(repo, targetPath, {}, (err) => { ... });

调用 download-git-repo 拉取模板,失败会提示 模板下载失败,成功则继续执行初始化流程。

execSync(`cd ${projectName} && git init`, { stdio: "inherit" });
execSync(`cd ${projectName} && npm install`, { stdio: "inherit" });
  • git init:初始化 Git 仓库(解决 husky 等工具依赖 .git 目录的问题)。
  • npm install:自动安装项目依赖(基于模板里的 package.json)。
  • { stdio: "inherit" }:让终端实时输出命令执行日志(用户能看到 git initnpm install 的过程)。

四、测试 & 发布:让脚手架真正能用起来!

1. 本地测试:直接运行 CLI

# 在脚手架项目目录执行
node cli.js create my-app
  • 观察终端输出:
    • 成功:模板下载完成! → 初始化 Git 仓库... → 依赖安装完成!
    • 失败:检查网络(能否访问 GitHub)、模板仓库地址是否正确。

2. 发布到 npm:让所有人都能安装

(1)修改 package.json,添加关键配置
{"name": "react-scaffold-cli","version": "1.0.0","bin": {"react-scaffold": "cli.js"  // 定义全局命令},"dependencies": {"commander": "^11.0.0","download-git-repo": "^3.0.2"}
}
  • bin:定义全局命令 react-scaffold,用户安装后可直接用 react-scaffold create ... 调用。
  • dependencies:声明生产依赖(commanderdownload-git-repo 必须被安装)。
(2)发布到 npm 仓库
# 1. 登录 npm(确保已注册账号)
npm login# 2. 发布脚手架
npm publish

发布成功后,任何人都能通过 npm install -g react-scaffold-cli 全局安装你的脚手架!

五、优化 & 扩展:让脚手架更强大

1. 模板仓库替换:用自己的项目模板

把 repo 换成你自己的 GitHub 仓库地址,比如:

const repo = "github:your-username/your-react-template#main";

模板仓库里可以包含:

  • React 路由配置(react-router-dom
  • AntD 基础组件(ButtonLayout 等)
  • Zustand 状态管理示例(用户登录状态、全局配置)

2. 增加交互:让用户选模板

如果想支持 多模板选择(比如 “React + Vue + ...”),可以用 inquirer 实现交互:

npm install inquirer
const inquirer = require("inquirer");program.command("create <projectName>").action(async (projectName) => {// 让用户选择模板const { template } = await inquirer.prompt([{type: "list",name: "template",message: "选择项目模板",choices: ["react-antd", "vue-element", "next-js"]}]);// 根据选择拼接不同的 repo 地址const repoMap = {"react-antd": "github:your-username/react-template#main","vue-element": "github:your-username/vue-template#main"};const repo = repoMap[template];// 后续流程和之前一样...});

3. 错误处理:让用户更清楚哪里出错了

如果下载模板失败,可以细化错误提示:

download(repo, targetPath, {}, (err) => {if (err) {if (err.message.includes("not found")) {console.error("❌ 模板仓库不存在,请检查地址!");} else if (err.message.includes("network")) {console.error("❌ 网络错误,请检查网络连接!");} else {console.error("❌ 模板下载失败:", err);}return;}// ...后续流程
});

六、总结:脚手架的价值不止于 “偷懒”

通过本文的 CLI 开发,你不仅学会了 “拉取模板 + 自动化流程” 的核心逻辑,更重要的是理解了 “标准化开发” 的意义:

  • 团队新人无需了解复杂技术栈配置,一行命令就能开始开发;
  • 项目结构、依赖版本统一,减少 “环境不一致” 导致的 Bug;
  • 后续迭代模板时,所有项目都能同步更新,真正做到 “一处修改,处处生效”。

如果你想让脚手架更强大,还能扩展:

  • 支持 多模板选择(React / Vue / 小程序);
  • 集成 代码规范检测(ESLint、Prettier);
  • 对接团队内部 Git 仓库,实现更定制化的流程。

现在,赶紧用你开发的脚手架生成一个项目,体验 “一键启动” 的快感吧~ 🚀

我的npmjs和github地址:
npmjs: react-scaffold-starter-cli - npm

github: https://github.com/jackywq/react-scaffold-starter-cli

github:https://github.com/jackywq/react-antd-zustand-scaffold

(如果觉得本文有用,欢迎点赞Csdn Github、分享给需要的同学,也可以在评论区交流你遇到的问题和优化思路~)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/95401.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/95401.shtml
英文地址,请注明出处:http://en.pswp.cn/diannao/95401.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python day43

浙大疏锦行 Python day43 import torch import numpy as np import pandas as pd import torchvision import torchvision.transforms as transforms import torch.nn as nn import torch.optim as optim import torch.nn.functional as F from torch.utils.data import Da…

python基于Hadoop的超市数据分析系统

前端开发框架:vue.js 数据库 mysql 版本不限 后端语言框架支持&#xff1a; 1 java(SSM/springboot)-idea/eclipse 2.NodejsVue.js -vscode 3.python(flask/django)–pycharm/vscode 4.php(thinkphp/laravel)-hbuilderx 数据库工具&#xff1a;Navicat/SQLyog等都可以 摘要&…

如何用 COLMAP 制作 Blender 格式的数据集

如何用 COLMAP 制作 Blender 格式的数据集并划分出 transforms_train.json、transforms_val.json 和 transforms_test.json。 一、什么是 Blender 格式数据集? Blender 格式数据集是 Nerf 和 Nerfstudio 常用的输入格式,其核心是包含了相机内外参的 JSON 文件,一般命名为:…

[GESP202309 六级] 2023年9月GESP C++六级上机题题解,附带讲解视频!

本文为GESP 2023年9月 六级的上机题目详细题解和讲解视频&#xff0c;觉得有帮助或者写的不错可以点个赞。 题目一讲解视频 GESP2023年9月六级上机题一题目二讲解视频 题目一:小羊买饮料 B3873 [GESP202309 六级] 小杨买饮料 - 洛谷 题目大意: 现在超市一共有n种饮料&#…

linux 操作ppt

目录 方法1&#xff1a;用 libreoffice 打开PPT文件 播放脚本&#xff1a; 方法2&#xff1a;用 python-pptx 创建和编辑PPT 方法3&#xff1a;其他方法 在Linux中&#xff0c;可以使用Python通过python-pptx库来创建和编辑PPT文件&#xff0c;但直接播放PPT文件需要借助其…

元数据管理与数据治理平台:Apache Atlas 基本搜索 Basic Search

文中内容仅限技术学习与代码实践参考&#xff0c;市场存在不确定性&#xff0c;技术分析需谨慎验证&#xff0c;不构成任何投资建议。 Apache Atlas 框架是一套可扩展的核心基础治理服务&#xff0c;使企业能够有效、高效地满足 Hadoop 中的合规性要求&#xff0c;并支持与整个…

LangChain4J-(1)-Hello World

一、LangChain4J是什么&#xff1f; LangChain4J 是一个专为 Java 生态系统设计的开源框架&#xff0c;用于简化与大语言模型&#xff08;LLM&#xff0c;如 OpenAI 的 GPT 系列、Google 的 Gemini、Anthropic 的 Claude 等&#xff09;的集成和交互。它借鉴了 Python 生态中 L…

HTTPS应用层协议-中间攻击人

HTTPS应用层协议-中间攻击人 • Man-in-the-MiddleAttack&#xff0c;简称“MITM 攻击” 确实&#xff0c;在方案 2/3/4 中&#xff0c;客户端获取到公钥 S 之后&#xff0c;对客户端形成的对称秘钥 X 用服务端给客户端的公钥 S 进行加密&#xff0c;中间人即使窃取到了数据&am…

利用 Makefile 高效启动 VIVADO 软件:深入解析与实践

利用 Makefile 高效启动 VIVADO 软件&#xff1a;深入解析与实践 系列文章目录 1、VMware Workstation Pro安装指南&#xff1a;详细步骤与配置选项说明 2、VMware 下 Ubuntu 操作系统下载与安装指南 3.基于 Ubuntu 的 Linux 系统中 Vivado 2020.1 下载安装教程 文章目录利用 …

[前端算法]排序算法

默认情况下&#xff0c;sort() 会将元素转换为字符串&#xff0c;然后按照 Unicode 编码的顺序进行排序&#xff1a; const fruits [apple, banana, cherry, date]; fruits.sort(); console.log(fruits); // 输出: ["apple", "banana", "cherry"…

C#标签批量打印程序开发

C#标签批量打印程序开发&#xff08;集成Bartender解决方案&#xff09;一、系统架构设计 1. 核心模块划分 public class LabelPrintingSystem {private IDataLoader _dataLoader; // 数据加载器private ITemplateEngine _templateEngine; // 模板引擎private IPrintControl…

ECC的原理、背景、工作机制和数学基础

ECC的原理、背景、工作机制和数学基础摘要&#xff1a;本文首先详细介绍ECC&#xff08;Error-Correcting Code&#xff0c;纠错码&#xff09;的原理&#xff0c;包括背景、工作机制和数学基础。然后&#xff0c;解释ECC在SRAM&#xff08;Static Random-Access Memory&#x…

计算机网络2-2:物理层下面的传输媒体

目录 导引型传输媒体 同轴电缆 双绞线 光纤 电力线 非导引型传输媒体 无线电波 微波 红外线 可见光 无线电频谱管理机构 导引型传输媒体 同轴电缆 双绞线 光纤 光在光纤中传播的基本原理 电力线 非导引型传输媒体 无线电波 微波 红外线 可见光 LiFi(可见光通信) …

Dify 从入门到精通(第 32/100 篇):Dify 的日志分析与监控

Dify 从入门到精通&#xff08;第 32/100 篇&#xff09;&#xff1a;Dify 的日志分析与监控 Dify 入门到精通系列文章目录 第一篇《Dify 究竟是什么&#xff1f;真能开启低代码 AI 应用开发的未来&#xff1f;》介绍了 Dify 的定位与优势第二篇《Dify 的核心组件&#xff1a…

【IntelliJ IDEA】修改堆内存

idea卡顿&#xff0c;鼠标漂移修改idea文件打开 idea 安装路径&#xff0c;【bin】目录下【idea64.exe.vmoptions】文件修改【-Xms】最小内存【-Xmx】最大内存-Xms2048m -Xmx9216midea更改内存设置工具栏帮助更改内存设置设置堆大小上限为 文件 设置的最大内存保存并重启Leslie…

Docker与Docker Compose:容器世界的“单兵作战”与“军团指挥官”

在容器化技术的浪潮中&#xff0c;Docker和Docker Compose如同“双子星”&#xff0c;一个专注于单兵作战&#xff0c;一个擅长军团指挥。它们看似相似&#xff0c;却各司其职。对于开发者来说&#xff0c;理解它们的区别不仅能让代码部署事半功倍&#xff0c;更能避免踩坑。本…

进阶向:Python编写自动化邮件发送程序

Python编写自动化邮件发送程序&#xff1a;从零开始详解在数字化时代&#xff0c;自动化邮件发送功能已成为企业和个人提升工作效率的重要工具。据统计&#xff0c;全球每天发送的商业邮件超过30亿封&#xff0c;其中约40%是通过自动化系统发送的。这种功能被广泛应用于多种场景…

ChatGpt 5系列文章1——编码与智能体

人工智能技术正在以惊人的速度发展&#xff0c;重新定义着开发人员的工作方式。2025年8月&#xff0c;OpenAI正式发布了面向开发人员的GPT-5 一、GPT-5的编码能力突破 GPT-5在关键编码基准测试中创造了行业新纪录(SOTA)&#xff0c;在SWE-bench Verified测试中得分74.9%&…

力扣top100(day02-05)--二叉树 02

102. 二叉树的层序遍历 /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* TreeNode(int val) { this.val val; }* TreeNode(int val, TreeNode left, TreeNode right)…

开疆智能Ethernet转ModbusTCP网关连接发那科机器人与三菱PLC配置案例

本案例是三菱FX5U PLC通过ethernet/IP转ModbusTCP网关对发那科机器人进行控制的配置案例。PLC端主要配置以太网端口设置在通信测试中&#xff0c;PLC作为主站&#xff0c;在PLC设置中选择“以太网端口”非常关键&#xff0c;以确保通信测试的正常进行。1、首先&#xff0c;在PL…