由于自己开发的小工具越来越多,需要一个首页作为索引,以下是一个基于 React、Next.js、Arco Design 和 TypeScript 的目录页工程示例。这个示例将实现卡片形式的链接索引,并支持配置请求链接和卡片内容。 如下图:
以下是完整的工程结构和代码:
- 首先创建项目结构:
lua
directory-page/
├── components/
│ ├── CardItem.tsx
│ └── CardList.tsx
├── pages/
│ ├── index.tsx
│ └── _app.tsx
├── types/
│ └── card.ts
├── config/
│ └── cardConfig.ts
├── styles/
│ └── globals.css
├── package.json
└── tsconfig.json
- 配置 package.json:
json
{
"name": "directory-page",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"@arco-design/web-react": "^2.46.0",
"next": "14.1.0",
"react": "18.2.0",
"react-dom": "18.2.0"
},
"devDependencies": {
"@types/node": "20.11.0",
"@types/react": "18.2.0",
"@types/react-dom": "18.2.0",
"typescript": "5.3.3"
}
}
- 类型定义 (types/card.ts):
typescript
export interface CardItem {
id: string;
title: string;
description: string;
url: string;
apiUrl?: string; // 可选的API请求地址
icon?: string; // 可选的图标
}
- 卡片配置 (config/cardConfig.ts):
typescript
import { CardItem } from '../types/card';
export const cardConfig: CardItem[] = [
{
id: '1',
title: '首页',
description: '网站首页导航',
url: '/',
apiUrl: '/api/home',
icon: 'home',
},
{
id: '2',
title: '产品页面',
description: '查看所有产品信息',
url: '/products',
apiUrl: '/api/products',
icon: 'appstore',
},
// 可以继续添加更多卡片配置
];
- 卡片组件 (components/CardItem.tsx):
typescript
import { Card } from '@arco-design/web-react';
import { IconProps } from '@arco-design/web-react/icon';
import Link from 'next/link';
import { CardItem } from '../types/card';
interface CardItemProps {
item: CardItem;
}
const CardItem: React.FC<CardItemProps> = ({ item }) => {
return (
<Link href={item.url}>
<Card
hoverable
style={{ width: 300, margin: '0 20px 20px 0' }}
title={item.title}
>
<Card.Meta description={item.description} />
{item.apiUrl && (
<div style={{ marginTop: 10 }}>
API: <span style={{ color: '#666' }}>{item.apiUrl}</span>
</div>
)}
</Card>
</Link>
);
};
export default CardItem;
- 卡片列表组件 (components/CardList.tsx):
typescript
import { Grid } from '@arco-design/web-react';
import CardItem from './CardItem';
import { CardItem as CardItemType } from '../types/card';
interface CardListProps {
items: CardItemType[];
}
const Row = Grid.Row;
const Col = Grid.Col;
const CardList: React.FC<CardListProps> = ({ items }) => {
return (
<Row gutter={[20, 20]}>
{items.map((item) => (
<Col key={item.id} span={8}>
<CardItem item={item} />
</Col>
))}
</Row>
);
};
export default CardList;
- 主页面 (pages/index.tsx):
typescript
import { ConfigProvider } from '@arco-design/web-react';
import CardList from '../components/CardList';
import { cardConfig } from '../config/cardConfig';
export default function Home() {
return (
<ConfigProvider>
<div style={{ padding: '20px' }}>
<h1 style={{ marginBottom: '20px' }}>页面目录</h1>
<CardList items={cardConfig} />
</div>
</ConfigProvider>
);
}
- App组件 (pages/_app.tsx):
typescript
import '@arco-design/web-react/dist/css/arco.css';
import '../styles/globals.css';
import type { AppProps } from 'next/app';
function MyApp({ Component, pageProps }: AppProps) {
return <Component {...pageProps} />;
}
export default MyApp;
- 全局样式 (styles/globals.css):
css
body {
margin: 0;
padding: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen,
Ubuntu, Cantarell, 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;
}
- TypeScript 配置 (tsconfig.json):
json
{
"compilerOptions": {
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true,
"baseUrl": "."
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
"exclude": ["node_modules"]
}
使用方法:
- 运行
npm install
安装依赖 - 运行
npm run dev
启动开发服务器 - 在
config/cardConfig.ts
中配置卡片内容,包括:- title: 卡片标题
- description: 卡片描述
- url: 跳转链接
- apiUrl: 可选的API地址
- icon: 可选的图标名称
功能特点:
- 使用 Arco Design 的 Card 组件实现卡片样式
- 支持响应式布局(通过 Grid 系统)
- 可配置化卡片内容(在 cardConfig.ts 中修改)
- TypeScript 类型安全
- Next.js 路由支持
- Hover 效果的卡片交互
在生产环境下部署和运行
1. 构建生产版本
在部署到生产环境之前,需要将项目构建为优化的静态文件和服务器端代码。
操作步骤:
-
确保依赖已安装:
bashnpm install
-
构建项目 : 运行以下命令,Next.js 会生成优化的生产构建文件,通常输出到
.next
目录:bashnpm run build
- 这会编译 TypeScript 代码、优化静态资源并生成服务器端渲染所需的代码。
- 如果有错误(如类型检查失败),会在这一步暴露出来。
-
检查构建结果:
- 构建完成后,查看控制台输出,确保没有错误。
.next
目录会包含生产环境所需的所有文件。
2. 部署方式
Next.js 支持多种部署方式,根据你的需求选择合适的方案:
方式 1:部署到 Vercel(推荐)
Vercel 是 Next.js 的官方推荐部署平台,部署简单且支持自动扩展。
-
安装 Vercel CLI(可选):
bashnpm install -g vercel
-
部署项目: 在项目根目录运行:
bashvercel
- 第一次部署需要登录并配置项目。
- Vercel 会自动检测 Next.js 项目,执行
npm run build
,并部署。
-
运行:
- 部署完成后,Vercel 会提供一个 URL(如
https://your-project.vercel.app
),无需手动运行服务器。 - 支持自动 HTTPS、域名绑定和环境变量配置。
- 部署完成后,Vercel 会提供一个 URL(如
方式 2:部署到自定义服务器(如 Node.js 服务器)
如果你想自己管理服务器,可以使用 Node.js 运行 Next.js 项目。
-
准备服务器:
- 确保服务器已安装 Node.js(推荐 v18.x.x)。
- 将项目文件上传到服务器(包括
package.json
、node_modules
和.next
目录)。
-
启动项目: 在项目根目录运行:
bashnpm run start
-
默认监听
3000
端口。 -
如果需要自定义端口,可以通过环境变量设置:
bashPORT=8080 npm run start
-
-
配置反向代理(可选):
-
使用 Nginx 或 Apache 将请求代理到 Next.js 服务。
-
示例 Nginx 配置: server { listen 80; server_name your-domain.com;
bashlocation / { proxy_pass http://localhost:3000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }
-
方式 3:静态部署(仅限静态站点)
如果你的项目只使用静态页面(没有服务器端渲染或 API 路由),可以导出为静态文件。
-
修改 next.config.js(如果没有就创建一个):
javascriptmodule.exports = { output: 'export', };
-
导出静态文件:
bashnpm run build
-
部署:
- 将生成的
out
目录上传到任何静态文件托管服务(如 Netlify、GitHub Pages、AWS S3)。 - 无需运行服务器,直接访问静态文件即可。
- 将生成的
3. 运行生产环境的最佳实践
为了确保生产环境的稳定性和性能,建议遵循以下实践:
配置环境变量
- 在
.env.production
文件中配置生产环境变量,例如: NEXT_PUBLIC_API_URL=api.yourdomain.com PORT=8080 - Next.js 会自动加载这些变量。
- 对于 Vercel,可以在平台界面上设置环境变量。
使用 PM2 管理进程(自定义服务器)
如果使用 Node.js 服务器,推荐使用 PM2 来管理进程:
-
安装 PM2:
bashnpm install -g pm2
-
启动应用:
bashpm2 start npm --name "next-app" -- run start
-
设置开机自启:
bashpm2 startup pm2 save
日志和监控
- 配置日志输出到文件或监控服务(如 Sentry)。
- 使用
console.log
或自定义日志工具记录关键信息。
HTTPS 和域名
- 在生产环境中始终使用 HTTPS。
- 通过 Nginx、Cloudflare 或 Vercel 配置 SSL 证书。
4. 示例:部署到 Ubuntu 服务器
假设你有一个 Ubuntu 服务器,以下是完整步骤:
-
安装 Node.js:
bashcurl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash - sudo apt-get install -y nodejs
-
传输项目文件: 使用 SCP 或 Git:
bashscp -r ./your-project user@server-ip:/path/to/deploy
-
安装依赖并构建:
bashcd /path/to/deploy npm install npm run build
-
安装并配置 Nginx:
bashsudo apt-get install nginx sudo nano /etc/nginx/sites-available/next-app
添加配置: server { listen 80; server_name your-domain.com;
bashlocation / { proxy_pass http://localhost:3000; proxy_set_header Host $host; } }
启用配置:
bashsudo ln -s /etc/nginx/sites-available/next-app /etc/nginx/sites-enabled sudo systemctl restart nginx
-
启动 Next.js:
bashnpm install -g pm2 pm2 start npm --name "next-app" -- run start
-
访问 : 通过浏览器访问
http://your-domain.com
。
5. 常见问题
- 内存不足:增加服务器内存或配置 swap 空间。
- 端口被占用 :检查并释放端口,或修改
PORT
环境变量。 - 构建失败:检查依赖版本兼容性,确保 Node.js 版本正确。
根据具体需求(简单部署选 Vercel,自定义选 Node.js 服务器),选择适合的方式即可。