diff --git a/src/app/about/page.tsx b/src/app/about/page.tsx
index 408460d..97fcdad 100644
--- a/src/app/about/page.tsx
+++ b/src/app/about/page.tsx
@@ -57,7 +57,7 @@ export default function About() {
theme === "dark" ? "text-indigo-300" : "text-indigo-700"
}`}
>
- Zhuba-Ahhh
+ {process.env.NEXT_PUBLIC_AUTHOR_NAME}
前端开发者 / 技术博主
diff --git a/src/app/blog/[id]/AnimatedBlogPost.tsx b/src/app/blog/[id]/AnimatedBlogPost.tsx
index 6f49671..60ab0c5 100644
--- a/src/app/blog/[id]/AnimatedBlogPost.tsx
+++ b/src/app/blog/[id]/AnimatedBlogPost.tsx
@@ -17,10 +17,14 @@ interface AnimatedBlogPostProps {
headings: Heading[];
readingTime: number;
relatedPosts: BlogPost[];
+ prevPost?: BlogPost;
+ nextPost?: BlogPost;
}
export default function AnimatedBlogPost({
post,
+ prevPost,
+ nextPost,
headings,
readingTime,
relatedPosts,
@@ -55,7 +59,7 @@ export default function AnimatedBlogPost({
contentFile={post?.contentFile}
components={mdxComponents}
/>
-
+
@@ -21,9 +27,33 @@ export default function BlogFooter({ post }: BlogFooterProps) {
))}
-
+
+
+ {prevPost && (
+
+ )}
+
+
+
+
+
+ {nextPost ? (
+
+ ) : (
+
+ )}
+
+
>
);
}
diff --git a/src/app/blog/[id]/BlogHeader.tsx b/src/app/blog/[id]/BlogHeader.tsx
index 6e95007..a696154 100644
--- a/src/app/blog/[id]/BlogHeader.tsx
+++ b/src/app/blog/[id]/BlogHeader.tsx
@@ -7,17 +7,27 @@ interface BlogHeaderProps {
}
export default function BlogHeader({ post, readingTime }: BlogHeaderProps) {
+ const { title, author, date, coverImage } = post;
return (
<>
- {post.title}
-
-
{post.date} |
{post.author} |
-
预计阅读时间: {readingTime} 分钟
+
{title}
+
+
+
+ {date}
+
+ |
+ {author}
+ |
+
+
+ 预计阅读时间: {readingTime} 分钟
+
- {post.coverImage && (
+ {coverImage && (
);
}
+
+const CalendarIcon = ({ className }: { className: string }) => {
+ return (
+
+ );
+};
+
+const ClockIcon = ({ className }: { className: string }) => {
+ return (
+
+ );
+};
diff --git a/src/app/blog/[id]/TableOfContents.tsx b/src/app/blog/[id]/TableOfContents.tsx
index f3b4bb9..22bcebf 100644
--- a/src/app/blog/[id]/TableOfContents.tsx
+++ b/src/app/blog/[id]/TableOfContents.tsx
@@ -49,26 +49,26 @@ const TableOfContents: React.FC
= ({ headings }) => {
return (
文章目录
}>
-
-
-
- )
-}
-\`\`\`
-
-## 新的图片组件
-
-Next.js 13引入了新的\`Image\`组件,它提供了更好的性能和用户体验:
-
-\`\`\`jsx
-import Image from 'next/image'
-
-export default function Avatar() {
- return (
-
- )
-}
-\`\`\`
-
-新的\`Image\`组件支持:
-
-- 自动图片优化
-- 延迟加载
-- 响应式图片
-- 防止布局偏移
-
-## 字体优化
-
-Next.js 13引入了新的字体系统,它可以自动优化和加载自定义字体:
-
-\`\`\`jsx
-import { Inter } from 'next/font/google'
-
-const inter = Inter({ subsets: ['latin'] })
-
-export default function RootLayout({ children }) {
- return (
-
- {children}
-
- )
-}
-\`\`\`
-
-这个系统可以:
-
-- 自动内联字体CSS
-- 消除布局偏移
-- 预加载关键字体文件
-
-## 从Next.js 12迁移到13
-
-迁移到Next.js 13需要注意以下几点:
-
-1. 创建新的\`app\`目录,逐步迁移路由
-2. 更新\`next/image\`导入为\`next/legacy/image\`
-3. 将客户端组件标记为\`'use client'\`
-4. 更新API路由到新的\`app/api\`目录
-5. 使用新的数据获取方法替代\`getServerSideProps\`和\`getStaticProps\`
-
-## 结论
-
-Next.js 13带来了许多令人兴奋的新特性,这些特性不仅提高了开发效率,还大大改善了应用性能和用户体验。App Router、服务器组件和流式渲染等新特性为我们提供了更灵活、更强大的工具,使得构建现代Web应用变得更加容易。
-
-随着Next.js的不断发展,我们可以期待看到更多令人兴奋的新特性和改进。如果您还没有尝试过Next.js 13,现在是时候了!
- `,
+ content: content2,
date: "2024-03-20",
author: "李四",
tags: ["Next.js", "服务器组件", "性能优化"],
diff --git a/src/data/ts/1.ts b/src/data/ts/1.ts
new file mode 100644
index 0000000..438fa64
--- /dev/null
+++ b/src/data/ts/1.ts
@@ -0,0 +1,412 @@
+export const content1 = `
+# 深入理解React Hooks
+
+React Hooks是React 16.8中引入的新特性,它彻底改变了我们编写React组件的方式。本文将深入探讨Hooks的工作原理,包括常用Hooks的实现细节和使用技巧,以及如何创建自定义Hooks。
+
+## 为什么需要Hooks?
+
+在Hooks出现之前,React组件主要分为类组件和函数组件。类组件可以使用状态和生命周期方法,而函数组件则更简单,但功能有限。Hooks的出现使得函数组件也能够使用状态和其他React特性,从而带来以下优势:
+
+1. 更简洁的代码
+2. 更容易复用逻辑
+3. 更好的性能优化
+4. 更容易理解和维护的组件
+
+## 常用Hooks详解
+
+### useState
+
+\`useState\`是最基本的Hook,用于在函数组件中添加状态。
+
+\`\`\`jsx
+import React, { useState } from 'react';
+
+function Counter() {
+ const [count, setCount] = useState(0);
+
+ return (
+
+
You clicked {count} times
+
+
+ );
+}
+\`\`\`
+
+\`useState\`返回一个数组,第一个元素是当前状态值,第二个元素是更新状态的函数。
+
+### useEffect
+
+\`useEffect\`用于处理副作用,如数据获取、订阅或手动修改DOM等。
+
+\`\`\`jsx
+import React, { useState, useEffect } from 'react';
+
+function DataFetcher() {
+ const [data, setData] = useState(null);
+
+ useEffect(() => {
+ fetch('https://api.example.com/data')
+ .then(response => response.json())
+ .then(data => setData(data));
+ }, []); // 空数组表示只在组件挂载时执行一次
+
+ return (
+
+ {data ?
{JSON.stringify(data, null, 2)}
: 'Loading...'}
+
+ );
+}
+\`\`\`
+
+\`useEffect\`接受两个参数:一个函数和一个依赖数组。函数在组件渲染后执行,依赖数组决定了effect何时重新运行。
+
+### useContext
+
+\`useContext\`用于访问React的Context API,使得组件可以订阅上下文变化。
+
+\`\`\`jsx
+import React, { useContext } from 'react';
+
+const ThemeContext = React.createContext('light');
+
+function ThemedButton() {
+ const theme = useContext(ThemeContext);
+ return ;
+}
+\`\`\`
+
+### useReducer
+
+\`useReducer\`是\`useState\`的替代方案,用于管理复杂的状态逻辑。
+
+\`\`\`jsx
+import React, { useReducer } from 'react';
+
+function reducer(state, action) {
+ switch (action.type) {
+ case 'increment':
+ return {count: state.count + 1};
+ case 'decrement':
+ return {count: state.count - 1};
+ default:
+ throw new Error();
+ }
+}
+
+function Counter() {
+ const [state, dispatch] = useReducer(reducer, { count: 0 });
+ return (
+ <>
+ Count: {state.count}
+
+
+ >
+ );
+}
+\`\`\`
+
+## 自定义Hooks
+
+创建自定义Hook允许你将组件逻辑提取到可重用的函数中。
+
+\`\`\`jsx
+import { useState, useEffect } from 'react';
+
+function useWindowWidth() {
+ const [width, setWidth] = useState(window.innerWidth);
+
+ useEffect(() => {
+ const handleResize = () => setWidth(window.innerWidth);
+ window.addEventListener('resize', handleResize);
+ return () => {
+ window.removeEventListener('resize', handleResize);
+ };
+ }, []);
+
+ return width;
+}
+
+function MyResponsiveComponent() {
+ const width = useWindowWidth();
+ return Window width is {width}
;
+}
+\`\`\`
+
+## Hooks的使用规则
+
+使用Hooks时需要遵循两个重要规则:
+
+1. 只在最顶层使用Hooks
+2. 只在React函数中调用Hooks
+
+这些规则确保Hooks在每次渲染时都以相同的顺序被调用,这对于Hooks的正确工作至关重要。
+
+## Hooks与类组件的对比
+
+Hooks和类组件各有优势。Hooks通常能让代码更简洁,逻辑更容易复用,但类组件在某些场景下仍然有其优势,如错误边界。
+
+以下是一个简单的对比:
+
+| 特性 | Hooks | 类组件 |
+| ---- | ----- | ------ |
+| 代码简洁性 | ✅ | ❌ |
+| 逻辑复用 | ✅ | ❌ |
+| 学习曲线 | 中等 | 较陡 |
+| 性能 | ✅ | ✅ |
+
+
+## 高级Hooks详解
+
+### useRef
+
+\`useRef\`用于创建一个可变的ref对象,其.current属性被初始化为传入的参数。
+
+\`\`\`jsx
+function TextInputWithFocusButton() {
+ const inputEl = useRef(null);
+ const onButtonClick = () => {
+ // \`current\` 指向已挂载到 DOM 上的文本输入元素
+ inputEl.current.focus();
+ };
+ return (
+ <>
+
+
+ >
+ );
+}
+\`\`\`
+
+### useLayoutEffect
+
+\`useLayoutEffect\`与\`useEffect\`类似,但它会在所有的DOM变更之后同步调用effect。
+
+\`\`\`jsx
+useLayoutEffect(() => {
+ // 在DOM更新后立即执行
+ // 适用于需要在浏览器绘制之前进行DOM测量的场景
+}, [dependency]);
+\`\`\`
+
+## Hooks的实现原理
+
+React Hooks的实现依赖于JavaScript的闭包机制。每次组件渲染时,React都会创建一个新的执行上下文,其中包含了该次渲染的props和state。
+
+以\`useState\`为例,其简化实现可能如下:
+
+\`\`\`javascript
+let state;
+function useState(initialValue) {
+ state = state || initialValue;
+ function setState(newValue) {
+ state = newValue;
+ render();
+ }
+ return [state, setState];
+}
+\`\`\`
+
+这解释了为什么Hooks需要在组件的顶层调用 - 它们依赖于被调用的顺序来正确地将内部状态与每个Hook调用关联起来。
+
+## Hooks在实际项目中的应用
+
+### 状态管理
+
+使用\`useReducer\`和\`useContext\`可以创建一个简单的全局状态管理解决方案:
+
+\`\`\`jsx
+const initialState = { count: 0 };
+const reducer = (state, action) => {
+ switch (action.type) {
+ case 'increment': return { count: state.count + 1 };
+ case 'decrement': return { count: state.count - 1 };
+ default: throw new Error();
+ }
+};
+
+const CountContext = React.createContext();
+
+function CountProvider({ children }) {
+ const [state, dispatch] = useReducer(reducer, initialState);
+ return (
+
+ {children}
+
+ );
+}
+
+function Counter() {
+ const { state, dispatch } = useContext(CountContext);
+ return (
+ <>
+ Count: {state.count}
+
+
+ >
+ );
+}
+\`\`\`
+
+这个例子展示了如何使用Hooks创建一个简单但功能强大的状态管理系统。
+
+## 性能优化
+
+Hooks提供了几种方式来优化组件性能:
+
+1. \`useMemo\`: 缓存计算结果
+2. \`useCallback\`: 缓存函数
+3. \`React.memo\`: 优化函数组件的重渲染
+
+\`\`\`jsx
+import React, { useMemo, useCallback } from 'react';
+
+function ExpensiveComponent({ data, onItemClick }) {
+ const sortedData = useMemo(() => {
+ return data.sort((a, b) => a.id - b.id);
+ }, [data]);
+
+ const handleClick = useCallback((item) => {
+ console.log('Item clicked:', item);
+ onItemClick(item);
+ }, [onItemClick]);
+
+ return (
+
+ {sortedData.map(item => (
+ - handleClick(item)}>
+ {item.name}
+
+ ))}
+
+ );
+}
+
+export default React.memo(ExpensiveComponent);
+\`\`\`
+
+## Hooks的工作原理与源码解析
+
+为了更深入地理解Hooks的工作原理,我们需要探讨React的内部实现。React使用一个链表结构来存储组件的Hooks状态。
+
+### Hooks的内部结构
+
+在React的源码中,每个函数组件实例都与一个\`Fiber\`节点相关联。这个\`Fiber\`节点包含一个\`memoizedState\`属性,用于存储该组件的Hooks状态。每个Hook在内部表示为一个对象,大致结构如下:
+
+\`\`\`javascript
+{
+ memoizedState: any,
+ baseState: any,
+ baseQueue: Update | null,
+ queue: UpdateQueue | null,
+ next: Hook | null,
+}
+\`\`\`
+
+这些Hook对象通过\`next\`指针形成一个链表。
+
+### 为什么Hooks不能在循环中使用
+
+Hooks不能在循环、条件或嵌套函数中使用的原因与React如何将Hook的调用与其内部状态关联有关。React依赖于Hooks被调用的顺序来正确地将每个Hook与其对应的状态关联起来。
+
+让我们看一个简化的React内部实现示例:
+
+\`\`\`javascript
+let firstWorkInProgressHook = null;
+let workInProgressHook = null;
+
+function updateWorkInProgressHook() {
+ if (workInProgressHook === null) {
+ // 这是组件中的第一个Hook
+ workInProgressHook = firstWorkInProgressHook;
+ } else {
+ // 后续的Hooks
+ workInProgressHook = workInProgressHook.next;
+ }
+ return workInProgressHook;
+}
+
+function useState(initialState) {
+ let hook = updateWorkInProgressHook();
+
+ if (hook === null) {
+ // 首次渲染时初始化Hook
+ hook = {
+ memoizedState: initialState,
+ next: null
+ };
+
+ if (firstWorkInProgressHook === null) {
+ firstWorkInProgressHook = hook;
+ }
+ }
+
+ // 使用或更新Hook的状态
+ const setState = (newState) => {
+ hook.memoizedState = newState;
+ // 触发重新渲染
+ };
+
+ return [hook.memoizedState, setState];
+}
+\`\`\`
+
+在这个简化的实现中,我们可以看到React如何依赖于Hooks的调用顺序。如果在循环或条件语句中使用Hooks,可能会导致Hook的调用顺序在不同的渲染之间发生变化,从而破坏React对Hook状态的正确追踪。
+
+例如,考虑以下代码:
+
+\`\`\`jsx
+function Counter(props) {
+ if (props.count % 2 === 0) {
+ const [evenCount, setEvenCount] = useState(0);
+ }
+ const [count, setCount] = useState(0);
+ // ...
+}
+\`\`\`
+
+在这个例子中,\`evenCount\`的Hook只在\`props.count\`为偶数时创建。这意味着\`count\`的Hook在不同渲染之间可能对应于不同的内部Hook对象,导致状态混乱。
+
+### 自定义Hook的实现原理
+
+自定义Hook本质上是将一系列Hook调用封装到一个函数中。它们不依赖于特殊的React内部机制,而是利用了JavaScript的闭包特性。
+
+例如,一个\`useWindowSize\`自定义Hook的实现可能如下:
+
+\`\`\`jsx
+function useWindowSize() {
+ const [size, setSize] = useState({ width: window.innerWidth, height: window.innerHeight });
+
+ useEffect(() => {
+ const handleResize = () => {
+ setSize({ width: window.innerWidth, height: window.innerHeight });
+ };
+ window.addEventListener('resize', handleResize);
+ return () => window.removeEventListener('resize', handleResize);
+ }, []);
+
+ return size;
+}
+\`\`\`
+
+这个自定义Hook组合了\`useState\`和\`useEffect\`,创建了一个可重用的逻辑单元。
+
+## Hooks与函数式编程
+
+Hooks的设计理念与函数式编程密切相关。它们鼓励我们将逻辑分解为小的、可组合的单元,这与函数式编程的核心原则一致。
+
+例如,\`useReducer\`Hook实际上是在React组件中实现了一个简化版的Redux模式。这种方法使得状态管理逻辑更加清晰和可测试。
+
+## 结论
+
+React Hooks是一个强大的特性,它简化了状态管理和副作用处理,使得函数组件更加灵活和强大。通过深入理解Hooks的工作原理和使用技巧,我们可以编写出更简洁、可维护和高性能的React应用。
+
+然而,Hooks并不是银弹。在某些场景下,类组件可能仍然是更好的选择。关键是要根据具体情况选择最合适的工具。随着React的不断发展,我们可以期待看到更多围绕Hooks的创新和最佳实践的出现。
+
+通过深入理解Hooks的内部工作原理,我们可以更好地把握它们的使用限制和最佳实践。Hooks不仅改变了我们编写React组件的方式,还推动了整个React生态系统向更函数式、更声明式的方向发展。
+
+随着对Hooks的深入理解,开发者可以创建更加模块化、可重用和易于测试的组件。然而,重要的是要记住,Hooks并不是解决所有问题的万能工具。在某些情况下,类组件或其他模式可能更适合特定的需求。关键是要根据具体情况选择最合适的工具和方法。
+
+`;
diff --git a/src/data/ts/2.ts b/src/data/ts/2.ts
new file mode 100644
index 0000000..f6c9a0a
--- /dev/null
+++ b/src/data/ts/2.ts
@@ -0,0 +1,343 @@
+export const content2 = `
+# Next.js 13新特性解析
+
+Next.js 13是一个重大更新,引入了许多激动人心的新特性,如App Router、服务器组件、流式渲染等。本文将详细介绍这些新特性的使用方法和优势,以及如何从Next.js 12迁移到13版本。
+
+## App Router
+
+App Router是Next.js 13最显著的新特性之一,它彻底改变了路由管理的方式。
+
+### 基于文件系统的路由
+
+App Router延续了Next.js基于文件系统的路由概念,但引入了新的\`app\`目录结构:
+
+\`\`\`plaintext
+app/
+ layout.js
+ page.js
+ about/
+ page.js
+ blog/
+ [slug]/
+ page.js
+\`\`\`
+
+在这个结构中,\`page.js\`文件定义了路由的主要内容,而\`layout.js\`则定义了共享布局。
+
+### 嵌套布局
+
+App Router支持嵌套布局,这使得创建复杂的页面结构变得更加简单:
+
+\`\`\`jsx
+// app/layout.js
+export default function RootLayout({ children }) {
+ return (
+
+ {children}
+
+ )
+}
+
+// app/blog/layout.js
+export default function BlogLayout({ children }) {
+ return (
+
+ Blog Navigation
+ {children}
+
+ )
+}
+\`\`\`
+
+### 服务器组件
+
+默认情况下,App Router中的所有组件都是服务器组件。这意味着它们在服务器上渲染,可以直接访问后端资源,并且不会增加客户端的JavaScript包大小。
+
+\`\`\`jsx
+// app/page.js
+async function getData() {
+ const res = await fetch('https://api.example.com/data')
+ return res.json()
+}
+
+export default async function Page() {
+ const data = await getData()
+ return {data.map(item => {item.title}
)}
+}
+\`\`\`
+
+### 客户端组件
+
+当需要客户端交互时,可以使用客户端组件
+
+\`\`\`jsx
+'use client'
+
+import { useState } from 'react'
+
+export default function Counter() {
+ const [count, setCount] = useState(0)
+ return (
+
+ )
+}
+\`\`\`
+
+## 服务器组件
+
+服务器组件是Next.js 13的另一个重要特性,它允许我们在服务器上渲染React组件,从而提高性能和SEO。
+
+### 优势
+
+1. 减少客户端JavaScript包大小
+2. 直接访问后端资源
+3. 自动代码分割
+4. 改善首次加载性能
+
+### 使用场景
+
+服务器组件特别适合于:
+
+- 需要访问后端资源的组件
+- 不需要客户端交互的静态内容
+- SEO关键的页面内容
+
+\`\`\`jsx
+// app/products/page.js
+async function getProducts() {
+ const res = await fetch('https://api.example.com/products')
+ return res.json()
+}
+
+export default async function ProductsPage() {
+ const products = await getProducts()
+ return (
+
+
Products
+
+ {products.map(product => (
+ - {product.name}
+ ))}
+
+
+ )
+}
+\`\`\`
+
+## 流式渲染
+
+流式渲染允许将页面内容分块传输到客户端,这可以显著改善大型应用的用户体验。
+
+### 实现方式
+
+Next.js 13通过\`loading.js\`文件和React的\`Suspense\`组件支持流式渲染:
+
+\`\`\`jsx
+// app/dashboard/loading.js
+export default function Loading() {
+ return Loading...
+}
+
+// app/dashboard/page.js
+import { Suspense } from 'react'
+import UserProfile from './UserProfile'
+import UserPosts from './UserPosts'
+
+export default function Dashboard() {
+ return (
+
+
Dashboard
+ Loading profile...
}>
+
+
+ Loading posts...}>
+
+
+
+ )
+}
+\`\`\`
+
+## 新的图片组件
+
+Next.js 13引入了新的\`Image\`组件,它提供了更好的性能和用户体验:
+
+\`\`\`jsx
+import Image from 'next/image'
+
+export default function Avatar() {
+ return (
+
+ )
+}
+\`\`\`
+
+新的\`Image\`组件支持:
+
+- 自动图片优化
+- 延迟加载
+- 响应式图片
+- 防止布局偏移
+
+## 字体优化
+
+Next.js 13引入了新的字体系统,它可以自动优化和加载自定义字体:
+
+\`\`\`jsx
+import { Inter } from 'next/font/google'
+
+const inter = Inter({ subsets: ['latin'] })
+
+export default function RootLayout({ children }) {
+ return (
+
+ {children}
+
+ )
+}
+\`\`\`
+
+这个系统可以:
+
+- 自动内联字体CSS
+- 消除布局偏移
+- 预加载关键字体文件
+
+## 从Next.js 12迁移到13
+
+迁移到Next.js 13需要注意以下几点:
+
+1. 创建新的\`app\`目录,逐步迁移路由
+2. 更新\`next/image\`导入为\`next/legacy/image\`
+3. 将客户端组件标记为\`'use client'\`
+4. 更新API路由到新的\`app/api\`目录
+5. 使用新的数据获取方法替代\`getServerSideProps\`和\`getStaticProps\`
+
+## 结论
+
+Next.js 13带来了许多令人兴奋的新特性,这些特性不仅提高了开发效率,还大大改善了应用性能和用户体验。App Router、服务器组件和流式渲染等新特性为我们提供了更灵活、更强大的工具,使得构建现代Web应用变得更加容易。
+
+随着Next.js的不断发展,我们可以期待看到更多令人兴奋的新特性和改进。如果您还没有尝试过Next.js 13,现在是时候了!
+
+## Turbopack - 新的打包工具
+
+Next.js 13引入了Turbopack,这是一个用Rust编写的增量打包工具,旨在替代Webpack。
+
+### Turbopack的主要优势:
+
+1. 更快的启动时间 - 比Webpack快700倍
+2. 更快的更新 - 比Webpack快20倍
+3. 内存效率更高 - 使用的内存比Webpack少少5倍
+
+### 如何启用Turbopack:
+
+在开发模式下,只需添加 --turbo 标志:
+
+\`\`\`bash
+next dev --turbo
+\`\`\`
+
+注意:Turbopack目前仍处于beta阶段,可能存在一些兼容性问题。
+
+## 改进的国际化支持
+
+Next.js 13改进了国际化(i18n)支持,使得创建多语言应用变得更加简单。
+
+### 新的i18n路由
+
+在 \`app\` 目录中,你可以使用以下结构来支持多语言:
+
+\`\`\`
+app/
+ [lang]/
+ page.js
+ layout.js
+ about/
+ page.js
+\`\`\`
+
+### 使用示例:
+
+\`\`\`jsx
+// app/[lang]/layout.js
+export async function generateStaticParams() {
+ return [{ lang: 'en' }, { lang: 'de' }, { lang: 'fr' }]
+}
+
+export default function Layout({ children, params }) {
+ return (
+
+ {children}
+
+ )
+}
+\`\`\`
+
+## 新的Middleware API
+
+Next.js 13引入了新的Middleware API,使得在请求处理过程中进行拦截和修改变得更加容易。
+
+### Middleware的使用场景:
+
+- 认证和授权
+- A/B测试
+- 地理位置基础的内容定制
+- 边缘计算
+
+### 示例:
+
+\`\`\`typescript
+// middleware.ts
+import { NextResponse } from 'next/server'
+import type { NextRequest } from 'next/server'
+
+export function middleware(request: NextRequest) {
+ const country = request.geo?.country || 'US'
+ return NextResponse.rewrite(new URL(\`/\${country}\${request.nextUrl.pathname}\`, request.url))
+}
+
+export const config = {
+ matcher: '/:path*',
+}
+\`\`\`
+
+## 改进的TypeScript支持
+
+Next.js 13进一步增强了对TypeScript的支持,提供了更好的类型推断和更严格的类型检查。
+
+### 主要改进:
+
+1. 自动生成类型定义文件
+2. 改进的路由类型
+3. 更好的API路由类型支持
+
+### 示例:
+
+\`\`\`typescript
+// app/api/user/[id]/route.ts
+import { NextResponse } from 'next/server'
+
+export async function GET(
+ request: Request,
+ { params }: { params: { id: string } }
+) {
+ const id = params.id
+ // 获取用户数据
+ return NextResponse.json({ id, name: 'John Doe' })
+}
+\`\`\`
+
+## 结论
+
+Next.js 13不仅带来了App Router、服务器组件和流式渲染等重大新特性,还在性能优化、开发体验和国际化支持等方面做出了显著改进。Turbopack的引入预示着未来更快的构建速度,而改进的Middleware API和TypeScript支持则为开发者提供了更强大、更灵活的工具。
+
+随着Next.js生态系统的不断发展,我们可以期待看到更多创新和改进。无论你是正在构建新项目还是考虑升级现有应用,Next.js 13都值得你认真考虑和尝试。
+`;
diff --git a/src/data/ts/index.ts b/src/data/ts/index.ts
new file mode 100644
index 0000000..062386e
--- /dev/null
+++ b/src/data/ts/index.ts
@@ -0,0 +1,2 @@
+export * from "./1";
+export * from "./2";
\ No newline at end of file
diff --git a/src/utils/blogHelpers.ts b/src/utils/blogHelpers.ts
index d566710..7b8ccdc 100644
--- a/src/utils/blogHelpers.ts
+++ b/src/utils/blogHelpers.ts
@@ -1,4 +1,4 @@
-import { useMemo } from 'react';
+import { useMemo } from "react";
export function extractHeadings(content: string) {
const headingRegex = /^(#{1,3})\s+(.+)$/gm;
@@ -9,7 +9,7 @@ export function extractHeadings(content: string) {
headings.push({
level: match[1].length,
text: match[2],
- slug: match[2].toLowerCase().replace(/\s+/g, "-"),
+ slug: `${match[2].toLowerCase().replace(/\s+/g, "-")}`,
});
}
@@ -28,4 +28,4 @@ export function useExtractHeadings(content: string) {
export function useEstimateReadingTime(content: string) {
return useMemo(() => estimateReadingTime(content), [content]);
-}
\ No newline at end of file
+}