【NextJS】Arco Design与Next.js快速上手

vue版本可以转《【VUE】ArcoDesign之自定义主题样式和命名空间》
今儿整个Next.js+Arco+TailwindCSS的组合

安装

需要同时安装 react >= 16.8 和 react-dom >= 16.8

初始化Next.js:

bash 复制代码
pnpx create-next-app@15.0.4
# ----------
What is your project named? .
Would you like to use TypeScript? `Yes`
Would you like to use ESLint? `Yes`
Would you like to use Tailwind CSS? `Yes`
Would you like your code inside a `src/` directory? `No`
Would you like to use App Router? (recommended) `Yes`
Would you like to use Turbopack for `next dev`?  `No`
Would you like to customize the import alias (`@/*` by default)? `No`

初始化arco-design及相关依赖

bash 复制代码
pnpm add @arco-design/web-react

# 按需加载支持(next.js支持webpack,以下选用webpack依赖包实现)
pnpm add -D @arco-plugins/webpack-react

# 后续有自定义主题实现,以下安装相关依赖
pnpm add -D less less-loader postcss-loader style-loader css-loader

完整package.json:

json 复制代码
{
  "name": "next-arco",
  "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.65.0",
    "next": "15.0.4",
    "react": "^19.0.0",
    "react-dom": "^19.0.0"
  },
  "devDependencies": {
    "@arco-plugins/webpack-react": "^1.4.9",
    "@types/node": "^20",
    "@types/react": "^19",
    "@types/react-dom": "^19",
    "css-loader": "^7.1.2",
    "eslint": "^8",
    "eslint-config-next": "15.0.4",
    "less": "^4.2.1",
    "less-loader": "^12.2.0",
    "postcss": "^8",
    "postcss-loader": "^8.1.1",
    "style-loader": "^4.0.0",
    "tailwindcss": "^3.4.1",
    "typescript": "^5"
  }
}

目录结构:

复制代码
|- app
	|- fonts
	|- favicon.ico
	|- globals.css
	|- layout.tsx
	|- page.tsx
|- public
|- .eslintrc.json
|- .gitignore
|- next.config.ts
|- next-env.d.ts
|- package.json
|- pnpm-lock.yaml
|- postcss.config.mjs
|- README.md
|- tailwind.config.ts
|- tsconfig.json

接下来,开整~

开整

Arco Design 整合

typescript 复制代码
// file: ./next.config.ts

import type {NextConfig} from "next";
import type {ArcoDesignPluginOptions} from "@arco-plugins/webpack-react";

import ArcoWebpackPlugin from "@arco-plugins/webpack-react";

// ArcoWebpackPlugin的配置项
// @link https://github.com/arco-design/arco-plugins/blob/main/packages/plugin-webpack-react/README.zh-CN.md
const ArcoOptions: Partial<ArcoDesignPluginOptions> = {
    include: ['app'],
    removeFontFace: true,
    modifyVars: {
        prefix: 'CustomPrefixName'
    },
};

// next.js的配置项
const nextConfig: NextConfig = {
    /* config options here */
    // @link https://nextjs.org/docs/app/api-reference/next-config-js/transpilePackages
    transpilePackages: [
        '@arco-design/web-react'
    ],
    // 由webpack来配置载入@arco-plugins/webpack-react扩展
    // @link https://nextjs.org/docs/app/api-reference/next-config-js/webpack
    webpack: (config) => {
        config.module.rules.push({
            test: /\.css$/,
            use: [{loader: 'css-loader'}]
        });
        config.module.rules.push({
            test: /\.less$/,
            use: [
                {loader: 'style-loader'},
                {loader: 'css-loader'},
                // 下面两个顺序要注意
                {loader: "postcss-loader"},
                {loader: 'less-loader', options: {lessOptions: {modifyVars: {}}}}
            ]
        })
        config.plugins.push(new ArcoWebpackPlugin(ArcoOptions));
        return config;
    }
};

export default nextConfig;

应用

实现目标:arco - 全局设置各组件默认配置

先对项目结构做点小调整

bash 复制代码
|- app
	# ..
	|- globals.css # => 移动:/layouts/default/styles/globals.less
	# ..
|- layouts
	|- default
		|- styles
			|- globals.less
			|- theme.ts
		|- index.tsx
		|- types.d.ts

现在有了个默认布局组件了,开始填代码

typescript 复制代码
// file: /layouts/default/types.d.ts
import type {ReactNode} from "react";

export interface DefaultLayoutProps {
    children: ReactNode;
}
typescript 复制代码
// file: /layouts/default/styles/theme.ts
import type {ConfigProviderProps} from "@arco-design/web-react";

export const prefixCls = 'CustomPrefixName';
export const componentConfig: ConfigProviderProps["componentConfig"] = {
    Button: {
        type: 'primary',
        shape: 'round',
    },
    DatePicker: {
        dayStartOfWeek: 2,
        utcOffset: 0,
    },
    InputNumber: {
        mode: 'button',
    },
    'Radio.Group': {
        type: 'button',
    },
    Space: {
        size: 'large',
    },
    Table: {
        border: false,
        noDataElement: 'Oops, no data ~',
    },
    Tag: {
        color: 'arcoblue',
        size: 'large',
    },
};


export default {
    prefixCls,
    componentConfig
}
typescript 复制代码
// file: /layouts/default/index.tsx
"use client";

import type {DefaultLayoutProps as Props} from "./types";
import {ConfigProvider} from "@arco-design/web-react";

import theme from "./styles/theme";
import "./styles/globals.less";

const DefaultLayout = function (props: Readonly<Props>) {
    const {children} = props;

    return (
        <ConfigProvider prefixCls={theme.prefixCls}
                        componentConfig={theme.componentConfig}>
            {children}
        </ConfigProvider>
    )
}

export default DefaultLayout;

可选 以下部分是样式文件(主要验证TailwindCSS的整合情况)

typescript 复制代码
// file: /layouts/default/styles/globals.less
@tailwind base;
@tailwind components;
@tailwind utilities;

:root {
    --font-family: Verdana, Geneva, Tahoma, sans-serif;
}

html {
    font-family: var(--font-family);
}

接下来回到app目录,完成最后收尾:

typescript 复制代码
// file: /app/layout.tsx
import type {ReactNode} from "react";
import type {Metadata} from "next";

// 载入默认布局组件
import DefaultLayout from "@/layouts/default"

export const metadata: Metadata = {
    title: "Create Next App",
    description: "Generated by create next app",
};

export default function RootLayout({
                                       children,
                                   }: Readonly<{
    children: ReactNode;
}>) {
    return (
        <html lang="en">
        <body>
        <DefaultLayout>
            {children}
        </DefaultLayout>
        </body>
        </html>
    );
}
typescript 复制代码
// file: /app/page.tsx

"use client";

import {
    Button,
    DatePicker,
    Space,
    InputNumber,
    Radio,
    Table,
    Tag,
} from '@arco-design/web-react';

const columns = [
    {
        title: 'Name',
        dataIndex: 'name',
    },
    {
        title: 'Salary',
        dataIndex: 'salary',
    },
    {
        title: 'Address',
        dataIndex: 'address',
    },
    {
        title: 'Email',
        dataIndex: 'email',
    },
];

export default function Home() {

    return (
        <div className={"w-fit mt-20 mx-auto"}>
            <Space direction='vertical'>
                <Space>
                    <Button>Button 1</Button>
                    <Button status={'success'}>Button 2</Button>
                    <Button type={'secondary'}>Button 2</Button>
                </Space>
                <Space>
                    <Radio.Group options={['JavaScript', 'CSS', 'React', 'Vue']} defaultValue='JavaScript'/>
                    <Radio.Group options={['Light', 'Dark']} defaultValue='Light'/>
                </Space>
                <Space>
                    <DatePicker showTime/>
                    <DatePicker.RangePicker/>
                </Space>
                <Space>
                    <InputNumber defaultValue={2}/>
                    <InputNumber defaultValue={3}/>
                </Space>
                <Space>
                    <Tag>ArcoDesign</Tag>
                    <Tag>Design System</Tag>
                    <Tag>Component</Tag>
                    <Tag>Design Lab</Tag>
                </Space>
                <Table columns={columns} data={[]}/>
            </Space>
        </div>
    );
}
相关推荐
phltxy42 分钟前
从零入门JavaScript:基础语法全解析
开发语言·javascript
Kagol1 小时前
JavaScript 中的 sort 排序问题
前端·javascript
天“码”行空1 小时前
java面向对象的三大特性之一多态
java·开发语言·jvm
cos2 小时前
Fork 主题如何更新?基于 Ink 构建主题更新 CLI 工具
前端·javascript·git
odoo中国2 小时前
Odoo 19 模块结构概述
开发语言·python·module·odoo·核心组件·py文件按
代码N年归来仍是新手村成员3 小时前
【Java转Go】即时通信系统代码分析(一)基础Server 构建
java·开发语言·golang
Z1Jxxx3 小时前
01序列01序列
开发语言·c++·算法
摸鱼的春哥4 小时前
AI编排实战:用 n8n + DeepSeek + Groq 打造全自动视频洗稿流水线
前端·javascript·后端
沐知全栈开发4 小时前
C语言中的强制类型转换
开发语言
关于不上作者榜就原神启动那件事4 小时前
Java中大量数据Excel导入导出的实现方案
java·开发语言·excel