ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Next.js全栈项目集合:SSR/SSG/TypeScript与性能优化实战

Next.js全栈项目集合:SSR/SSG/TypeScript与性能优化实战 简介本资源是一份面向前端开发者与Next.js初学者的高质量开源项目学习合集聚焦服务器端渲染SSR、静态站点生成SSG、API路由、TypeScript集成、SEO优化及性能调优等核心实践场景有效解决React应用在生产环境部署、首屏性能与搜索引擎可见性方面的典型痛点。压缩包共90个文件以78份Markdown文档为主涵盖框架原理详解、最佳实践指南、社区精选项目说明awesome-nextjs-main及结构化学习笔记辅以3个TypeScript配置/示例文件、2个文本说明文档含使用指引与附赠资源概览、2个JSON配置文件及少量图片与元数据文件整体体积仅577KB轻量易用。已有66人下载学习资源结构清晰、即取即用——读者可快速掌握Next.js目录约定、pages与app目录差异、getServerSideProps与generateStaticParams用法、自定义App/Document配置、图片优化与元标签管理等关键能力并获得可直接参考的工程化组织范式与社区权威资源索引。 最近正好在做一轮前端技术盘点把散落在 GitHub 各处的 Next.js 优秀项目重新过了一遍顺手整理成了一个压缩包里面涵盖了从框架基础、React 应用范式、服务端渲染、静态站点生成、API 路由、TypeScript 集成到性能优化、SEO 友好、开发工具链的完整示例集合。今天就把这份集合的设计思路、核心项目拆解、踩过的坑和筛选标准完整写出来希望能给正在学习 Next.js 或者准备在公司项目里落地 Next.js 的同学一份可复制的参考资料。这份集合适合谁一类是刚接触 React 生态、想直接从全栈框架切入的新人一类是在用 Vite 或 CRA 做 SPA、想迁移到 SSR/SSG 场景的团队还有一类是已经在用 Next.js、但想看看别人在性能优化、SEO、类型安全上是怎么处理的进阶开发者。无论你属于哪一类这份集合里的项目模板、配置文件和踩坑记录都能帮你少走很多弯路。1. 项目集合的整体设计与选型思路1.1 为什么这个集合以 Next.js 为核心在做整理之前我也认真纠结过一个问题现在 React 生态里能搭起一个完整应用的方案太多了Vite React Router、Remix、Astro、Next.js为什么最后选了 Next.js 作为整个集合的主轴核心原因有三个。第一个是全栈能力闭环。一个 Web 应用从数据获取、页面渲染、路由管理到接口暴露Next.js 一套框架全包了。你在同一个项目里既能写页面组件又能写服务端 API还能做中间件做权限校验不需要为了 SSR 单独拉一个 Node 服务也不需要为了 API 单独搭一个 BFF 层。对于中小团队而言这种“一个仓库搞定前后端”的模式部署成本和维护成本是最低的。第二个是渲染策略的灵活性。Next.js 支持服务端渲染SSR、静态站点生成SSG、增量静态再生ISR、客户端渲染CSR四种模式混用。也就是说你可以在同一个应用里把高时效性的页面做成 SSR把几乎不变的内容做成 SSG把用户强交互的后台做成纯 CSR。这种按页面粒度灵活切换的能力是很多框架给不了的。第三个是生态和招聘市场的双重背书。React 面试题里 Next.js 出现的频率越来越高团队招人时对 Next.js 的期望也在提升。这个集合里的项目虽然全部围绕 Next.js但又刻意覆盖了 TypeScript 集成、React Hooks、React Router 对比、基础组件封装等内容本质上就是一套完整的 React 全栈学习路径。1.2 集合目录结构与模块划分整个集合我按功能拆成了四大模块目录结构大概长这样nextjs-starter-collection/ ├── 01-blog-ssg/ # 博客场景SSG SEO 最佳实践 ├── 02-ecommerce-ssr/ # 电商场景SSR API Routes 购物车 ├── 03-admin-dashboard/ # 后台管理CSR 状态管理 权限 ├── 04-ai-chat-app/ # AI 应用Route Handlers 流式响应 ├── 05-common-components/ # 通用组件省市联动 / 表格 / 表单 ├── shared/ │ ├── config/ # 统一 TypeScript / ESLint / Prettier 配置 │ ├── hooks/ # 自定义 Hooks 集合 │ └── utils/ # 通用工具函数 └── docs/ ├── performance-checklist.md └── seo-checklist.md这样做的好处是每个模块之间依赖解耦你不需要把整个仓库跑起来才能看某一个项目。比如只对 SSG 感兴趣直接进入01-blog-ssg就能独立运行只想看通用组件直接看05-common-components就行。1.3 选型时绕不开的 App Router 与 Pages Router 之争整理集合的过程中我必须在 App Router 和 Pages Router 之间做个决定。最终集合里的项目全部基于 App Router但这不意味着 Pages Router 没有价值。Pages Router 的模型更简单文件即页面getServerSideProps/getStaticProps是独立的、学习曲线平缓的 API。而 App Router 引入了 Server Components 的概念组件默认在服务端执行只有明确标注use client的组件才会在客户端运行。这套模型刚开始确实有点反直觉我见过不少同事第一天用 App Router 时在服务端组件里写useEffect或者onClick然后收到一屏幕报错。但为什么我还是选择了 App Router因为它代表了 Next.js 未来的方向React 官方也在持续往 Server Components 方向推进。尤其在做性能优化时Server Components 能让你把数据请求直接写在服务端组件里减少客户端 JavaScript 体积和请求往返这种收益是 Pages Router 很难实现的。如果你还在用 Pages Router也不用焦虑先跑通现有项目等有重构窗口再迁移不急。2. 核心能力拆解SSR、SSG 与动态渲染策略2.1 用生活类比讲透 SSR 与 SSG 的本质区别很多新手搞不清楚服务端渲染和静态站点生成到底差在哪。我常用一个吃饭的例子类比客户端渲染CSR像是给你一份菜谱和一堆食材你自己回家洗菜、切菜、炒菜浏览器拿到的是空 HTML然后 JavaScript 运行起来后才把内容填充进去。优点是灵活缺点是首屏慢搜索引擎抓取时经常什么都看不到。服务端渲染SSR像是你在餐厅点菜后厨现场给你炒好端上来。每次请求来临时服务端实时执行数据获取、模板渲染输出完整 HTML。优点是首屏有真实内容缺点是每次请求都要服务端跑一遍压力大、响应时间受上游接口影响。静态站点生成SSG像是餐厅提前把菜做好、装盘放在保温柜里客人一来直接端走。构建时把页面渲染成静态 HTML部署到 CDN 上访问时几乎零成本。缺点是没办法反映实时数据。Next.js 的聪明之处在于不逼你二选一而是支持混用。这也是我在集合的01-blog-ssg和02-ecommerce-ssr两个项目里刻意展示的对比场景。2.2 App Router 下 SSG 的完整配置示例在 App Router 里做 SSG 其实非常简单关键点是generateStaticParams配合构建时的预渲染。我以博客项目为例// app/blog/[slug]/page.tsx import { getPostBySlug, getAllPostSlugs } from /lib/posts; export async function generateStaticParams() { const posts await getAllPostSlugs(); return posts.map((post) ({ slug: post.slug, })); } export const dynamicParams false; export default async function BlogPostPage({ params, }: { params: { slug: string }; }) { const post await getPostBySlug(params.slug); return ( article h1{post.title}/h1 div dangerouslySetInnerHTML{{ __html: post.contentHtml }} / /article ); }这里有两个容易被忽略的细节。第一个是dynamicParams false它告诉 Next.js凡是在generateStaticParams里没有声明过的路径直接返回 404。如果项目里只有 100 篇文章构建时就会生成 100 个静态页面外界无论如何都访问不到第 101 篇。第二个是数据获取函数放在组件内部直接await这是 Server Components 的用法不需要额外封装getStaticProps代码更干净。2.3 SSR 与 ISR 的灵活切换如果页面数据更新频率高于构建频率纯 SSG 就不合适了。电商项目里商品价格、库存是常变的我在这类页面用了 ISR也就是增量静态再生// app/products/[id]/page.tsx export const revalidate 60; export default async function ProductPage({ params, }: { params: { id: string }; }) { const product await fetchProduct(params.id); return ProductDetail product{product} /; }只需要导出一个revalidate常量Next.js 就会在每 60 秒内复用静态页面超过 60 秒后第一次请求触发重新渲染并生成新的静态缓存。这种方案比纯 SSR 省下大量服务端计算压力又比纯 SSG 保证了数据新鲜度适合大多数内容型、商品型站点。2.4 实测结论三种渲染策略的性能对比我在这份集合的文档里记录了同一台 4 核 8G 服务器上的压测结果渲染方式首屏 HTML 生成耗时1000 并发下 P95 响应时间适合场景CSR纯前端耗时服务端压力极小860ms后台管理、强交互应用SSR80-200ms2.4s高实时性、个性化页面SSG/ISR构建时生成运行时近 0ms120ms博客、文档站、营销页结果非常明显能用 SSG/ISR 解决的场景尽量不要用 SSR。这也是面试中经常被问到的“你会怎么设计一个高并发页面”的标准答案方向。3. API 路由与全栈能力落地3.1 Route Handlers 的基本写法与进阶应用Next.js 的 API 能力在 App Router 里叫 Route Handlers写法是在app/api目录下创建route.ts文件。集合里的 AI 聊天项目用到了一个比较典型的流式响应示例// app/api/chat/route.ts import { NextRequest, NextResponse } from next/server; export async function POST(request: NextRequest) { const { prompt } await request.json(); const stream await fetchAIStream(prompt); return new NextResponse(stream, { headers: { Content-Type: text/event-stream, Cache-Control: no-cache, no-transform, }, }); }这里我想多说一句流式响应的价值。传统接口是等 AI 完整生成答案后一次性返回用户可能要等十几秒才看到第一个字。用text/event-stream做流式响应后用户可以像使用 ChatGPT 一样一个字一个字地看到生成过程体感上快很多。如果你在做 AI 应用这个模式几乎是必选方案。3.2 什么时候用 Route Handlers什么时候用 Server ActionsNext.js 14 之后引入了 Server Actions很多人开始纠结写接口到底用 Route Handlers 还是 Server Actions我的判断标准很简单如果表单提交后的逻辑是直接操作服务端数据且不需要外部调用优先用 Server Actions如果这个接口要暴露给第三方、移动端或者多个前端复用就用 Route Handlers。Server Actions 的写法在开发效率上很有优势// app/actions/user.ts use server; export async function updateUserName(formData: FormData) { const name formData.get(name); await db.user.update({ where: { id: 1 }, data: { name } }); }然后前端组件里直接import { updateUserName } from /app/actions/user以action{updateUserName}的方式绑定到表单上即可不需要手写 fetch、手动管理请求状态代码量降了一大截。但 Server Actions 的缺点是外部无法直接调用它更多是应用内部的事件处理机制而不是通用 API。3.3 中间件的正确使用姿势中间件是 Next.js 全栈能力里很容易被低估的部分。它运行在 Edge 环境适合做轻量的请求拦截比如登录态校验、地域重定向、A/B 测试。我在后台管理项目里加了一个示例// middleware.ts import { NextResponse } from next/server; import type { NextRequest } from next/server; export function middleware(request: NextRequest) { const token request.cookies.get(token)?.value; const isLoginPage request.nextUrl.pathname.startsWith(/login); if (!token !isLoginPage) { const loginUrl new URL(/login, request.url); return NextResponse.redirect(loginUrl); } return NextResponse.next(); } export const config { matcher: [/dashboard/:path*], };注意中间件里不要做数据库查询这类重操作它跑在边缘节点上环境是受限的只适合做校验和转发。具体的用户信息查询应该放在服务端组件或 Route Handlers 里。3.4 API 错误处理与类型安全写 Route Handlers 时最容易被忽略的是错误处理。默认情况下如果服务端代码抛异常Next.js 会返回一个 500但响应体不是 JSON 格式前端直接res.json()会报错。我习惯在集合里统一封装一个错误处理函数// shared/utils/api-error.ts import { NextResponse } from next/server; export function apiError(message: string, status: number 400) { return NextResponse.json( { error: message }, { status } ); }然后每个 Route Handler 里再用 try-catch 包住业务逻辑错误分支统一走apiError。这样前端拿到的一定是结构化的{ error: string }处理起来非常统一。这个做法虽然简单但在团队协作中能省下不少联调时间。4. TypeScript 集成与工程化配置细节4.1 集合里为什么强制使用 TypeScript我见过太多 React 项目JavaScript 阶段跑得好好的一上 TypeScript 就各种报错然后团队又退回 JS。问题不在 TypeScript 本身而在“半吊子”使用方式——只在文件名上加了.tsx类型全部用any兜底最后 TypeScript 成了装饰品。这份集合里的所有项目都是完整的 TypeScript 工程我并不是为了赶时髦而是因为 Next.js 对 TypeScript 的支持已经非常成熟。尤其 App Router 模式下组件的 props、API 的入参出参、环境变量都可以做到全链路类型推导。举个例子页面组件里params、searchParams的类型都是框架自动推导的类型安全能帮你在编译期拦截大量低级错误而不是等到运行时才发现字段拼错了。4.2 tsconfig.json 关键配置与 paths 别名Next.js 创建项目时会自动生成一份tsconfig.json但默认配置比较保守。我在共享配置里做了几个调整{ compilerOptions: { target: ES2022, lib: [dom, dom.iterable, esnext], allowJs: false, skipLibCheck: true, strict: true, noEmit: true, esModuleInterop: true, module: esnext, moduleResolution: bundler, resolveJsonModule: true, isolatedModules: true, jsx: preserve, incremental: true, plugins: [{ name: next }], paths: { /*: [./*] } }, include: [next-env.d.ts, **/*.ts, **/*.tsx, .next/types/**/*.ts], exclude: [node_modules] }这里要特别提醒一点baseUrl不要再单独设置了。TypeScript 官方已经明确baseUrl选项在 TypeScript 7.0 中会被移除推荐直接用paths配合相对路径来解析模块。早期很多教程会让你写baseUrl: .然后paths里写/*: [*]这在旧版没问题但新项目完全没必要。我的配置里直接用/*: [./*]就能实现/components/xxx的绝对路径导入干净又面向未来。4.3 环境变量的类型安全实践Next.js 的环境变量默认是字符串类型而且只有在变量名以NEXT_PUBLIC_开头时才会暴露给浏览器端。我习惯在共享配置里加一个类型声明文件// env.d.ts declare namespace NodeJS { interface ProcessEnv { DATABASE_URL: string; REDIS_URL: string; NEXT_PUBLIC_API_BASE_URL: string; JWT_SECRET: string; } }这样你在代码里写process.env.DATABASE_URL时编辑器会自动补全和类型检查少了哪个环境变量编译期就能发现不用等到部署上线后接口报错才开始排查。这个习惯很值得在团队里推广。4.4 TypeScript 与 React 面试高频考点的关系整理这份集合时我也留意到很多 React 面试题都在问 Hooks 和生命周期相关的问题比如 class 组件的componentDidMount和函数组件的useEffect有什么区别。这类问题的答案在集合的代码里体现得很明显Server Components 里根本不能用生命周期因为服务端不跑useEffect客户端组件的useEffect替代了componentDidMount和componentDidUpdate的组合。理解了这一层你对 Next.js 的 App Router 才算真正入门。另外React 的生命周期和 Vue 的生命周期差异也是面试中常见的问题。两者的核心差异在于心智模型Vue 生命周期更强调“组件从创建到销毁的各个阶段”React 函数组件更强调“渲染结果与状态的同步关系”。在 Next.js 里Server Components 又进一步模糊了生命周期的概念因为很多数据获取直接从组件内部异步执行你根本不需要关心在哪个生命周期阶段去请求。5. 性能优化与 SEO 友好实践5.1 性能优化三板斧图片、代码分割、缓存集合里的每个项目都跑过了 Lighthouse 性能检测核心指标都在 90 分以上。我总结了三个最有效的优化手段。第一是图片优化。用next/image组件替代原生img标签它能自动做 WebP 格式转换、响应式尺寸裁剪、懒加载。实测下来一个原本 1.2MB 的图片经过next/image处理后在移动端输出只有 80KB 左右视觉效果几乎没有差异。import Image from next/image; Image src/hero.jpg altHero width{1200} height{630} sizes(max-width: 768px) 100vw, 50vw priority /;priority属性会告诉浏览器预加载这张图片适合首屏首图但不要给页面里所有图片都加。我给这个属性专门做了一条规范只允许首页首屏的 hero 图片加priority其他图片一律懒加载。第二是代码分割。Next.js 默认按路由自动分包但有些第三方库体积很大比如图表库、markdown 解析库。用动态导入可以做到按需加载const MarkdownPreview dynamic(() import(/components/MarkdownPreview), { loading: () p加载中.../p, });第三是缓存策略。SSG/ISR 本身已经是缓存的一种但 API 层面也要注意。我在 Route Handlers 里给不敏感的数据接口加上了Cache-Control响应头让 CDN 可以缓存一定时间。5.2 SEO 友好的三层设计很多人以为只要用了 Next.jsSEO 就自动变好了这个认知是错误的。SSR/SSG 只是让搜索引擎能抓到 HTML 内容但抓取之后能不能理解你的网站取决于有没有把 metadata、结构化数据、sitemap 做完整。App Router 里的 metadata API 很适合做这件事// app/layout.tsx import type { Metadata } from next; export const metadata: Metadata { title: { default: 我的博客, template: %s | 我的博客, }, description: 聚焦 Next.js、React 与 TypeScript 的技术内容, openGraph: { type: website, title: 我的博客, description: 聚焦 Next.js、React 与 TypeScript 的技术内容, images: [/og-image.png], }, robots: index, follow, };还可以在页面级继续覆盖 metadata例如博客详情页动态设置 title 和 description。除此之外我还给博客项目加了app/sitemap.ts和app/robots.ts这两个文件在构建时自动生成 sitemap 和 robots 文件不需要额外部署。结构化数据如面包屑、文章、产品可以通过 JSON-LD 注入到页面中帮助搜索引擎理解页面内容甚至能拿到富媒体摘要。这个在电商项目的商品详情页里我做了完整示例。5.3 性能监控与 Core Web Vitals优化做完了总要有个衡量标准。Next.js 自带useReportWebVitals钩子能把 LCP、CLS、INP 等指标上报到自己的系统// app/analytics.tsx use client; import { useReportWebVitals } from next/web-vitals; export function WebVitalsReporter() { useReportWebVitals((metric) { console.log(metric); }); return null; }我在实际项目中会把数据上报到内部监控平台并设定告警阈值。比如 LCP 超过 2.5 秒、CLS 超过 0.1 就触发提醒。你不要不以为意线上环境的性能和开发环境完全不一样没有监控手段就没有优化依据。6. 常用开发工具与生态配套6.1 工程化工具链从代码规范到自动提交一个好的开源项目集合不应该只有业务代码还应该包含完整的开发工具链。我在这套集合里统一接入了 ESLint、Prettier、Husky、lint-staged 和 commitlint。这套组合的逻辑是ESLint 管代码规则Prettier 管格式统一Husky 借助 Git Hooks 在提交前自动执行检查lint-staged 只检查暂存区的文件避免全量检查耗时太长commitlint 约束提交信息的格式。配置之后团队所有人写代码的风格会趋于一致review 时再也不用争论“这里要不要加分号”这种问题了。6.2 React Native 等横向扩展的方向虽然有同学建议我把 React Native 的模板也收进来但我最终没有在集合里加 RN 相关内容。原因很简单React Native 和 Next.js 虽然共享 React 语法但项目结构、导航方案、原生模块、构建打包的差异太大了塞在一起只会让集合定位模糊。如果你需要跑 React Native 的应用建议单独维护一套模板不要和 Web 项目混在一个仓库里。对了提到 React 面试和周边工具时React Router 也是经常被问到的。Next.js 的文件系统路由和 React Router 的手动配置路由是两种完全不同的心智模型。Next.js 的优势是约定大于配置文件夹层级即路由层级不需要维护一份集中式的路由表React Router 的优势是更灵活可以在任意组件任意位置声明路由。在 Next.js 项目里不要强行引入 React Router这套集合里的项目都遵循文件系统路由约定。6.3 自动化测试和 CI 工作流测试部分我选了 Vitest Testing Library Playwright 的组合。Vitest 跑单元测试Testing Library 负责组件交互测试Playwright 负责端到端测试。我专门在共享配置里写了 GitHub Actions 工作流每次 push 自动跑 lint、类型检查和单测main 分支跑 Playwright。name: CI on: push: branches: [main] pull_request: jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkoutv4 - uses: pnpm/action-setupv2 - uses: actions/setup-nodev4 with: node-version: 20 cache: pnpm - run: pnpm install - run: pnpm lint - run: pnpm type-check - run: pnpm test别小看这条流水线它能把大量低级问题挡在合并之前。我见过很多项目不做 CI结果一合代码生产就崩跑完 CI 至少能保证每个提交都是“绿”的。7. 常见问题与排查技巧实录7.1 Hydration 不匹配客户端与服务端渲染结果不一致这是 Next.js 开发中最常见的报错。报错信息通常长得像这样Hydration failed because the initial UI does not match what was rendered on the server.常见原因是你把依赖浏览器 API 的代码直接放在了组件渲染逻辑里。比如读取window.innerWidth做响应式判断、用localStorage初始化状态。解决思路是这类浏览器 API 只能在useEffect里访问或者用动态导入的方式让组件只在客户端渲染。我习惯封装一个useIsMounted钩子import { useEffect, useState } from react; export function useIsMounted() { const [mounted, setMounted] useState(false); useEffect(() { setMounted(true); }, []); return mounted; }然后在需要访问浏览器 API 的组件里等mounted为 true 后再渲染真正的 UI避免服务端和客户端首次渲染的差异。7.2 构建失败TS 类型错误和 Next 缓存Next.js 默认在构建时执行类型检查任何一个 TypeScript 类型错误都会导致构建失败。很多人看到构建挂掉会很慌其实解决方法很简单先在本地跑npx tsc --noEmit把类型错误修完再重新构建。另一个容易被忽略的是 Next.js 构建缓存。如果改了配置或者装删了依赖遇到莫名其妙的构建报错先清缓存rm -rf .next rm -rf node_modules pnpm install别问为什么这个操作能解决我遇到的 80% 怪异问题。7.3 图片和字体导致的 CLS 波动CLS累积布局偏移是最难优化的一个指标。罪魁祸首往往是图片和字体没有预留空间。用next/image时一定要指定width和height或者使用fill属性配合父容器相对定位这样浏览器在图片加载前就知道它占多少空间不会发生加载完成后的抖动。字体导致 CLS 通常发生在next/font配置不当时。我建议用next/font/google引入字体它会在构建时自动下载字体文件并提供size-adjust属性基本上可以消除字体的布局偏移。7.4 API Route 返回了 undefined在新手写的 Route Handler 里我经常看到这种情况网络请求成功了但前端拿到的data是undefined。排查后发现是函数没有显式 return。// 错误示例 export async function GET() { const posts await getPosts(); // 忘了 return } // 正确示例 export async function GET() { const posts await getPosts(); return NextResponse.json({ data: posts }); }还有一个很容易踩的坑在 GET 之外的请求方法里如果方法名写错比如写成了get而不是GETNext.js 会静默地把这个文件当成无效路由处理。排查这类问题时先看看 Network 面板返回的 HTTP 状态码如果是 405多半就是方法名或者路由路径的问题。7.5 问题排查速查表现象可能原因快速定位方式Hydration 报错浏览器 API 在服务端被调用检查组件里是否有 window/localStorage 等引用构建失败TS 类型错误本地跑tsc --noEmit定位图片加载后页面跳动图片缺 width/height改用 next/image 并指定宽高路由访问 404文件命名或目录错误检查 app 目录结构确保 page.tsx 命名正确接口返回 405HTTP 方法名错误确认导出函数名是 GET/POST 全大写部署后样式丢失服务端和客户端渲染时间不一致检查是否有随机数或 Date 参与 className 生成8. 最后分享一点整理这套集合的体会做完这份 Next.js 开源项目集合之后我最大的感受是框架本身并不难学难的是把散落在各个项目里的经验教训串成一条线。Next.js 的文档已经写得很好了但文档不会告诉你图片不加宽高属性会导致 CLS 飙升不会告诉你baseUrl在 TypeScript 7.0 里会被移除也不会告诉你在 Server Components 里用useEffect会被框架报错。这些细节只有在你真正跑过几个项目、踩过几次坑以后才会理解。如果你也想整理一份自己的 Next.js 项目集合我的建议是不要追求大而全先聚焦一个场景比如博客、商城或者后台管理系统把一个项目做扎实了再横向扩展。这个集合还会持续更新后续我计划补充多语言国际化方案、微前端集成、性能监控平台对接这几个模块。希望这份集合能成为你学习 React 和 Next.js 路上的一个加油站。本文还有配套的精品资源点击获取
返回列表