首页
/ Strapi create-strapi CLI 完全指南:从一行命令到新项目的完整流程与实现解析

Strapi create-strapi CLI 完全指南:从一行命令到新项目的完整流程与实现解析

2026-09-06 12:36:09作者:卓艾滢Kingsley

create-strapi 是 Strapi 官方的项目脚手架命令行包,负责把“创建一个新的 Strapi 应用”这件事压缩成一条命令。本文基于仓库中 create-strapi 包的 README 及其背后的 create-strapi-app 实现源码 展开,讲清每条快速启动命令背后发生了什么:CLI 如何解析参数、如何交互式提问、默认生成哪些依赖、以及数据库与模板相关的完整选项,读完你可以从零开始用任意包管理器初始化一个 Strapi 5.x 项目,并理解脚手架每一步的默认值来源。

包定位:一个极薄的入口包装器

Strapi 仓库把“创建项目”的 CLI 拆成了两个包:

#!/usr/bin/env node
'use strict';
require('create-strapi-app/bin');

它唯一做的事就是把执行权委托给 create-strapi-app 包的可执行入口。

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 strapiyarn create strapipnpm 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.tsOptions 接口中。

基础选项

选项 作用 备注
[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.tsif (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 只接受三种值:mysqlpostgressqlite(类型约束见 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.databaseDatabaseInfo 结构: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-testshideHelp()),注释明确说明目的是“让旧 CI/脚本继续能跑”,仅接受、被忽略。

参数组合的硬性限制

index.ts 在真正开始脚手架之前做了一组前置校验,任何一条不满足都会以 fatal 立即终止,这在写自动化脚本时尤其值得注意:

  1. --javascript / --typescript 不能与 --template 同时使用(模板自带语言设定);
  2. --ts--js 不能同时使用;
  3. --example 不能与 --template 同时使用;
  4. --template 的值不能以 - 开头(防止与选项冲突);
  5. 多个包管理器选项不能同时出现(--use-npm--use-pnpm--use-yarn 至多选一个);
  6. 使用 --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@^18react-dom@^18react-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.tsOptions/Scope 类型,最后用 examples/emptyexamples/getstarted 等示例工程核对生成结果的目录结构。适用前提:Node.js >=20.0.0 <=26.x.x,且命令拉取的 @latest 版本以 npm 上实际发布的版本为准。

登录后查看全文
热门项目推荐
相关项目推荐