大家好啊,书接上文,Next.js 就是一坨,为此我把手里一个比较大的项目给迁移到了 Vite,整体迁移过程非常简单,不过一些比较机械的动作我交给了 AI,AI 还是好用啊🤤
首先,需要评估项目中使用的 Next.js 特性:
可以迁移的特性:
- 客户端渲染(CSR)
- 静态页面
- 路由系统
- API 代理
需要替代方案的特性:
- 服务端渲染(SSR)→ 考虑使用 Vite SSR 插件或 Remix
- API Routes → 迁移到独立后端或使用 Vite 代理
- 图片优化(next/image)→ 使用 Vite 插件或第三方服务
- 自动代码分割 → 使用 React.lazy() 和动态导入
这里我使用的是 App Router,所以迁移过去有点麻烦,重复的动作太多,Next.js 有两种路由,一种是 App Router 一种是 Pages Router,Vite 想要实现路由得安装 react-router 或者别的模块,装了后如下进行配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| import { Routes, Route, Navigate } from 'react-router-dom' import { Suspense, lazy } from 'react' import Loading from './components/Loading'
const Home = lazy(() => import('./pages/home')) const About = lazy(() => import('./pages/about')) const PostDetail = lazy(() => import('./pages/posts/[id]'))
export default function Router() { return ( <Suspense fallback={<Loading />}> <Routes> <Route path="/" element={<Home />} /> <Route path="/about" element={<About />} /> <Route path="/posts/:id" element={<PostDetail />} /> <Route path="*" element={<Navigate to="/" replace />} /> </Routes> </Suspense> ) }
|
然后就是动态参数获取
Next.js:
1 2 3 4 5 6
| import { useRouter } from 'next/router'
export default function PostPage() { const router = useRouter() const { id } = router.query }
|
Vite + React Router:
1 2 3 4 5
| import { useParams } from 'react-router-dom'
export default function PostPage() { const { id } = useParams<{ id: string }>() }
|
接着就是导航方式,Next.js 的 link 必须用 <Link> 来进行包裹,迁移到别的项目后你想用 <a> 或者别的都可以
Next.js:
1 2 3 4 5
| import Link from 'next/link' import { useRouter } from 'next/router'
<Link href="/about">About</Link> router.push('/about')
|
Vite + React Router:
1 2 3 4 5
| import { Link, useNavigate } from 'react-router-dom'
<Link to="/about">About</Link> const navigate = useNavigate() navigate('/about')
|
环境变量迁移很简单,直接照搬即可
Next.js:
1 2 3 4 5
| NEXT_PUBLIC_API_URL=https:
const apiUrl = process.env.NEXT_PUBLIC_API_URL
|
Vite:
1 2 3 4 5
| VITE_API_URL=https:
const apiUrl = import.meta.env.VITE_API_URL
|
Next.js 的静态资源,官方说使用 <Image> 这个标签能最大化的利用图片、压缩图片啥的,不过用了也就那样,没啥鸟用
Next.js:
1 2
| import Image from 'next/image' <Image src="/photo.jpg" width={500} height={300} alt="Photo" />
|
Vite:
1 2 3 4
| <img src="/photo.jpg" alt="Photo" className="w-[500px] h-[300px]" />
|
如果你的项目用到了SSR,则可以考虑Vite 的 SSR https://cn.vite.dev/guide/ssr:
1 2 3 4 5 6 7 8 9 10
| import { defineConfig } from 'vite' import react from '@vitejs/plugin-react'
export default defineConfig({ plugins: [react()], ssr: { noExternal: ['react', 'react-dom'], }, })
|