Webiny全栈无头CMS与云原生应用开发实战指南
1. 项目概述:一个面向未来的无头CMS与应用程序框架
如果你正在寻找一个既能管理内容,又能构建复杂应用的“一体化”解决方案,那么webiny/webiny-js绝对值得你花时间深入研究。这不是一个简单的博客系统,也不是一个纯粹的API服务。它是一个基于Node.js和React构建的、开源的、无头内容管理系统(Headless CMS)和应用程序框架,并且原生部署在AWS云上。简单来说,它试图解决一个核心矛盾:当你的业务需要同时具备灵活的内容管理和强大的自定义应用能力时,传统的单体CMS或独立的BFF(Backend For Frontend)架构往往显得笨重或割裂。Webiny 的野心是提供一个“全栈”平台,让你在一个统一的体系下,既能通过可视化界面管理文章、页面、表单,又能像开发普通React应用一样,构建带有复杂业务逻辑的管理界面或用户端应用。
我第一次接触 Webiny 是在为一个中型电商项目做技术选型时。客户的需求很典型:需要一个由市场团队自主更新的商品详情页和营销页面(CMS功能),同时又要有一个高度定制化的订单管理和数据分析后台(应用功能)。当时评估了 WordPress + 自定义插件、Strapi + 单独开发后台等多种方案,要么是CMS太重、开发不自由,要么是前后端分离带来的部署和运维复杂度激增。Webiny 的出现,提供了一种新的思路——它将 CMS 的核心能力(内容建模、权限、媒体库)作为底层服务提供,同时允许开发者在其之上用熟悉的 React 技术栈自由构建应用模块,所有东西都通过一套统一的GraphQL API通信,并一键部署到云端。这听起来像是“既要又要还要”,但 Webiny 通过其独特的架构设计,在一定程度上实现了这个目标。
对于开发者而言,Webiny 降低了从零搭建一个企业级、云原生应用的门槛。它内置了用户管理、文件管理、审计日志、多租户等基础设施,你只需要关注业务逻辑本身。对于团队负责人或创业者,它意味着更快的产品上市时间和更可控的长期技术债务。当然,它也不是银弹,其强绑定AWS和相对复杂的概念体系,意味着有一定的学习曲线。接下来,我将深入拆解这个项目的核心设计、实操细节以及我趟过的一些坑,希望能帮你判断它是否是你的“菜”。
2. 核心架构与设计哲学拆解
要理解 Webiny 能做什么以及如何做,必须先从它的架构入手。它的设计哲学非常明确:“Everything is a Plugin”(一切皆插件)和“Serverless First”(无服务器优先)。这两个原则贯穿了整个系统,决定了开发者的使用体验和系统的扩展能力。
2.1 一切皆插件:高度可扩展的模块化体系
Webiny 的核心不是一个庞大的单体应用,而是一个由众多插件组装起来的生态系统。从内容模型定义、页面构建器组件,到一个简单的设置菜单项,都是通过插件系统注册和管理的。这种设计带来了极大的灵活性。
插件类型与作用域:Webiny 的插件主要分为两大类:API插件和Admin插件。
- API 插件:运行在
Lambda函数(无服务器环境)中,负责定义GraphQL模式(Schema)、解析器(Resolvers)、数据模型以及后端业务逻辑。当你创建一个新的内容模型或自定义GraphQL查询时,你实际上是在编写一个 API 插件。 - Admin 插件:运行在浏览器中,是基于
React的管理界面扩展。它用于在 Webiny 管理后台(Admin App)中添加新的页面、菜单、设置项或可视化组件。你构建的每一个自定义管理功能,都是一个 Admin 插件。
这种前后端分离的插件架构,使得功能模块可以独立开发、测试和部署。例如,你可以为一个“客户反馈”模块编写一个 API 插件来处理数据的存储和查询,同时编写一个 Admin 插件来提供一个表格界面供客服人员查看反馈。这两个插件通过共享的GraphQL类型定义进行通信,但开发和生命周期可以相对独立。
为什么选择插件化?从实践角度看,这解决了传统 CMS 功能扩展时的“侵入性”问题。在 WordPress 中,虽然也有插件机制,但很多深度定制需要直接修改主题文件或核心代码,升级时容易产生冲突。Webiny 的插件化要求所有扩展都必须通过规定的API进行,这虽然初期增加了些许样板代码的负担,但长期来看,维护性和清晰度更高。你的业务代码和核心代码是解耦的。
2.2 无服务器优先:拥抱云原生与按需付费
Webiny 是少数几个从一开始就为无服务器架构设计的全栈框架之一。它深度集成AWS服务,如Lambda、API Gateway、DynamoDB、S3、CloudFront等。当你运行webiny deploy命令时,它背后的Pulumi(一个基础设施即代码工具)会帮你创建和配置所有这些云资源。
这种选择带来的核心优势:
- 极低的运维成本:你不需要管理服务器。
Lambda函数只在被请求时执行,按调用次数和计算时间付费。对于中小型项目或访问量波动大的项目,成本可能远低于维持一台24小时运行的EC2实例。 - 天生的高可用与可扩展性:
AWS的这些托管服务本身就具备高可用和自动扩展的能力。理论上,你的应用可以轻松应对流量洪峰。 - 开发与生产环境的一致性:Webiny CLI 工具可以一键部署整个应用到云端,也可以在你的本地模拟出类似云端的开发环境(通过
webiny watch命令),减少了“在我机器上是好的”这类问题。
当然,这也意味着妥协和挑战:
- 供应商锁定:你被牢牢绑定在
AWS生态中。虽然理论上可以移植,但工作量巨大。选择 Webiny 就等于选择了AWS。 - 冷启动延迟:
Lambda函数在闲置一段时间后再次被调用时,会有一个初始化过程(冷启动),可能导致首次请求响应变慢。Webiny 通过一些优化(如GraphQL接口合并)来缓解,但对于实时性要求极高的交互,仍需注意。 - 调试复杂性:调试运行在远端
Lambda中的代码,比调试本地Node.js服务要麻烦一些,需要更依赖日志(CloudWatch)和结构化错误信息。
2.3 三层应用结构:清晰的职责分离
Webiny 将一个完整的项目结构清晰地分为三层,这有助于团队协作和代码组织:
- API (
/api):这是后端核心,包含所有的GraphQLAPI 定义和业务逻辑。它又细分为多个服务,如Page Builder、File Manager、Form Builder以及你自定义的API。每个服务最终都会部署为独立的Lambda函数。 - Admin (
/admin): 这是一个React单页应用(SPA),是内容管理员和运营人员使用的管理后台。它通过GraphQL与API层通信。你开发的 Admin 插件就放在这里。 - Website (
/website):这也是一个React应用,是面向公众的网站前端。它同样通过GraphQL获取由Page Builder等API服务渲染好的内容。你可以完全定制这个前端的样式和交互,它相当于一个“无头”的消费者。
这种结构强迫开发者进行关注点分离。API开发者专注于数据和安全,Admin开发者专注于管理体验,Website开发者专注于终端用户界面。三者通过GraphQL这个强类型契约连接,并行开发效率很高。
3. 核心功能模块深度解析
Webiny 不是一个空架子,它自带了一系列开箱即用、功能强大的核心模块。理解这些模块,是高效利用它的基础。
3.1 Page Builder:可视化页面创作引擎
这是 Webiny 的招牌功能,一个React驱动的、块编辑器风格的可视化页面构建器。它允许非技术人员通过拖拽预定义的“元素”(如文本、图片、按钮、视频、Grid布局等)来创建和编辑页面。
核心概念与实操:
- 元素(Elements):页面的基础构建块。每个元素都是一个
React组件,并配有一套属性(Settings)表单。例如,Paragraph元素有一个用于输入文本内容的Rich Text Editor设置项。开发者的主要扩展点之一就是创建自定义元素。你需要创建一个Admin插件来注册这个元素,定义它在编辑器工具栏中的图标和设置表单,同时还需要在Website层编写该元素最终渲染的React组件。 - 页面与模板:创建的页面可以保存为模板,方便复用。页面数据(元素树及其配置)以
JSON格式存储在DynamoDB中。当Website前端请求页面时,Page Builder API会获取这份JSON,并将其“转换”为一组React组件props,传递给Website层进行渲染。这个过程是动态的,意味着你无需重新部署网站就能更新页面内容。 - SEO 与设置:每个页面都可以独立设置
SEO标题、描述、Open Graph图片等,这对于内容营销至关重要。
注意:Page Builder 生成的页面是动态渲染的,这对
SEO可能是个挑战。虽然现代搜索引擎能抓取JavaScript渲染的内容,但为了最佳实践,Webiny 推荐并支持为关键页面(如首页)配置静态化输出或使用SSR(服务器端渲染),但这需要额外的Lambda@Edge配置,复杂度会上升。
3.2 Headless CMS:灵活的内容建模
除了可视化建站,Webiny 也提供了传统的无头CMS功能。你可以通过管理界面创建“内容模型”,定义字段(文本、数字、富文本、引用、文件等),然后基于这些模型创建内容条目。
与 Page Builder 的关系:这是两个互补的内容管理维度。Page Builder 管理的是“页面”的布局和视觉内容,而Headless CMS管理的是结构化的“数据”。例如,你可以用Headless CMS创建一个“产品”模型,包含名称、价格、描述、规格等字段。然后,在 Page Builder 中创建一个产品详情页,并拖入一个“动态内容”元素,将其绑定到“产品”模型。这样,页面布局是固定的,但具体显示哪个产品的数据,则由页面URL参数或上下文决定。这种结合提供了极大的灵活性。
内容交付:所有通过Headless CMS创建的内容,都通过统一的GraphQL API暴露。前端应用(无论是Website层还是移动端)都可以通过GraphQL查询精确获取所需的数据,避免了REST API的过度获取或欠获取问题。
3.3 文件管理与表单构建
这两个是提升运营效率的利器。
- File Manager:提供了一个完整的
S3前端管理器。支持上传、裁剪、分类、搜索图片和文档,并自动生成CDN链接。在Page Builder或Headless CMS中引用图片时,可以直接从文件库中选择,非常方便。 - Form Builder:允许非开发者在后台创建表单(如联系表单、调查问卷)。可以定义字段、验证规则,并设置表单提交后的行为(如发送邮件到指定邮箱、将数据存储为
CMS条目等)。这省去了为每一个简单表单都去开发前后端的麻烦。
3.4 多租户与细粒度权限控制
对于构建SaaS平台或内部多团队使用的系统,多租户是刚需。Webiny 原生支持多租户架构,数据在存储层通过租户ID进行逻辑隔离。你可以在一个Webiny实例中创建多个“租户”,每个租户拥有完全独立的内容、页面、用户和权限体系。
权限控制基于RBAC(角色基于访问控制),非常精细。你可以创建角色(如“编辑”、“审核员”、“管理员”),并为角色分配精确到具体操作(CRUD)的权限,例如“可以创建文章,但不能发布”。这套权限系统贯穿所有核心模块,是构建企业级应用的安全基石。
4. 从零开始:开发与部署实战指南
理论讲得再多,不如动手一试。下面我将以一个常见的需求——“构建一个内部团队知识库”——为例,带你走一遍 Webiny 的核心开发流程。这个知识库需要:1. 一个由运营人员通过可视化编辑器维护的首页;2. 一个结构化的“文章”内容模型,用于存储技术文档;3. 一个自定义的“文章分类”管理界面。
4.1 环境初始化与项目创建
首先,确保你有一个AWS账户并配置好CLI凭证(aws configure)。然后全局安装 Webiny CLI:
npm install -g @webiny/cli使用 CLI 创建新项目:
webiny create my-knowledge-base --template=cms这里我们选择cms模板,它包含了Page Builder和Headless CMS等核心模块。创建过程会询问一些配置,如AWS区域、是否部署GraphQL API到云端等。对于首次体验,我建议先选择在本地开发,暂时不部署。
项目创建后,目录结构如下:
my-knowledge-base/ ├── api/ # 后端 GraphQL API 和服务 ├── apps/ │ ├── admin/ # 管理后台 React 应用 │ └── website/ # 公开网站 React 应用 ├── packages/ # 可复用的业务逻辑包 └── webiny.config.ts # 项目主配置进入项目根目录,安装依赖(这个过程可能比较长,因为它需要安装整个Monorepo的依赖):
cd my-knowledge-base yarn4.2 本地开发环境启动
Webiny 使用一个巧妙的“观察”(watch)模式来启动本地开发环境。它会启动本地API服务器(模拟Lambda环境)和两个React开发服务器(admin和website)。
yarn webiny watch首次运行会进行大量编译。完成后,控制台会输出访问地址,通常是:
- 管理后台:
http://localhost:3001 - 网站前台:
http://localhost:3000 - GraphQL Playground:
http://localhost:3001/graphql(用于测试 API)
使用默认的超级管理员账户(创建项目时设置的邮箱和密码)登录管理后台。至此,一个功能完整的本地 Webiny 环境就运行起来了。
4.3 创建内容模型与自定义 GraphQL API
我们的知识库需要“文章”模型。在管理后台的Headless CMS->Models中,可以图形化创建。但作为开发者,我们更推荐代码驱动的方式,以便版本控制。
- 定义内容模型:在
/api/code/graphql/src下创建文件article.gql.ts。这里我们使用GraphQL SDL和代码插件来定义。
// api/code/graphql/src/article.gql.ts import { GraphQLSchemaPlugin } from "@webiny/handler-graphql/types"; // 定义 GraphQL 类型 const typeDefs = ` type Article @model { id: ID! title: String! @title content: RichText! @richText category: RefField! @refField(model: "Category") tags: [String]! createdAt: DateTime! updatedAt: DateTime! } input ArticleInput { title: String! content: JSON! category: ID! tags: [String]! } type ArticleQuery { # 这里会自动生成 getArticle, listArticles 等查询 } type ArticleMutation { # 这里会自动生成 createArticle, updateArticle, deleteArticle 等变更 } extend type Query { articles: ArticleQuery } extend type Mutation { articles: ArticleMutation } `; // 创建插件来注册这个 Schema const plugin: GraphQLSchemaPlugin = { type: "graphql-schema", schema: { typeDefs } }; export default plugin;- 注册插件:在
/api/code/graphql/src/plugins.ts中导入并注册这个插件。
import articleSchema from "./article.gql"; // ... 其他导入 export default [ // ... 其他插件 articleSchema ];- 创建关联模型(分类):同样方式,创建一个
Category模型,包含name和slug字段。
实操心得:Webiny 的
@model、@title等指令是其CRUD自动生成系统的核心。它们会自动为模型创建对应的DynamoDB表、GraphQL CRUD解析器以及管理界面中的表单字段。这极大地提升了开发效率,但也要注意,对于特别复杂的业务逻辑,你可能需要覆盖自动生成的解析器。
4.4 构建自定义管理界面(Admin 插件)
现在我们需要在管理后台为“文章”和“分类”提供一个管理界面。这需要创建Admin插件。
- 生成插件脚手架:Webiny CLI 提供了便捷的生成器。
cd apps/admin yarn webiny generate plugin --type entity-management --name Article这会在apps/admin/src/plugins/entityManagement/article下生成一系列文件,包括路由、菜单、列表视图和编辑表单的组件。
自定义列表和表单:打开生成的文件,例如
ArticleList.tsx,你可以修改Table组件显示的列,绑定到我们之前定义的Article模型的字段(如title,category.name,createdOn)。在ArticleForm.tsx中,你可以使用 Webiny 提供的UI组件(如Input,RichTextEditor,Select)来构建创建/编辑表单,并绑定到GraphQL变更操作。关联分类选择器:在文章表单中,
category字段是一个引用。我们需要一个下拉选择器来关联Category模型。可以使用useQuery钩子获取所有分类列表,然后填充到Select组件中。
// 示例代码片段 import { useQuery } from "@apollo/react-hooks"; import gql from "graphql-tag"; const LIST_CATEGORIES = gql` query ListCategories { listCategories { data { id name } } } `; function ArticleForm() { const { data } = useQuery(LIST_CATEGORIES); const categories = data?.listCategories?.data || []; return ( <Grid> <Cell span={12}> <Input name="title" label="Title" /> </Cell> <Cell span={12}> <Select name="category" label="Category" options={categories.map(cat => ({ id: cat.id, name: cat.name }))} /> </Cell> {/* ... 其他字段 */} </Grid> ); }- 注册菜单和路由:生成器已经帮我们在插件的
index.ts中注册了菜单和路由。你只需要调整菜单的标签和位置即可。运行yarn webiny watch,刷新管理后台,你应该能看到新的“文章”菜单项。
4.5 在 Page Builder 中集成动态内容
我们希望知识库的首页(用 Page Builder 制作)能展示最新的文章列表。
- 创建页面元素:我们需要创建一个自定义的“文章列表”元素。在
/apps/admin/src/plugins/pageBuilder/elements下创建一个新的插件目录,例如articlesList。 - 定义元素设置:创建一个
Settings.tsx组件,定义元素在编辑器中可配置的选项,例如“显示文章数量”、“是否显示分类筛选”。 - 定义渲染组件:在
/apps/website/src下创建对应的React组件ArticlesList.tsx。这个组件将在网站前端渲染。它需要接收来自Page Builder的设置props,并使用GraphQL查询获取文章列表数据并渲染。 - 注册元素:在
Admin插件中,使用pageBuilder.registerElement方法将这个新元素注册到编辑器工具栏中。
这样,运营人员就可以在编辑首页时,直接从工具栏拖拽“文章列表”元素到页面上,并通过设置面板调整其显示方式。前端渲染时,该元素会动态去API拉取最新的文章数据。
4.6 部署到 AWS
当开发测试完成后,就可以部署到生产环境了。Webiny 的部署命令非常简洁:
yarn webiny deployCLI 会引导你选择部署的环境(如dev,prod),然后开始打包代码、通过Pulumi创建或更新AWS资源栈。这个过程可能需要20-30分钟,因为它要处理API Gateway、Lambda、CloudFront分发等多个资源。
部署成功后,CLI 会输出管理后台和网站前端的CloudFront域名。你需要为这些域名配置自定义域名和SSL证书(通常在AWS Certificate Manager中申请),以提供专业的访问体验。
5. 常见问题、性能优化与避坑指南
在实际使用 Webiny 构建项目的过程中,我遇到并总结了一些典型问题和优化点。
5.1 开发环境与调试
问题:
webiny watch启动慢或内存占用高。- 原因:项目是
Monorepo,首次启动需要编译大量包。Lambda本地模拟环境也有开销。 - 解决:确保机器内存充足(建议16G以上)。可以使用
yarn webiny watch api只启动API层,或者yarn webiny watch admin只启动管理后台,进行针对性开发。利用好.env文件和环境变量,避免每次全量构建。
- 原因:项目是
问题:如何调试
Lambda函数中的代码?- 解决:本地开发时,
console.log会输出到webiny watch的控制台。生产环境,务必在Lambda函数中集成结构化日志(如使用@webiny/handler内置的日志工具),并到AWS CloudWatch中查看日志流。对于复杂问题,可以配置Lambda将日志发送到外部可观测性平台。
- 解决:本地开发时,
5.2 数据建模与 GraphQL
问题:
DynamoDB单表设计 vs 多表设计?- 背景:Webiny 默认使用单表设计,所有实体(如页面、
CMS条目)都存储在一张主表中,通过PK(分区键)和SK(排序键)来区分。这是DynamoDB的最佳实践之一,能实现高效的多实体查询。 - 建议:除非有非常特殊的性能或数据隔离需求,否则遵循 Webiny 的单表设计。不要轻易尝试改为多表,这会破坏很多内置的查询和工具。理解其
PK/SK的命名模式(如T#root#L#en-US#ARTICLE#<id>)对于编写高级GraphQL查询过滤器很有帮助。
- 背景:Webiny 默认使用单表设计,所有实体(如页面、
问题:复杂的
GraphQL查询性能不佳。- 排查:首先在
GraphQL Playground中检查查询的耗时。使用AWS X-Ray对Lambda和DynamoDB调用进行跟踪。 - 优化:
- 避免深度嵌套和循环查询:
GraphQL的灵活性可能导致N+1查询问题。确保在GraphQL解析器中合理使用数据加载器(DataLoader)来批量获取关联数据。Webiny 在某些内置字段上已经做了优化。 - 善用筛选和分页:在
listArticles等查询中,一定要使用limit和after(用于分页)参数,避免一次性拉取过多数据。利用where条件进行精确筛选。 - 考虑
DynamoDB索引:对于高频的查询模式(如“按分类和发布时间倒序列出文章”),你可能需要在内容模型定义中,通过@index指令添加全局二级索引(GSI)。
- 避免深度嵌套和循环查询:
- 排查:首先在
5.3 前端性能与 SEO
问题:Page Builder 页面加载速度慢,特别是首屏。
- 分析:页面内容是以
JSON形式存储的,前端需要先获取JSON,再递归渲染组件树。如果页面元素非常多,JSON体积大,且组件依赖的JavaScript包未优化,就会导致加载慢。 - 优化:
- 代码分割:确保
Website和Admin的React应用配置了代码分割(React.lazy+Suspense)。Webiny 的create-react-app模板默认支持。 - 图片优化:使用
File Manager上传图片时,利用其内置的图片处理功能(通过sharp)生成WebP等现代格式,并在Page Builder图片元素中指定响应式尺寸。 - 静态化/SSR:对于极少变化的首页等关键页面,可以考虑使用
webiny export命令将其预渲染为静态HTML,并部署到S3+CloudFront。对于需要个性化但又要SEO的页面,可以研究使用Lambda@Edge实现SSR,但这属于高级主题,配置复杂。
- 代码分割:确保
- 分析:页面内容是以
问题:如何更好地管理前端状态?
- 建议:对于
Website应用,简单的状态可以用React Context或useState/useReducer。对于复杂的状态(如用户会话、购物车),推荐使用Apollo Client的缓存管理能力,或者集成像Zustand、Jotai这样轻量的状态库。避免在Page Builder元素组件中滥用全局状态,因为它们可能被频繁挂载和卸载。
- 建议:对于
5.4 部署与运维
问题:
Lambda冷启动导致API响应慢。- 缓解措施:
- 保持
Lambda温暖:对于关键API(如GraphQL),可以设置一个CloudWatch Events定时规则,每隔几分钟调用一次ping接口,使函数保持活跃状态。注意这会增加少量费用。 - 优化包体积:精简
Lambda函数代码依赖。使用Webpack或esbuild进行tree-shaking。Webiny 的构建流程已经做了很多优化。 - 使用
Provisioned Concurrency:为关键的、延迟敏感的Lambda函数配置预置并发。这能彻底消除冷启动,但费用固定,需根据业务量权衡。
- 保持
- 缓解措施:
问题:如何管理多环境(开发、测试、生产)?
- 最佳实践:Webiny 项目根目录的
webiny.config.ts和webiny.project.ts文件支持环境变量注入。为每个环境(dev,staging,prod)创建不同的AWS配置文件和Pulumi栈。通过环境变量区分数据库表前缀、S3桶名等资源。绝对不要在不同环境间共享关键资源(如DynamoDB表)。
- 最佳实践:Webiny 项目根目录的
问题:项目升级(Webiny 版本升级)需要注意什么?
- 警告:Webiny 更新活跃,但大版本升级(如
5.x到6.x)可能包含破坏性变更。务必:- 在非生产环境首先测试升级。
- 仔细阅读官方发布的升级指南和变更日志。
- 备份数据库(特别是
DynamoDB表)。虽然 Webiny 的Pulumi部署通常不直接操作已有数据,但升级过程中的数据迁移脚本可能有风险。 - 检查你自定义的插件和代码,是否调用了已废弃的
API。
- 警告:Webiny 更新活跃,但大版本升级(如
5.5 安全与权限
问题:如何实现基于自定义字段的细粒度权限?
- 场景:除了默认的
CRUD权限,你可能需要“用户只能编辑自己创建的文章”。 - 实现:Webiny 的权限系统可以扩展。你可以在自定义的
GraphQL解析器前添加一个安全层。在解析器内部,先检查用户的角色/组,再结合查询条件(如createdBy: { eq: currentUser.id })来过滤数据。这通常需要覆盖自动生成的list和get解析器,实现自定义的数据访问逻辑。
- 场景:除了默认的
问题:如何防护
GraphQL API不被滥用?- 措施:
- 深度和复杂度限制:在
API Gateway或GraphQL服务器层(如使用graphql-depth-limit,graphql-cost-analysis中间件)设置查询深度和复杂度限制,防止恶意超复杂查询拖垮后端。 - 请求限流:在
API Gateway阶段配置使用计划(Usage Plans)和API密钥,或结合AWS WAF进行更复杂的限流和防护。 - 审计日志:确保开启
CloudTrail和Lambda/API Gateway的访问日志,记录所有API调用,便于事后审计和排查。
- 深度和复杂度限制:在
- 措施:
Webiny 是一个功能强大但体系也相对复杂的平台。它不适合“五分钟快速建站”,而是为那些需要在云原生环境下,构建长期演进、功能丰富的定制化内容驱动型应用的团队准备的。它的优势在于,用一套统一的技术栈和架构,覆盖了从内容管理到复杂应用开发的广阔场景。如果你和你的团队熟悉React、Node.js和AWS,并且对无服务器架构持开放态度,那么投入时间学习 Webiny 可能会在未来为你节省大量的重复造轮子的时间。
