一个基于next实现的基础索引页

由于自己开发的小工具越来越多,需要一个首页作为索引,以下是一个基于 React、Next.js、Arco Design 和 TypeScript 的目录页工程示例。这个示例将实现卡片形式的链接索引,并支持配置请求链接和卡片内容。 如下图:

以下是完整的工程结构和代码:

  1. 首先创建项目结构:
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
  1. 配置 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"
  }
}
  1. 类型定义 (types/card.ts):
typescript 复制代码
export interface CardItem {
  id: string;
  title: string;
  description: string;
  url: string;
  apiUrl?: string; // 可选的API请求地址
  icon?: string;   // 可选的图标
}
  1. 卡片配置 (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',
  },
  // 可以继续添加更多卡片配置
];
  1. 卡片组件 (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;
  1. 卡片列表组件 (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;
  1. 主页面 (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>
  );
}
  1. 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;
  1. 全局样式 (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;
}
  1. 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"]
}

使用方法:

  1. 运行 npm install 安装依赖
  2. 运行 npm run dev 启动开发服务器
  3. config/cardConfig.ts 中配置卡片内容,包括:
    • title: 卡片标题
    • description: 卡片描述
    • url: 跳转链接
    • apiUrl: 可选的API地址
    • icon: 可选的图标名称

功能特点:

  • 使用 Arco Design 的 Card 组件实现卡片样式
  • 支持响应式布局(通过 Grid 系统)
  • 可配置化卡片内容(在 cardConfig.ts 中修改)
  • TypeScript 类型安全
  • Next.js 路由支持
  • Hover 效果的卡片交互

在生产环境下部署和运行


1. 构建生产版本

在部署到生产环境之前,需要将项目构建为优化的静态文件和服务器端代码。

操作步骤:

  1. 确保依赖已安装

    bash 复制代码
    npm install
  2. 构建项目 : 运行以下命令,Next.js 会生成优化的生产构建文件,通常输出到 .next 目录:

    bash 复制代码
    npm run build
    • 这会编译 TypeScript 代码、优化静态资源并生成服务器端渲染所需的代码。
    • 如果有错误(如类型检查失败),会在这一步暴露出来。
  3. 检查构建结果

    • 构建完成后,查看控制台输出,确保没有错误。
    • .next 目录会包含生产环境所需的所有文件。

2. 部署方式

Next.js 支持多种部署方式,根据你的需求选择合适的方案:

方式 1:部署到 Vercel(推荐)

Vercel 是 Next.js 的官方推荐部署平台,部署简单且支持自动扩展。

  1. 安装 Vercel CLI(可选)

    bash 复制代码
    npm install -g vercel
  2. 部署项目: 在项目根目录运行:

    bash 复制代码
    vercel
    • 第一次部署需要登录并配置项目。
    • Vercel 会自动检测 Next.js 项目,执行 npm run build,并部署。
  3. 运行

    • 部署完成后,Vercel 会提供一个 URL(如 https://your-project.vercel.app),无需手动运行服务器。
    • 支持自动 HTTPS、域名绑定和环境变量配置。

方式 2:部署到自定义服务器(如 Node.js 服务器)

如果你想自己管理服务器,可以使用 Node.js 运行 Next.js 项目。

  1. 准备服务器

    • 确保服务器已安装 Node.js(推荐 v18.x.x)。
    • 将项目文件上传到服务器(包括 package.jsonnode_modules.next 目录)。
  2. 启动项目: 在项目根目录运行:

    bash 复制代码
    npm run start
    • 默认监听 3000 端口。

    • 如果需要自定义端口,可以通过环境变量设置:

      bash 复制代码
      PORT=8080 npm run start
  3. 配置反向代理(可选)

    • 使用 Nginx 或 Apache 将请求代理到 Next.js 服务。

    • 示例 Nginx 配置: server { listen 80; server_name your-domain.com;

      bash 复制代码
          location / {
              proxy_pass http://localhost:3000;
              proxy_set_header Host $host;
              proxy_set_header X-Real-IP $remote_addr;
          }
      }

方式 3:静态部署(仅限静态站点)

如果你的项目只使用静态页面(没有服务器端渲染或 API 路由),可以导出为静态文件。

  1. 修改 next.config.js(如果没有就创建一个):

    javascript 复制代码
    module.exports = {
      output: 'export',
    };
  2. 导出静态文件

    bash 复制代码
    npm run build
  3. 部署

    • 将生成的 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 来管理进程:

  1. 安装 PM2:

    bash 复制代码
    npm install -g pm2
  2. 启动应用:

    bash 复制代码
    pm2 start npm --name "next-app" -- run start
  3. 设置开机自启:

    bash 复制代码
    pm2 startup
    pm2 save

日志和监控

  • 配置日志输出到文件或监控服务(如 Sentry)。
  • 使用 console.log 或自定义日志工具记录关键信息。

HTTPS 和域名

  • 在生产环境中始终使用 HTTPS。
  • 通过 Nginx、Cloudflare 或 Vercel 配置 SSL 证书。

4. 示例:部署到 Ubuntu 服务器

假设你有一个 Ubuntu 服务器,以下是完整步骤:

  1. 安装 Node.js

    bash 复制代码
    curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
    sudo apt-get install -y nodejs
  2. 传输项目文件: 使用 SCP 或 Git:

    bash 复制代码
    scp -r ./your-project user@server-ip:/path/to/deploy
  3. 安装依赖并构建

    bash 复制代码
    cd /path/to/deploy
    npm install
    npm run build
  4. 安装并配置 Nginx

    bash 复制代码
    sudo apt-get install nginx
    sudo nano /etc/nginx/sites-available/next-app

    添加配置: server { listen 80; server_name your-domain.com;

    bash 复制代码
        location / {
            proxy_pass http://localhost:3000;
            proxy_set_header Host $host;
        }
    }

    启用配置:

    bash 复制代码
    sudo ln -s /etc/nginx/sites-available/next-app /etc/nginx/sites-enabled
    sudo systemctl restart nginx
  5. 启动 Next.js

    bash 复制代码
    npm install -g pm2
    pm2 start npm --name "next-app" -- run start
  6. 访问 : 通过浏览器访问 http://your-domain.com


5. 常见问题

  • 内存不足:增加服务器内存或配置 swap 空间。
  • 端口被占用 :检查并释放端口,或修改 PORT 环境变量。
  • 构建失败:检查依赖版本兼容性,确保 Node.js 版本正确。

根据具体需求(简单部署选 Vercel,自定义选 Node.js 服务器),选择适合的方式即可。

相关推荐
加班是不可能的,除非双倍日工资3 小时前
css预编译器实现星空背景图
前端·css·vue3
wyiyiyi4 小时前
【Web后端】Django、flask及其场景——以构建系统原型为例
前端·数据库·后端·python·django·flask
gnip4 小时前
vite和webpack打包结构控制
前端·javascript
excel4 小时前
在二维 Canvas 中模拟三角形绕 X、Y 轴旋转
前端
阿华的代码王国5 小时前
【Android】RecyclerView复用CheckBox的异常状态
android·xml·java·前端·后端
一条上岸小咸鱼5 小时前
Kotlin 基本数据类型(三):Booleans、Characters
android·前端·kotlin
Jimmy5 小时前
AI 代理是什么,其有助于我们实现更智能编程
前端·后端·ai编程
ZXT5 小时前
promise & async await总结
前端
Jerry说前后端5 小时前
RecyclerView 性能优化:从原理到实践的深度优化方案
android·前端·性能优化
画个太阳作晴天5 小时前
A12预装app
linux·服务器·前端