React Router 框架模式(Framework Mode)安装指南:create-react-router 从零搭建到原理剖析
【免费下载链接】react-routerDeclarative routing for React项目地址: https://gitcode.com/GitHub_Trending/re/react-router
React Router 支持 Declarative、Data、Framework 三种使用模式,其中 Framework 模式是最推荐的起步方式:它用 Vite 插件包裹 Data 模式的能力,额外提供类型安全的href、Route Module API、智能代码拆分以及 SPA/SSR/SSG 渲染策略(见 docs/start/modes.md)。本文以官方文档 docs/start/framework/installation.md 为主体,完整覆盖从模板创建、安装依赖、启动开发服务器到可用模板的实战流程,并结合本仓库 packages/create-react-router 的 CLI 源码,深入讲解该脚手架背后的执行步骤、全部命令行参数与模板解析机制。读完本文,你不仅能三步跑起一个 Framework 模式应用,还能理解npx create-react-router在背后究竟做了什么、各参数的默认值从哪里来。
快速上手:三步启动一个 Framework 模式应用
官方安装文档给出的标准流程是:大多数项目都应从模板起步,使用 React Router 官方维护的基础模板创建项目:
npx create-react-router@latest my-react-router-app然后进入新目录,安装依赖并启动开发服务器:
cd my-react-router-app npm i npm run dev启动后打开浏览器访问http://localhost:5173,即可看到运行中的应用。
需要说明两点边界:
npm i/npm run dev是在你新创建的项目中执行的命令(模板自带dev、build、start等 scripts);本仓库自身是 pnpm workspace,仓库内开发请使用pnpm install,不要把本仓库当作新建项目来安装。- 文档同时提供了等价的
npm create react-router写法(见 packages/create-react-router/README.md),npx create-react-router@latest与npm create react-router本质上是同一条路径:npx下载 npm 上的create-react-router包并执行其bin入口。从 packages/create-react-router/package.json 可以看到该包注册了create-react-router可执行文件,指向dist/cli.js。
创建出的项目长什么样
仓库内的集成测试模板与官方默认模板结构一致,可参考 integration/helpers/vite-7-template/package.json 与 integration/helpers/vite-8-template/package.json:核心 scripts 为dev(react-router dev)、build(react-router build)、start(react-router-serve ./build/server/index.js)和typecheck;依赖包含@react-router/dev、@react-router/express、@react-router/node、@react-router/serve、react-router、react、react-dom以及vite等。模板目录名带 Vite 主版本(vite-7 / vite-8),说明默认模板是跟随 Vite 主版本演进维护的。
深入 CLI:npx create-react-router 背后执行了什么
官方文档只展示了最简命令,而 CLI 的完整实现位于 packages/create-react-router/index.ts。其入口 cli.ts 负责收集 argv 并调用createReactRouter。从源码结构看,整个创建流程被拆分为一组顺序执行的步骤(index.ts):
| 步骤 | 对应函数 | 作用 |
|---|---|---|
| 1 | introStep | 打印 CLI 版本横幅;非交互 shell 下提示"等效于带--yes运行" |
| 2 | projectNameStep | 确定项目目录(位置参数或交互提示,默认./my-react-router-app) |
| 3 | copyTemplateToTempDirStep | 下载/拷贝模板到系统临时目录(带 loading 动画) |
| 4 | copyTempDirToAppDirStep | 检查目标目录文件冲突后拷贝到项目目录,并更新package.json |
| 5 | gitInitQuestionStep/gitInitStep | 询问(或按参数)是否执行git init+git add .+ 初始提交 |
| 6 | installDependenciesQuestionStep/installDependenciesStep | 询问(或按参数)是否用检测到的包管理器执行install |
| 7 | agentSkillsQuestionStep/copyAgentSkillsToAppDirStep | 是否把 React Router agent skill 拷入.agents/skills/react-router |
| 8 | doneStep | 打印"进入项目目录"等收尾提示 |
几个值得了解的实现细节:
- 冲突保护:
copyTempDirToAppDirStep会递归比对目标目录与模板文件,若存在重名文件且未加--overwrite,交互模式下会列出将被覆盖的文件并二次确认;非交互环境下则直接报错终止(index.ts)。拷贝时始终跳过.git/与node_modules/目录。 - 版本钉选:
updatePackageJSON会把模板package.json中react-router及@react-router/*依赖里声明为*的版本,改写为与所选 React Router 版本匹配的^x.y.z(预发布版本则精确钉死),同时把name字段替换为你的项目名(index.ts)。这就是为什么文档中用@latest时你能拿到当前最新稳定版,而用--react-router-version时可以精确复现某一版本。 - 包管理器自动探测:CLI 读取
npm_config_user_agent环境变量判断你实际是通过 npm / pnpm / yarn / bun / deno / nub 中的哪一个执行的命令(index.ts),安装步骤会沿用同一个包管理器,避免"用 pnpm 创建却用 npm 安装"的混用。合法值列表见 index.ts。
完整参数参考
--help输出与parseArgs定义(index.ts)一致,测试用例 packages/create-react-router/tests/create-react-router-test.ts 也对该输出做了快照校验。参数完整清单如下:
| 参数 | 说明 | 默认行为 |
|---|---|---|
<projectDir>(位置参数) | React Router 项目目录 | 交互提示,初始值./my-react-router-app |
--template <name> | 指定项目模板 | 使用 React Router 官方默认模板 |
--[no-]install | 创建后是否安装依赖 | 交互询问;非交互环境默认安装 |
--package-manager <name> | 指定包管理器 | 自动探测,兜底npm |
--show-install-output | 显示安装过程的原始输出 | 不显示(只显示 loading 指示) |
--[no-]agent-skills | 是否包含 React Router agent skill | 交互询问;非交互环境默认包含 |
--[no-]git-init | 是否初始化 Git 仓库并提交 | 交互询问;非交互环境默认初始化 |
--react-router-version, -v <ver> | 使用的 React Router 版本 | 与 CLI 包同版本(即@latest对应的版本) |
--token <token> | GitHub 个人访问令牌,用于私有仓库模板 | 不传 |
--overwrite | 允许覆盖目标目录中的冲突文件 | 不覆盖(交互确认或报错) |
--yes, -y | 跳过所有提问直接执行 | 交互环境不启用 |
--no-color/--no-motion | 禁用彩色输出 / 禁用动画 | 不启用 |
--help, -h/--version, -V | 打印帮助 / 版本并退出 | — |
几个行为要点(均以 index.ts 源码为准):
- 非交互 shell 自动
--yes:getContext在检测到非 TTY 环境时会强制yes = true,即 CI/脚本中运行时不会有任何交互提示,等效于全部按默认值执行;但此时必须提供项目目录位置参数,否则会直接报错(index.ts、index.ts)。 - 版本校验:
--react-router-version会经 semver 校验,非法值会告警并回退为 CLI 自身版本(index.ts)。 - 一个可直接复制到脚本中的示例(关闭动画、显式包管理器、钉住版本):
npx create-react-router@latest my-app \ --template remix-run/react-router-templates/basic \ --package-manager pnpm \ --react-router-version 8 \ --yes模板机制:不止一种来源
文档提到除了官方默认模板,还可以通过--template使用"可直接部署"的社区模板(如remix-run/react-router-templates/<template-name>)。模板解析逻辑在 packages/create-react-router/copy-template.ts,按以下优先级判定来源:
- 本地路径:
file://URL、本地目录、本地 tarball(.tar.gz/.tgz); - GitHub 仓库缩写:
owner/repo或owner/repo/目录形式,内部会请求 GitHub 的 tarball 接口(若指定了目录,则直接走 codeload 分支 tarball 并在解包时按路径前缀过滤,见 copy-template.ts); - GitHub 仓库 URL:完整仓库 URL 或
.../tree/<branch>/<dir>形式的目录 URL(copy-template.ts 中定义了严格的 URL 校验规则); - 任意 tarball URL:任意可下载的
.tar.gz链接(包括 GitHub Release 资产,会先查 API 换取下载地址,copy-template.ts)。
对私有仓库模板,传--token携带具有该仓库访问权限的 GitHub 个人访问令牌,请求会附加Authorization: token <token>头(copy-template.ts)。
模板内容本身必须是一个含合法package.json的 React Router 项目——创建结束时updatePackageJSON会校验这一点,缺失或非法都会终止(index.ts)。
环境要求与验证路径
- Node.js:packages/create-react-router/package.json 声明
engines.node为>=22.22.0;仓库内集成测试模板同样要求node >=22.22.0(见 integration/helpers/vite-7-template/package.json 的engines字段)。请在满足该 Node 版本的机器上执行安装命令。 - 默认端口:文档承诺
npm run dev后可访问http://localhost:5173(Vite 默认端口)。 - 回归验证:CLI 的端到端行为(
--help快照、交互提示、模板拷贝、冲突处理等)由 packages/create-react-router/tests/create-react-router-test.ts 覆盖,其中使用 MSW 模拟 GitHub 请求(packages/create-react-router/tests/msw.ts),可作为理解 CLI 各分支行为的可执行依据。
小结
Framework 模式的安装路径可以浓缩为:npx create-react-router@latest <dir>→<dir>内<pkg> i→<pkg> run dev→ 打开http://localhost:5173。脚手架 CLI 在这一过程中完成了模板拉取(本地目录/tarball、GitHub 缩写或 URL、任意 tarball 链接四种来源)、文件冲突保护、依赖版本钉选、包管理器对齐、Git 初始化与 agent skill 注入一整套工程化动作,所有行为均可通过本文参数表中的命令行选项在 CI 等非交互场景下完全确定化。下一步建议继续阅读 路由配置,了解创建出的项目中routes.ts与 Route Module 的用法。
【免费下载链接】react-routerDeclarative routing for React项目地址: https://gitcode.com/GitHub_Trending/re/react-router
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考