构建 AI Educademy 提出了一项独特的技术挑战:创建一个可供全世界学习者使用、易于维护且可扩展以服务数百万用户的平台,同时保持代码库整洁且对开发人员友好。
在本次深入探讨中,我们将详细介绍塑造我们平台的架构决策,从我们选择 Next.js 15 到我们如何使用 git 子模块管理多语言内容。无论您是要构建教育平台、文档网站还是任何内容丰富的应用程序,您都可以在这里找到实用的见解。
当我们开始构建 AI Educademy 时,Next.js 14 是标准。当我们发布时,Next.js 15 已经发布,对 App Router 进行了重大改进。我们之所以能够实现这一跨越,是因为有几个因素与我们的目标完美契合:
默认服务器组件:Next.js 15 App Router 默认使用服务器组件,这意味着我们可以直接在组件中获取数据,无需额外的 API 路由来进行简单操作。这降低了复杂性并提高了开箱即用的性能。
增量静态再生(ISR):教育内容不会不断变化,但它确实会变化。 ISR 允许我们在构建时预渲染页面,然后按计划重新验证它们。这意味着我们的博客文章、教程和课程材料始终是新鲜的,不会因按需渲染而影响性能。
内置优化:自动处理图像优化、字体加载和代码分割。我们不必花费周期来构建或配置这些功能 - 它们只是工作。
基于文件的路由:App Router 直观的文件结构使页面和 API 路由所在的位置一目了然。新的贡献者可以立即进入代码库并了解其结构。
// Our routing structure is intuitive and scalable
app/
├── [locale]/
│ ├── page.tsx
│ ├── programs/
│ │ ├── page.tsx
│ │ └── [slug]/
│ │ └── page.tsx
│ └── blog/
│ ├── page.tsx
│ └── [slug]/
│ └── page.tsx
├── api/
└── layout.tsx
AI Educademy 是为全球社区打造的。提供多种语言的内容不仅是可有可无,而且对于实现我们为所有人提供免费人工智能教育的使命至关重要。
我们选择 next-intl 因为它:
/en/programs 和 /es/programas)以下是我们构建 i18n 设置的方式:
// middleware.ts - Detects user locale and routes accordingly
import { createMiddleware } from 'next-intl/middleware';
export default createMiddleware({
locales: ['en', 'es', 'fr', 'de', 'zh'],
defaultLocale: 'en'
});
export const config = {
matcher: ['/((?!api|_next|.*\\..*).*)']
};
我们的翻译文件按区域设置和功能组织:
messages/
├── en/
│ ├── common.json
│ ├── programs.json
│ └── blog.json
├── es/
│ ├── common.json
│ └── ...
└── fr/
└── ...
这种方法可以很好地扩展。添加新语言意味着添加包含 JSON 文件的新文件夹 - 无需更改代码。
这就是事情变得有趣的地方。我们本来可以使用传统的无头 CMS,但我们选择了 MDX,因为它为我们提供了两全其美的功能:与我们的代码一起进行版本控制的内容管理,以及将交互式 React 组件直接嵌入到我们的教育内容中的能力。
当您阅读有关 AI Educademy 的博客文章或教程时,您不仅仅是在阅读静态 HTML。您可能正在与以下人员互动:
所有这一切都是可能的,因为我们使用 MDX。我们的内容作者可以用 Markdown 编写,但开发人员可以传入自定义组件:
---
title: "Understanding Neural Networks"
---
# Understanding Neural Networks
<ConceptExplainer concept="neural-networks" />
Neural networks are inspired by how our brains work...
<InteractiveQuiz questionId="nn-101" />
## Real-World Applications
<CodeExample language="python" title="Simple Neural Network" />
为了使 MDX 在 Next.js 15 中顺利工作,我们使用 @next/mdx 并在 next.config.js 中配置它:
// next.config.js
import createMDX from '@next/mdx';
const withMDX = createMDX({
options: {
remarkPlugins: [
// Our custom plugins for syntax highlighting, TOC generation, etc.
],
rehypePlugins: []
}
});
export default withMDX({
pageExtensions: ['ts', 'tsx', 'mdx']
});
这是一个聪明的架构决策:我们的内容位于单独的 git 存储库中,作为 git 子模块拉入主应用程序。
为什么?因为它可以:
我们的目录结构如下所示:
ai-educademy/
├── content/ (git submodule)
│ ├── blog/
│ │ ├── en/
│ │ ├── es/
│ │ └── fr/
│ ├── programs/
│ │ └── [course content]
│ └── lab/
│ └── [interactive exercises]
├── app/
├── package.json
└── .gitmodules
当我们需要更新内容时,我们:
# Pull latest content
git submodule update --remote
# Or content authors can PR directly to the content repo
这种解耦改变了我们的速度。内容可以在不触发应用程序重建的情况下进行更新(感谢 ISR),并且非工程师也可以添加新程序。
教育可以在所有设备上进行,包括低带宽环境。我们将 AI Educademy 打造为 PWA,以便学习者能够:
// next.config.js includes PWA configuration
import withPWA from 'next-pwa';
const withPWA = require('next-pwa')({
dest: 'public',
disable: process.env.NODE_ENV === 'development'
});
我们的 Service Worker 策略很简单:
我们在 Vercel 上进行部署,因为与 Next.js 的集成是无缝的。每次推送到我们的主分支都会触发自动构建和部署。更重要的是:
我们的部署管道如下所示:
Git Push → GitHub → Vercel Build → CDN Distribution → Global Users
特别是对于内容更新,我们设置了 Webhooks,以便当我们的内容子模块更新时,Vercel 会自动使用新内容重建网站。
所有这些架构一起工作,创建一个在顶层执行的平台。我们的实际指标:
这些不是虚荣指标 - 更快的网站意味着更多的学习者可以访问我们的内容,特别是那些在移动网络上或基础设施有限的地区的学习者。
整个代码库是开源的。如果您想了解所有这些部分如何协同工作,您可以探索存储库,做出改进,或将其分叉到您自己的教育平台。
我们在这里描述的架构不是专有的 - 它是建立在可靠的、广泛采用的开源工具之上的。社区从我们的学习中受益,我们也从社区的贡献中受益。
无论您是构建教育平台还是任何内容丰富的应用程序,请考虑:
AI Educademy 代表了我们对可访问、高性能和可维护的教育技术基础设施的承诺。如果您对这些技术感兴趣或想做出贡献,我们的代码是开源的,等待您的协作。
想尝试我们的平台吗? 探索我们的项目 | 参观实验室 | 阅读更多关于我们的使命