【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>
    );
}
相关推荐
fmdpenny31 分钟前
Vue3初学之商品的增,删,改功能
开发语言·javascript·vue.js
小美的打工日记44 分钟前
ES6+新特性,var、let 和 const 的区别
前端·javascript·es6
涛ing1 小时前
21. C语言 `typedef`:类型重命名
linux·c语言·开发语言·c++·vscode·算法·visual studio
等一场春雨1 小时前
Java设计模式 十四 行为型模式 (Behavioral Patterns)
java·开发语言·设计模式
涔溪1 小时前
有哪些常见的 Vue 错误?
前端·javascript·vue.js
程序猿online1 小时前
前端jquery 实现文本框输入出现自动补全提示功能
前端·javascript·jquery
黄金小码农1 小时前
C语言二级 2025/1/20 周一
c语言·开发语言·算法
萧若岚2 小时前
Elixir语言的Web开发
开发语言·后端·golang
wave_sky2 小时前
解决使用code命令时的bash: code: command not found问题
开发语言·bash
水银嘻嘻2 小时前
【Mac】Python相关知识经验
开发语言·python·macos