Strapi create-strapi CLI 完全指南:从一行命令到新项目的完整流程与实现解析
create-strapi 是 Strapi 官方的项目脚手架命令行包,负责把“创建一个新的 Strapi 应用”这件事压缩成一条命令。本文基于仓库中 create-strapi 包的 README 及其背后的 create-strapi-app 实现源码 展开,讲清每条快速启动命令背后发生了什么:CLI 如何解析参数、如何交互式提问、默认生成哪些依赖、以及数据库与模板相关的完整选项,读完你可以从零开始用任意包管理器初始化一个 Strapi 5.x 项目,并理解脚手架每一步的默认值来源。
包定位:一个极薄的入口包装器
Strapi 仓库把“创建项目”的 CLI 拆成了两个包:
- packages/cli/create-strapi:发布到 npm 的
create-strapi包本体,内容极薄,只有一个 bin/index.js 入口脚本:
#!/usr/bin/env node
'use strict';
require('create-strapi-app/bin');
它唯一做的事就是把执行权委托给 create-strapi-app 包的可执行入口。
- packages/cli/create-strapi-app:真正实现所有创建逻辑的包,核心代码集中在 src/index.ts、src/create-strapi.ts 与 src/prompts.ts。
从 create-strapi 的 package.json 可以看到几个关键事实:
- 包版本与 Strapi 主包同步,当前仓库为
5.52.2; bin字段指向./bin/index.js,因此npx create-strapi能直接调用;- 唯一依赖就是同版本的
create-strapi-app; engines声明了运行环境要求:Node.js>=20.0.0 <=26.x.x、npm>=6.0.0。这意味着在低版本 Node 上运行该命令会被 src/index.ts 中调用的checkNodeRequirements()前置检查拦截。
这种“薄入口 + 重实现”的结构让 npm 生态里 npm init strapi、yarn create strapi、pnpm create strapi 这类约定俗成的创建命令全部落到同一个实现上。
快速上手:README 推荐的四种等价命令
README 给出的“Quick usage (recommended)”只有四行命令,但它们分别对应不同包管理器的生态约定:
npm init strapi@latest
yarn create strapi@latest
pnpm create strapi@latest
npx create-strapi@latest
npm init <name>是 npm 的惯例:等价于执行create-<name>,所以npm init strapi实际运行的是create-strapi;yarn create/pnpm create是 yarn 与 pnpm 各自的等价语法;npx create-strapi@latest则是不经过包管理器 create/init 别名、直接按包名调用的通用写法。
四种方式最终都会进入 bin/index.js,再转发到 create-strapi-app 的 commander 命令行定义中。命令接受一个可选的位置参数 [directory] 表示项目目录名,其余全部是 -- 选项。
完整的命令行选项清单
README 没有列出参数,但 src/index.ts 中的 command 定义给出了完整且可验证的选项全集。这些选项对应的 TypeScript 类型声明在 src/types.ts 的 Options 接口中。
基础选项
| 选项 | 作用 | 备注 |
|---|---|---|
[directory] |
项目目录名 | 位置参数;缺省时交互询问,默认值 my-strapi-project |
-v, --version |
打印版本号 | commander 内建 |
--quickstart |
快速创建 | 源码中标注为 deprecated;必须显式给出 directory,否则直接报错退出 |
--no-run |
创建后不自动启动应用 | 对应 runApp 字段 |
语言选择
| 选项 | 作用 |
|---|---|
--ts, --typescript |
以 TypeScript 初始化项目(README 与源码注释均标注 default) |
--js, --javascript |
以 JavaScript 初始化项目 |
二选一互斥,同时给出会触发 fatal 错误。选择 TypeScript 时,脚手架会额外写入开发依赖:typescript@^5、@types/node@^20、@types/react@^18、@types/react-dom@^18(见 src/index.ts 中 if (scope.useTypescript) 分支)。
包管理器选项
| 选项 | 作用 |
|---|---|
--use-npm / --use-yarn / --use-pnpm |
指定项目使用的包管理器,三者互斥 |
如果不显式指定,getPkgManager() 会读取 npm_config_user_agent 环境变量做推断:以 yarn 开头则用 yarn,以 pnpm 开头则用 pnpm,否则回退到 npm。这就是为什么“用哪个包管理器跑 create 命令,生成的项目默认就是该包管理器”这一行为成立的源码依据。
安装与自动化
| 选项 | 作用 |
|---|---|
--install / --no-install |
是否安装依赖(默认安装,交互确认) |
--non-interactive |
跳过所有交互提示、全部取默认值;必须显式给出 directory |
--git-init / --no-git-init |
是否 git init(默认是) |
布尔型选项的解析遵循 resolveOption() 的三级优先级:显式命令行参数 > 非交互模式下的默认值 > 交互式提问(默认值均为 true)。
数据库选项
--dbclient 只接受三种值:mysql、postgres、sqlite(类型约束见 src/types.ts 中的 DBClient)。配套的连接参数选项为:
--dbclient <dbclient> # mysql | postgres | sqlite
--dbhost <dbhost> # 数据库主机
--dbport <dbport> # 数据库端口
--dbname <dbname> # 数据库名
--dbusername <dbusername>
--dbpassword <dbpassword>
--dbssl <dbssl> # SSL 开关
--dbfile <dbfile> # sqlite 的数据库文件路径
--skip-db # 完全跳过数据库配置
这些值最终汇入 Scope.database(DatabaseInfo 结构:client + connection),并配合 addDatabaseDependencies() 把对应的数据库驱动依赖追加进生成的 package.json,写入模板中的 config/database.ts。
Cloud 与模板选项
| 选项 | 作用 |
|---|---|
--skip-cloud |
跳过 Strapi Cloud 登录与云项目创建 |
--example / --no-example |
是否附带示例内容与数据结构(交互默认否) |
--template <template> |
使用指定的 Strapi 模板仓库初始化 |
--template-branch <branch> |
模板仓库的分支 |
--template-path <path> |
模板仓库内的子目录路径 |
此外源码中还保留了一对隐藏的废弃兼容参数 --enable-ab-tests / --no-enable-ab-tests(hideHelp()),注释明确说明目的是“让旧 CI/脚本继续能跑”,仅接受、被忽略。
参数组合的硬性限制
index.ts 在真正开始脚手架之前做了一组前置校验,任何一条不满足都会以 fatal 立即终止,这在写自动化脚本时尤其值得注意:
--javascript/--typescript不能与--template同时使用(模板自带语言设定);--ts与--js不能同时使用;--example不能与--template同时使用;--template的值不能以-开头(防止与选项冲突);- 多个包管理器选项不能同时出现(
--use-npm、--use-pnpm、--use-yarn至多选一个); - 使用
--quickstart或--non-interactive时必须显式指定directory。
交互式流程:没有参数时会问什么
当不传选项直接运行时,src/prompts.ts 定义了五个 inquirer 提问,默认值全部可以在源码中逐一核对:
| 提问 | 默认值 |
|---|---|
What is the name of your project? |
my-strapi-project |
Start with Typescript? |
是 |
Start with an example structure & data? |
否 |
Initialize a git repository? |
是 |
Install dependencies with <pm>?(pm 为解析出的包管理器) |
是 |
若未指定 --skip-cloud 且处于交互模式,还会先经过 handleCloudLogin()(来自 src/cloud.ts)处理 Cloud 登录/试用创建,这也是 --skip-cloud 存在的原因。
默认生成的项目骨架
创建过程中的核心数据结构是 types.ts 中的 Scope 接口,它承载了目录、包管理器、数据库信息、模板信息、TS/示例开关等全部状态,随后传给 create-strapi.ts 中的 createStrapi(scope) 执行实际落盘。从 src/index.ts 中构造 scope 的代码可以直接读出新项目的默认依赖集(版本号为当前仓库 Strapi 版本 5.52.2):
@strapi/strapi、@strapi/database、@strapi/plugin-users-permissions、@strapi/plugin-cloud(均与 CLI 同版本)- 前端运行时:
react@^18、react-dom@^18、react-router-dom@^6.30.3(注释说明该范围与@strapi/*的 peer 依赖保持一致,以保证 npm 的 peer 解析干净)、styled-components@^6 - 选用 TypeScript 时追加
typescript@^5与对应@types/* - 根据
--dbclient追加数据库驱动
另外两个实现细节值得了解:
- 每次运行都会生成随机
uuid(可被环境变量STRAPI_UUID_PREFIX加前缀)与基于它的installId,用于遥测; - 工作过程使用系统临时目录下的随机路径(
os.tmpdir()/strapi<随机十六进制>)暂存,process.env.DOCKER === 'true'时会被记录进scope.docker,用于识别 Docker 内运行场景。
创建失败时,createStrapi 抛出的错误会先经 trackError() 上报,再以 logger.fatal 打印错误信息并终止进程。
实战示例
基于上述源码事实,一条完全静默、可放进 CI 或文档的等价命令可以写成:
npx create-strapi@latest my-app \
--non-interactive \
--ts \
--use-npm \
--dbclient sqlite \
--skip-cloud
含义:在 my-app 目录创建 TypeScript 项目,用 npm 安装依赖,数据库用 sqlite,跳过 Cloud 登录,全程无交互。若希望创建后立即启动,可去掉 --non-interactive 依赖默认的“安装后询问”,或使用 --quickstart <directory>(注意该参数已被标记 deprecated,且必须给目录名)。
小结
create-strapi 的价值在于把 Strapi 项目的初始化收敛为一条命令,而 packages/cli/create-strapi 本身只是一个入口转发器;真正完整的参数体系、交互默认值、依赖注入与校验规则都实现在 packages/cli/create-strapi-app 中。建议按以下顺序深入当前仓库:先读 README 的四种启动命令,再看 src/index.ts 的选项定义与校验逻辑,然后对照 src/prompts.ts 的交互默认值和 src/types.ts 的 Options/Scope 类型,最后用 examples/empty 或 examples/getstarted 等示例工程核对生成结果的目录结构。适用前提:Node.js >=20.0.0 <=26.x.x,且命令拉取的 @latest 版本以 npm 上实际发布的版本为准。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0625
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00