Strapi create-strapi-app 使用指南:从 CLI 参数到项目生成流程的完整解析
本文基于 Strapi 仓库中 create-strapi-app 包的 README 及其源码,系统讲解如何用 create-strapi-app CLI 创建一个全新的 Strapi 项目:包括 yarn create / npx / 全局安装三种启动方式、全部命令行参数与默认值、模板机制(内置 vanilla/example 与外部 GitHub/本地模板)、数据库配置逻辑,以及 CLI 内部的完整项目生成流程与故障恢复方法。读完后,你可以独立、可复现地完成交互式或非交互式(CI 场景)的 Strapi 项目初始化。
前置要求:Node.js 与 npm 版本
CLI 在运行任何逻辑之前会先做环境校验。从 engines 定义 与 package.json 的 engines 字段可以确认当前版本(5.52.2)的要求:
- Node.js:
>=20.0.0 <=26.x.x - npm:
>=6.0.0
checkNodeRequirements 函数的具体行为是:
- 若当前 Node 版本不满足
engines.node范围,直接logger.fatal终止并提示“Strapi requires Node.js >=20.0.0 <=26.x.x”; - 若 Node 大版本小于 26 且为奇数(非 LTS),则打印警告,提示 Strapi 仅支持 Node.js LTS 版本,其他版本可能存在兼容性问题。
因此建议始终使用偶数 LTS 版本(如 Node 20、22、24)运行该 CLI。
安装与快速开始
README 给出了三种等价的启动方式,核心都是调用 create-strapi-app 的二进制入口(bin: ./bin/index.js,见 package.json),并将项目目录名作为第一个参数:
方式一:yarn create(推荐)
yarn create strapi-app my-project
方式二:npx
npx create-strapi-app my-project
方式三:全局安装后直接调用
# yarn
yarn global add create-strapi-app
create-strapi-app my-app
# npm
npm install -g create-strapi-app
create-strapi-app my-app
执行后 CLI 会依次询问若干问题(见下文“交互式提示”一节),默认行为是:创建 TypeScript 项目、使用 sqlite 数据库、自动安装依赖并初始化 git 仓库。
一个典型的非交互(自动化)调用示例,可参考后文的 --non-interactive 组合:
npx create-strapi-app my-project --non-interactive --skip-cloud --no-install
交互式提示与默认值
交互式问题全部集中在 prompts.ts 与 utils/database.ts 中,使用 inquirer 实现。逐项默认值如下:
| 问题 | 来源 | 默认值 |
|---|---|---|
| What is the name of your project? | prompts.directory | my-strapi-project |
| Start with Typescript? | prompts.typescript | true |
| Start with an example structure & data? | prompts.example | false |
| Install dependencies with <packageManager>? | prompts.installDependencies | true |
| Initialize a git repository? | prompts.gitInit | true |
| Do you want to use the default database (sqlite)? | database.ts 中的 dbPrompt | true |
| Choose your default database client | 同上 | sqlite |
| Database name: / Host: / Port: / Username: / Password: / SSL | 同上 | 库名 strapi、host 127.0.0.1、postgres 端口 5432、mysql 端口 3306、SSL false |
| Filename:(sqlite 专用) | 同上 | .tmp/data.db |
其中几个值得注意的细节:
- 数据库名输入若包含
.会被校验函数直接拒绝(“The database name can't contain a "."”); - 选择 sqlite 时只问一个
filename(默认.tmp/data.db);选择 postgres/mysql 时问database/host/port/username/password/ssl六项; - 这些选择最终会被写入项目根目录的
.env文件(见下文“环境变量”小节)。
完整命令行参数参考
所有选项在 src/index.ts 的 commander 定义 中声明,参数类型为 Options 接口。完整清单如下:
| 参数 | 说明 |
|---|---|
create-strapi-app [directory] |
位置参数,项目目录;缺省时交互式询问,默认 my-strapi-project |
--quickstart |
快速创建(源码中标注 deprecated,等价于跳过交互并使用默认值) |
--no-run |
创建后不自动启动应用 |
--ts, --typescript |
使用 TypeScript 初始化(默认) |
--js, --javascript |
使用 JavaScript 初始化 |
--use-npm / --use-yarn / --use-pnpm |
指定包管理器 |
--install |
安装依赖 |
--no-install |
不安装依赖 |
--skip-cloud |
跳过 Cloud 登录与项目创建 |
--example |
使用示例应用(带内容类型与种子数据) |
--no-example |
不使用示例应用 |
--git-init |
初始化 git 仓库 |
--no-git-init |
不初始化 git 仓库 |
--non-interactive |
跳过所有交互式提示并使用默认值(自动化场景关键参数) |
--dbclient <dbclient> |
数据库客户端:sqlite / mysql / postgres |
--dbhost <dbhost> |
数据库主机 |
--dbport <dbport> |
数据库端口 |
--dbname <dbname> |
数据库名 |
--dbusername <dbusername> |
数据库用户名 |
--dbpassword <dbpassword> |
数据库密码 |
--dbssl <dbssl> |
数据库 SSL(传 true 表示开启) |
--dbfile <dbfile> |
sqlite 数据库文件路径 |
--skip-db |
跳过数据库配置(直接使用 sqlite 默认值) |
--template <template> |
指定一个 Strapi 模板(官方/本地/GitHub) |
--template-branch <branch> |
模板的分支 |
--template-path <path> |
模板仓库内的子路径 |
此外源码中还注册了两个隐藏的参数 --enable-ab-tests / --no-enable-ab-tests,注释明确说明它们是“Legacy no-ops”,仅为兼容旧 CI 脚本而存在,实际被忽略(index.ts L53-L55)。
参数冲突与硬性校验
index.ts 的 run 函数 在进入主流程前做了一组互斥校验,任何一条触发都会 logger.fatal 终止:
--javascript/--typescript不能与--template同时使用;--typescript与--javascript不能同时使用;--example不能与--template同时使用;- 模板名不能以
-开头; --use-npm、--use-pnpm、--use-yarn不能同时指定多个;- 使用
--quickstart或--non-interactive时必须显式提供<directory>位置参数。
另有一个安装路径校验 checkInstallPath:目标目录若已存在,必须是一个目录且最多只能有 1 个文件(实际要求接近空目录),否则会报 “You can only create a Strapi app in an empty directory”。
项目生成流程:从目录创建到种子数据
核心编排逻辑在 src/create-strapi.ts 中。createStrapi 先 ensureDir 创建目标目录,随后 createApp 按以下顺序执行(任一步失败都会 fse.remove(rootPath) 清理已生成的目录后抛错,保证不留半成品):
- 拷贝模板:
- 未指定
--template时,按useExample与useTypescript组合选择内置模板:example/vanilla/example-js/vanilla-js,从包内templates/目录整体复制到目标路径(create-strapi.ts L113-L123); - 指定
--template时调用 copyTemplate 拉取外部模板,完成后强制检查package.json是否存在,缺失则报 “Missing package.json in template”。
- 未指定
- 写 package.json:createPackageJSON 生成项目的
package.json,并合并 scope 中的依赖声明。其中 index.ts L168-L179 预置了核心依赖:当前版本的@strapi/strapi、@strapi/database、@strapi/plugin-users-permissions、@strapi/plugin-cloud,以及react@^18.0.0、react-dom@^18.0.0、react-router-dom@^6.30.3、styled-components@^6.0.0;若为 TypeScript 项目还会加入typescript@^5、@types/node@^20、@types/react@^18、@types/react-dom@^18(index.ts L205-L213)。 - 写
.env:generateDotEnv 用 lodash template 生成.env,内容包含:- 服务端口:
HOST=0.0.0.0、PORT=1337; - 六个随机生成的密钥(
crypto.randomBytes(16).toString('base64')):APP_KEYS(4 段拼接)、API_TOKEN_SALT、ADMIN_JWT_SECRET、JWT_SECRET、TRANSFER_TOKEN_SALT、ENCRYPTION_KEY; - 数据库段落:
DATABASE_CLIENT、DATABASE_HOST、DATABASE_PORT、DATABASE_NAME、DATABASE_USERNAME、DATABASE_PASSWORD、DATABASE_SSL、DATABASE_FILENAME,与前面数据库配置的选择一一对应。
- 服务端口:
- 包管理器专属配置:
- yarn ≥ 3 且项目内不存在
.yarnrc.yml时,写入nodeLinker: node-modules(create-strapi.ts L160-L165); - pnpm 时解析其版本并写入相应 workspace 配置(writePnpmWorkspaceConfig)。
- yarn ≥ 3 且项目内不存在
- 安装依赖(当
installDependencies为真):runInstall 用execa调用所选包管理器的 install 命令,并注入NODE_ENV=development与包管理器相关的环境变量。 .gitignore与 git 初始化:无论用户是否启用 git,都会确保写出.gitignore(内容来自 gitignore.ts);若gitInit为真,则 tryGitInit 执行git init。- 示例数据种子:仅当
useExample && installDependencies且存在scripts/seed.js时,执行<packageManager> run seed:example;失败只打印 “Failed to seed your database. Skipping”,不视为致命错误。 - 可选的自动启动:
--quickstart且未禁用run且依赖已安装时,会以stdio: 'inherit'直接执行<packageManager> run develop(create-strapi.ts L299-L323)。
创建结束后的输出与推荐命令
流程末尾,CLI 会打印项目内可用的命令(create-strapi.ts L255-L297):
<packageManager> run develop # 监听模式启动(开发)
<packageManager> run start # 无监听模式启动
<packageManager> run build # 构建管理后台
<packageManager> run deploy # 部署
<packageManager> run strapi # 查看全部命令
若使用了示例应用还会额外提示 <packageManager> run seed:example 用于灌入示例数据。最终给出的启动指引按依赖是否已安装分两种:
# 已安装依赖
cd my-project
yarn run develop # 或 npm / pnpm run develop
# 未安装依赖(--no-install 场景)
cd my-project
<packageManager> install
<packageManager> run develop
内置模板:vanilla 与 example 两种起步方式
CLI 包内自带四套模板,位于 packages/cli/create-strapi-app/templates:
| 模板名 | 触发条件 | 特点 |
|---|---|---|
vanilla |
默认(TypeScript) | 空项目骨架:config/(admin/api/database/middlewares/plugins/server 六份配置)、src/admin、src/api、src/extensions、src/index.ts、tsconfig.json |
vanilla-js |
--js |
同上,JavaScript 版(jsconfig.json) |
example |
--example(TypeScript) |
在 vanilla 基础上预置 about/article/author/category/global 等内容类型、shared 组件(media/quote/rich-text/seo/slider)、data/data.json 种子数据与 scripts/seed.js |
example-js |
--example --js |
同上,JavaScript 版 |
以 templates/vanilla 为例,其 config/ 目录包含 admin.ts、api.ts、database.ts、middlewares.ts、plugins.ts、server.ts 六个配置文件;templates/example 的 src/api/ 下则已有完整的 content-types/services/controllers/routes 四层结构,适合直接上手研究 Strapi 项目组织方式。
外部模板机制:--template 的四种解析路径
指定 --template 后,copyTemplate 按以下优先级解析模板来源,所有网络拉取均带 3 次重试:
- 官方模板名:纯字母字符串(
/^[a-zA-Z]*$/),会先向 GitHub API 发 HEAD 请求确认strapi/strapi仓库templates/<name>目录存在,然后下载该仓库对应分支的 tarball 并解压其中templates/<name>子路径(template.ts L23-L41)。仓库根的 templates 目录 就是官方模板的存放处,例如 templates/website。 - 本地路径:以
file://开头或解析后本地存在的目录,直接fse.copy复制。 - GitHub 简写:形如
owner/repo或owner/repo/path的非 URL 字符串(isGithubShorthand),从对应仓库下载,subPath取剩余路径段或--template-path。 - GitHub 完整 URL:形如
https://github.com/owner/repo/tree/branch/path的地址,解析出 owner/repo/branch/路径(isGithubRepo),同样下载对应 tarball 子路径。
--template-branch 与 --template-path 用于覆盖分支与子路径。再次强调约束:使用 --template 时不能再叠加 --example、--js、--ts,因为模板自身决定了语言与结构。
数据库配置:从 CLI 参数到 .env 落地
数据库解析逻辑在 getDatabaseInfos 中,行为决策树为:
--skip-db:直接返回默认配置sqlite+.tmp/data.db;--dbclient取值必须是sqlite/mysql/postgres之一,否则 fatal(“Invalid --dbclient ... expected one of sqlite, postgres, mysql”);- 只要提供了任意
--db*参数(dbclient/dbhost/dbport/dbname/dbusername/dbpassword六项之一),即视为“参数模式”:非 sqlite 时必须六项齐全,缺任何一项都会报 “Required database arguments are missing: ...”;sqlite 可只给--dbclient sqlite(加可选的--dbfile); - 完全没给
--db*参数时:--quickstart或--non-interactive下直接用 sqlite 默认值,交互模式下进入dbPrompt问答。
--dbssl 的取值会被解析为布尔('true' 为开),仅对 postgres/mysql 有意义。
驱动依赖自动注入:addDatabaseDependencies 按客户端把对应驱动写入项目依赖,当前仓库中锁定的版本为:
| 客户端 | 驱动 | 版本 |
|---|---|---|
| mysql | mysql2 |
3.20.0 |
| postgres | pg |
8.20.0 |
| sqlite | better-sqlite3 |
12.8.0 |
生成的 .env 中 DATABASE_CLIENT 等变量与上述选择一一对应,之后 config/database.ts 这类项目配置文件即可读取这些环境变量完成连接,无需改动代码。
包管理器选择与自动检测
getPkgManager 的决策顺序:
- 显式参数优先:
--use-npm→npm,--use-pnpm→pnpm,--use-yarn→yarn; - 未显式指定时,读取环境变量
npm_config_user_agent:以yarn开头则用 yarn,以pnpm开头则用 pnpm; - 兜底为
npm。
这个机制保证了在 yarn/pnpm 环境里执行 yarn create strapi-app 或 pnpm create ... 时,后续 install、seed、develop 等子命令会自动沿用你当前使用的包管理器,无需额外声明。
非交互模式与自动化场景
对 CI/CD 或脚本化创建项目,推荐用 --non-interactive(--quickstart 已标记 deprecated)。该模式下所有布尔选项走 resolveOption 的默认值分支:安装依赖、git init、TypeScript、sqlite 数据库。一个完整的自动化示例:
# 非交互创建 TypeScript 空项目,跳过 cloud 登录,不自动安装依赖
npx create-strapi-app my-app --non-interactive --skip-cloud --no-install --no-git-init
# 非交互创建,并直接指定远程 postgres(六项参数需齐全)
npx create-strapi-app my-app --non-interactive --skip-cloud \
--dbclient postgres --dbhost db.example.com --dbport 5432 \
--dbname strapi --dbusername strapi --dbpassword 'secret' --dbssl true
需要牢记的自动化约束:非交互模式必须提供 <directory>;--dbclient 为 mysql/postgres 时六个 --db* 参数缺一不可;想完全不配数据库就用 --skip-db。
故障排查要点
源码中的错误处理给出了明确的自救路径:
-
依赖安装失败:
createApp会捕获 install 错误并提示——“项目已正确创建”,手动进入目录补装即可(create-strapi.ts L209-L219):cd my-project yarn install # 或 npm install / pnpm install -
目标目录非空:换到空目录,或先清空(要求最多只允许 1 个文件存在)。
-
外部模板失败:确认模板仓库/分支/路径存在(CLI 会先 HEAD 检查),且模板内必须含
package.json;--template-branch拼写错误是常见原因。 -
seed 失败:使用
--example且自动种子失败时仅跳过,可事后手动执行<packageManager> run seed:example重试。 -
版本问题:Node 版本不满足
>=20.0.0 <=26.x.x时 CLI 会直接终止,切换 Node 版本后即可重试。
小结
create-strapi-app 是 Strapi v5 中开箱创建项目的官方入口:三种等价启动方式(yarn create / npx / 全局安装)、一套完整的参数体系(语言、包管理器、数据库、模板、git、非交互),以及一套有清理保障的生成流程(模板拷贝 → package.json/.env → 依赖安装 → git 初始化 → 种子数据)。日常开发用交互式默认值即可;在 CI 或批量创建场景中,组合 --non-interactive --skip-cloud 与 --db* / --skip-db 参数即可完全脚本化。所有行为均可在 packages/cli/create-strapi-app 的源码中逐行核对,内置模板可直接参考 templates/vanilla 与 templates/example 的结构。
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 StartedRust0624
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