news 2026/9/7 17:24:24

Strapi example-js 模板实战:从 develop 启动、build 构建到 strapi deploy 部署的完整工程链路

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Strapi example-js 模板实战:从 develop 启动、build 构建到 strapi deploy 部署的完整工程链路

Strapi example-js 模板实战:从 develop 启动、build 构建到 strapi deploy 部署的完整工程链路

【免费下载链接】strapi🚀 Strapi is the leading open-source headless CMS. It’s 100% JavaScript/TypeScript, fully customizable, and developer-first.项目地址: https://gitcode.com/GitHub_Trending/st/strapi

本篇基于 Strapi 仓库中create-strapi-appCLI 的 JS 示例模板(packages/cli/create-strapi-app/templates/example-js)及其自带的 README.md 展开。该文档是脚手架生成的 Strapi 应用根目录下的"上手指南",核心讲developstartbuild三个常用命令与strapi deploy部署流程。读完本文,你将不仅知道如何启动一个 Strapi 示例项目,还能深入理解模板的脚本映射、环境变量驱动的数据库/服务配置,以及种子脚本seed.js的首次运行检测与内容导入机制。

模板定位:create-strapi-app的 JS 示例工程

create-strapi-app是 Strapi 官方脚手架包,package.json 中声明其职责为 "Generate a new Strapi application.",当前仓库内版本为5.52.2,要求 Node.js>=20.0.0 <=26.x.x。该包通过files字段把templates/目录一并发布,仓库中提供了四套模板:

  • packages/cli/create-strapi-app/templates/vanilla/vanilla-js:空白项目;
  • packages/cli/create-strapi-app/templates/example/example-js:预置文章、作者、分类等内容模型与种子数据的示例项目。

example-js是面向 JavaScript 开发者的示例工程,其根目录结构(以仓库实际内容为准)为:

example-js/ ├── config/ # admin.js、api.js、database.js、middlewares.js、plugins.js、server.js ├── data/ # data.json 种子数据 + uploads/ 示例媒体文件 ├── database/ # migrations/ 数据库迁移目录 ├── public/uploads/ # 运行时上传目录 ├── scripts/seed.js # 种子脚本 ├── src/ # admin/、api/、components/、extensions/、index.js ├── jsconfig.json ├── package.json └── README.md # 即本篇的关联文档

其中src/api/下内置了aboutarticleauthorcategoryglobal五个内容类型(各自包含content-typescontrollersroutesservices四层文件),src/components/shared/下则提供了mediaquoterich-textseoslider五个可复用组件。这套模型让示例项目开箱即是一个可浏览的博客内容站,也决定了种子脚本需要导入哪些数据。

develop:开发模式启动(autoReload 开启)

模板 README 的第一个命令是develop,用于以开启 autoReload的方式启动应用,适合本地开发时热重载配置与代码变更:

npm run develop # or yarn develop

对照 package.json,这条 npm script 的真实映射是:

{ "scripts": { "build": "strapi build", "deploy": "strapi deploy", "develop": "strapi develop", "dev": "strapi develop", "console": "strapi console", "start": "strapi start", "strapi": "strapi", "upgrade": "npx @strapi/upgrade latest", "upgrade:dry": "npx @strapi/upgrade latest --dry", "seed:example": "node ./scripts/seed.js" } }

npm run develop最终执行的是 Strapi 内置 CLI 的strapi develop子命令。注意这里同时保留了dev别名,两条命令等价。

start:生产模式启动(autoReload 关闭)

第二个命令是start,以关闭 autoReload的方式启动应用,对应生产环境运行场景:

npm run start # or yarn start

映射关系同样是strapi startdevelopstart的区别仅在是否开启自动重载:前者监听文件变化并自动重启,便于开发迭代;后者以固定加载态运行,行为可预期,适合作为部署后的常驻进程。从模板脚本结构看,二者共用同一份config/src/,差异只体现在 CLI 层的运行策略上。

build:构建管理后台(admin panel)

第三个命令用于构建后台管理面板的静态资源:

npm run build # or yarn build

映射为strapi build。Strapi 的 admin 端是基于前端工程打包的 SPA,构建产物随应用一起分发;example-jssrc/admin/目录中带有app.example.jsvite.config.example.js两个示例文件,作为管理员面板定制(插件注册、Vite 配置扩展)的起点,默认处于.example示例态、不参与运行。

模板中的其他实用脚本

除 README 重点介绍的三个命令外,package.json 还预置了若干工程化脚本,实际使用示例项目时值得关注:

脚本实际命令用途
npm run consolestrapi console打开 Strapi 交互式控制台,直接调用strapi运行时 API
npm run seed:examplenode ./scripts/seed.js导入模板种子数据(内容 + 媒体)
npm run upgradenpx @strapi/upgrade latest执行 Strapi 升级流程
npm run upgrade:drynpx @strapi/upgrade latest --dry以 dry-run 模式预演升级,不落盘
npm run deploystrapi deploy执行部署(见下文)
npm run strapi ...strapi ...透传任意 Strapi CLI 子命令

配置层:环境变量驱动的服务与数据库

develop/start启动时加载的核心配置都在 config/ 目录。

服务配置 server.js

server.js 决定 API 服务监听行为:

module.exports = ({ env }) => ({ host: env('HOST', '0.0.0.0'), port: env.int('PORT', 1337), app: { keys: env.array('APP_KEYS'), }, webhooks: { populateRelations: env.bool('WEBHOOKS_POPULATE_RELATIONS', false), }, });
  • 默认监听0.0.0.0:1337,Strapi 的 1337 端口由此而来,可用HOST/PORT环境变量覆盖;
  • APP_KEYS是逗号分隔的签名密钥数组,用于 API Token 等签名场景;
  • WEBHOOKS_POPULATE_RELATIONS控制 Webhook 载荷是否展开关系字段,默认false

管理端配置 admin.js

admin.js 集中了后台安全相关的密钥,全部来自环境变量:

  • ADMIN_JWT_SECRET:管理员会话 JWT 签名密钥;
  • API_TOKEN_SALT:API Token 派生盐值;
  • TRANSFER_TOKEN_SALT:数据迁移/传输令牌盐值;
  • ENCRYPTION_KEY:管理端敏感信息加密密钥;
  • flags下的npspromoteEEdocLinks三个布尔开关控制后台内的调研问卷、EE 推广与文档链接展示,均可通过FLAG_NPSFLAG_PROMOTE_EEFLAG_DOC_LINKS关闭。

数据库配置 database.js

database.js 展示了模板对多数据库的完整支持,支持sqlite(默认)、mysqlpostgres三种DATABASE_CLIENT,并带有校验逻辑:

const client = env('DATABASE_CLIENT', 'sqlite'); if (!isDatabaseClientKind(client)) { throw new Error( `Unsupported DATABASE_CLIENT: ${client}. Use "postgres", "mysql", or "sqlite".` ); }

三种连接的要点:

  • sqlite(默认):文件型数据库,默认落在项目相对路径.tmp/data.dbpath.join(__dirname, '..', env('DATABASE_FILENAME', '.tmp/data.db'))),useNullAsDefault: true
  • mysql:默认localhost:3306,库名strapi,用户/密码strapi,连接池min=2, max=10DATABASE_POOL_MIN/DATABASE_POOL_MAX),支持DATABASE_SSL及其 key/cert/ca 等证书项;
  • postgres:默认localhost:5432,支持DATABASE_URL连接串与DATABASE_SCHEMA(默认public),SSL 配置项与 mysql 一致。

所有连接还会应用DATABASE_CONNECTION_TIMEOUT(默认60000ms)作为获取连接的超时时间。这意味着本地零配置即可运行(sqlite 落盘.tmp/),而在托管数据库环境下只需要注入DATABASE_CLIENT与相应连接变量。

种子数据脚本 seed.js 深度解析

npm run seed:example执行的 scripts/seed.js 是模板最有技术含量的部分,完整演示了"如何在 Strapi 运行时之外以编程方式创建内容"。其关键机制如下:

1. 首次运行检测(plugin store 标记位)

async function isFirstRun() { const pluginStore = strapi.store({ environment: strapi.config.environment, type: 'type', name: 'setup', }); const initHasRun = await pluginStore.get({ key: 'initHasRun' }); await pluginStore.set({ key: 'initHasRun', value: true }); return !initHasRun; }

通过 Strapi 的 plugin store 写入initHasRun标记,第二次运行时直接提示 "Seed data has already been imported"。从源码结构看,这是一个幂等性保护:重复导入会因唯一约束或重复内容失败,因此除非清空数据库,否则不做二次导入。

2. 打开 public 角色读取权限

setPublicPermissions会查找plugin::users-permissions.roletype: 'public'的角色,然后为articlecategoryauthorglobalabout五个控制器批量创建find/findOne权限:

action: `api::${controller}.${controller}.${action}`,

这解释了为什么示例项目在启动后无需任何后台操作,前端就能匿名GET /api/articles等接口——种子脚本替 public 角色完成了授权。

3. 媒体上传去重与 blocks 回填

  • uploadFile调用strapi.plugin('upload').service('upload'),即 upload 插件的上传服务,逐文件生成fileInfo(替代文本、标题、名称);
  • checkFileExistsBeforeUpload先按文件名(去掉扩展名)查询plugin::upload.file,已存在则复用,不存在才从data/uploads/读文件上传,并用mime-types推断 MIME;
  • updateBlocks遍历动态区(dynamic zone)的 blocks:对shared.media块回填单文件、对shared.slider块回填文件数组,其余块原样保留。

这套"先查库、后上传、按__component回填"的写法,正是 Strapi 动态区 + 组件模型(对应 src/components/shared/ 下的media.jsonslider.json等 schema)在种子脚本中的标准消费姿势。

4. 导入顺序与发布态

importSeedData的执行顺序为:授权 →categoriesauthors(先传头像再建作者)→articles(封面 + blocks 处理)→global(favicon 与默认分享图)→about。每个入口条目都显式设置publishedAt: Date.now(),确保导入的是已发布而非草稿态,API 立即可见。

5. 独立进程启动运行时

脚本末尾main函数展示了脱离 Web 服务、仅加载 Strapi 运行时的标准方式:

const { createStrapi, compileStrapi } = require('@strapi/strapi'); const appContext = await compileStrapi(); const app = await createStrapi(appContext).load(); // ... 执行 seed ... await app.destroy();

compileStrapi()编译上下文 →createStrapi().load()加载应用 → 执行种子逻辑 →destroy()释放。这一模式同样适用于编写一次性数据迁移脚本。

部署:strapi deploy与部署选项

模板 README 的部署章节指出 Strapi 支持多种部署方案,并给出核心命令:

yarn strapi deploy

对照 package.json,该命令对应"deploy": "strapi deploy"脚本(yarn strapi deploy则是通过"strapi": "strapi"脚本透传子命令,两者等价)。部署前通常需要先执行npm run build产出管理后台静态资源;在数据库层面则按上文DATABASE_CLIENT环境变量接入目标数据库,并注入ADMIN_JWT_SECRETAPI_TOKEN_SALTAPP_KEYS等安全变量。仓库的 examples/ 目录与 docker-compose.dev.yml 等文件也提供了开发/测试环境组合的参考。

小结

example-js模板 README 虽短,但它给出的develop/start/build/deploy四条命令覆盖了 Strapi 应用从开发到上线的完整生命周期;而围绕这份 README,模板工程内的 package.json 脚本映射、config/ 下环境变量驱动的服务与数据库配置、以及 scripts/seed.js 的运行时编程式导入,共同构成了一套可直接复制的 JS 版 Strapi 工程基线。以它为起点,替换src/api/中的内容类型、调整config/database.js的目标数据库,即可得到属于自己的 Strapi 应用骨架。

【免费下载链接】strapi🚀 Strapi is the leading open-source headless CMS. It’s 100% JavaScript/TypeScript, fully customizable, and developer-first.项目地址: https://gitcode.com/GitHub_Trending/st/strapi

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/7 17:23:40

DMA工作原理与实战:从数据搬运到串口接收、ADC采样

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/7 17:22:54

OSS PDF下载到指定文件夹:从原理到批量落地的完整方案

平时处理OSS里的PDF文件&#xff0c;最头疼的往往不是上传&#xff0c;反而是下载。尤其当你想把某个PDF直接落到本地指定文件夹&#xff0c;而不是让浏览器随手丢进“下载”目录时&#xff0c;各种小问题就冒出来了&#xff1a;文件名乱码、下载一半失败、明明有权限却报403、…

作者头像 李华
网站建设 2026/9/7 17:21:00

Java工程师必备:9个提升开发效率的工具库

做了这么多年Java开发&#xff0c;我一直有个观点&#xff1a;真正拉开开发效率差距的&#xff0c;往往不是语言本身&#xff0c;而是你手里工具库的熟练度。同一个CRUD接口&#xff0c;有人能在一个小时内搞定&#xff0c;有人要磨蹭一整天&#xff0c;区别就在这。今天把我一…

作者头像 李华
网站建设 2026/9/7 17:20:40

Git命令找不到?三平台PATH环境变量配置与排查完整指南

你是不是也遇到过这种情况&#xff1a;明明刚装完Git&#xff0c;打开终端敲 git --version &#xff0c;结果屏幕冷冷地回一句 git: command not found &#xff0c;Windows 上是 git 不是内部或外部命令 。这不是Git没装上&#xff0c;多数时候是PATH环境变量没配好。今…

作者头像 李华
网站建设 2026/9/7 17:19:31

全国景区数据分析与可视化:Python完整项目实战解析

在CSDN或者GitHub上搜“景区数据分析”这个关键词&#xff0c;能翻出几百个类似的项目&#xff0c;但绝大多数都停留在“爬了数据→画几张图→完事”的阶段。今天想聊的这套基于Python的全国景区数据分析与可视化实现&#xff0c;不是那种只跑通demo的作业级代码。它是一套带完…

作者头像 李华
网站建设 2026/9/7 17:19:16

AI辅助FPGA开发:用豆包破解Vivado时序与约束调试难题

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华