Carbon 设计系统集成 Next.js 示例:App Router、SCSS 主题与 @carbon/react 的完整落地指南
2026/9/16 13:37:30 网站建设 项目流程

Carbon 设计系统集成 Next.js 示例:App Router、SCSS 主题与 @carbon/react 的完整落地指南

【免费下载链接】carbonA design system built by IBM项目地址: https://gitcode.com/GitHub_Trending/carbo/carbon

Carbon 仓库的examples/nextjs目录提供了一个将 Carbon 设计系统接入 Next.js 应用的完整示例工程。本篇以 examples/nextjs/README.md 为主线,完整还原“先构建 monorepo、再运行示例”的标准工作流,并结合该示例的真实源码(next.config.js、package.json、src/app/layout.js、src/scss/styles.scss)逐文件剖析依赖版本、构建配置、全局 SCSS 引入方式与暗色主题切换机制,帮助读者掌握 Carbon 在 Next.js App Router 项目中的可复制集成方案。

示例工程的文件结构

在展开运行步骤前,先明确示例目录的组成,后文的配置分析均基于这些真实文件:

  • examples/nextjs/next.config.js—— Next.js 构建配置(strict mode、Turbopack、Sass 选项);
  • examples/nextjs/package.json—— 声明@carbon/reactnextreact等依赖与dev/build/start脚本;
  • examples/nextjs/src/app/layout.js—— App Router 根布局,负责引入全局 SCSS 与页面元数据;
  • examples/nextjs/src/app/page.js—— 首页客户端组件,演示引入 Carbon React 组件;
  • examples/nextjs/src/scss/styles.scss—— 全局样式入口,串联 Carbon 的 reset、grid、layer、themes、theme 与组件样式;
  • examples/nextjs/public/—— 静态资源(favicon、vercel.svg)。

运行步骤:先构建 monorepo,再启动示例

README 给出的启动流程分两步,且强调了执行顺序——必须先在 carbon 仓库根目录完成构建,再进入示例目录启动开发服务器:

# 第一步:在 carbon 仓库根目录 yarn install && yarn build

这一步会触发仓库根 package.json 中的build脚本,其定义是lerna run build --stream --prefix && node tasks/generate-repo-structure.mjs,即通过 Lerna 依次构建packages/*下的所有工作区包(@carbon/reactlib/产物与 scss 入口即在此阶段就绪)。根 package.json 同时声明了engines.node >= 20.xpackageManager: yarn@4.10.3,即该示例依赖的环境前提为 Node 20+ 与 Yarn 4。

# 第二步:进入示例目录 cd examples/nextjs yarn install # or npm install yarn dev # or npm run dev

dev脚本对应 package.json 中的next dev。启动后,README 提示在浏览器打开本地地址查看结果(文档写的是http://localhost:5173);需要注意的是 Next.js 开发服务器默认监听 3000 端口,README 后文的 API 路由说明(http://localhost:3000/api/hello)也印证了 3000 才是实际端口,请以next dev终端输出的地址为准。

此外 README 说明开发时修改页面文件即可热更新,页面会随编辑自动刷新;pages/api目录会被映射为/api/*路由。需要指出的是,从当前源码结构看,该示例已迁移到App Routersrc/app/目录),页面入口实际是 src/app/page.js 与 src/app/layout.js,README 中pages/index.js的描述属于 create-next-app 模板沿袭下来的旧表述,实际开发请以src/app下的文件为准。

依赖清单:示例锁定了哪些版本

package.json 是最小化但完整的依赖声明,关键版本如下:

依赖版本角色
@carbon/react^1.104.0-rc.0Carbon 的 React 组件库,提供Button等组件与@carbon/react/scss/*样式入口
next^16.2.11Next.js 16,启用 App Router 与 Turbopack
react/react-dom^19.2.5React 19
sass(devDependency)^1.93.2编译全局 SCSS 所需的 Sass 编译器

依赖脚本为buildnext build)、devnext dev)、startnext start)三个标准命令。值得注意的是sass被放在 devDependencies:示例直接编译 SCSS 源文件(而非引用预编译 CSS),因此构建链中必须有 Sass。

构建配置解读:next.config.js 的三个关键点

next.config.js 全文如下:

/** @type {import('next').NextConfig} */ const nextConfig = { reactStrictMode: true, turbopack: { root: __dirname, }, sassOptions: { quietDeps: true, }, }; module.exports = nextConfig;

三个配置项对 Carbon 集成各有实质意义:

  1. reactStrictMode: true:在开发模式下对组件做双渲染检查,提前暴露副作用与状态更新问题,对大量受控组件(表单类控件)的 Carbon 组件库尤为必要;
  2. turbopack.root: __dirname:显式将构建根目录锚定到示例目录本身。在 carbon 这样的 monorepo 中,Next.js 向上查找时可能误判项目根,该配置保证 Turbopack 不会越过示例目录去解析上层工作区;
  3. sassOptions.quietDeps: true:抑制来自依赖包(node_modules 中的@carbon/reactSCSS)的废弃警告与冗余输出,保持终端日志干净。同仓库的 examples/light-dark-mode/next.config.js 使用了完全一致的sassOptions.quietDeps: true配置,说明这是 Carbon 官方示例在 Next.js 中处理 Sass 依赖警告的统一做法。

全局样式入口:layout.js 如何接入 Carbon SCSS

src/app/layout.js 是整个示例与 Carbon 样式体系的连接点:

import '../scss/styles.scss'; export const metadata = { title: 'Create Next App', description: 'Generated by create next app', }; export default function RootLayout({ children }) { return ( <html lang="en"> <head> <link rel="icon" href="/favicon.ico" /> </head> <body>{children}</body> </html> ); }

这里通过相对路径import '../scss/styles.scss'把全局 SCSS 挂到根布局上。App Router 的根布局会在每次导航时保持挂载,因此全局样式只需引入一次即可作用于所有页面——这是 Next.js 中引入全局(非模块化)样式的标准位置。

SCSS 集成方案:styles.scss 逐行解析

src/scss/styles.scss 展示了 Carbon v12 样式体系的最小引入集:

@use '@carbon/react/scss/reset'; @use '@carbon/react/scss/grid'; @use '@carbon/react/scss/layer'; @use '@carbon/react/scss/themes'; @use '@carbon/react/scss/theme'; @use '@carbon/react/scss/components/button'; body { background: theme.$background; color: theme.$text-primary; } @media (prefers-color-scheme: dark) { :root { @include theme.theme(themes.$g100); } }

每个@use都有明确职责,可按需增删:

  • reset:浏览器样式重置,保证 Carbon 组件基线一致;
  • grid:布局网格系统(packages/react/scss/grid/下包含_css-grid.scss_flexbox.scss等模块);
  • layer:层级/遮罩(layer)体系,是 Tooltip、Modal、Tearsheet 等浮层组件的基础;
  • themes/theme:主题令牌(token)与主题混入。theme.$backgroundtheme.$text-primary这类变量来自主题令牌;
  • components/button:只引入当前用到的Button组件样式,体现“按组件按需加载样式”的思路——用到哪个组件就@use对应条目。

最后一段媒体查询是该示例的点睛之笔:在用户系统偏好暗色模式时,通过@include theme.theme(themes.$g100)将 Carbon 灰阶 100 暗色主题注入:root,实现零 JS 的跟随系统暗色切换g100为 Carbon 白/黑双主题对中的暗色侧)。这与同仓库 examples/light-dark-mode 示例的方向一致,可作为暗色主题接入的参考起点。

从源码结构看,@carbon/react/scss/下的_theme.scss_themes.scss等文件是构建期生成的转发桩,例如 packages/react/scss/_theme.scss 的内容只有一行@forward '@carbon/styles/scss/theme',即样式实现的单一真源在@carbon/styles包,@carbon/react提供的是面向 React 场景的再导出入口。理解这一点后,排查样式问题时可直接对照@carbon/styles的源文件。

组件使用:page.js 中的第一个 Carbon 组件

src/app/page.js 演示了在 App Router 页面中使用 Carbon React 组件:

'use client'; import React from 'react'; import { Button } from '@carbon/react'; import Image from 'next/image'; import styles from '../scss/Home.module.css'; export default function Home() { return ( <div className={styles.container}> <main className={styles.main}> <h1 className={styles.title}> Welcome to <a href="https://nextjs.org">Next.js!</a> </h1> <p className={styles.description}> <Button>Hello world</Button> </p> </main> {/* footer 省略 */} </div> ); }

三个要点:

  1. 'use client'指令:页面使用了交互式 React 组件(Button带有点击态),因此声明为客户端组件;
  2. 组件按需引入import { Button } from '@carbon/react'只取所需组件,与 SCSS 侧“只@usebutton 组件样式”的策略相互呼应;
  3. 两种样式体系共存:页面局部布局用 CSS Modules(Home.module.css),全局基线用 Carbon SCSS,二者互不干扰。

小结与延伸

该示例以不到十个文件演示了 Carbon 接入 Next.js 的完整闭环:根 monorepo 先行构建(yarn install && yarn build)→ 示例目录独立安装与next dev启动 →next.config.jsreactStrictMode+turbopack.root+sassOptions.quietDeps三件套 → 根布局引入全局 SCSS →styles.scss按模块@usereset/grid/layer/themes/theme 与组件样式 → 页面中以'use client'组件消费@carbon/react。在此基础上,还可以继续阅读同目录群中 examples/light-dark-mode(Next.js 亮暗双主题)、examples/custom-theme(Vite 定制主题)以及 docs/guide 下的主题与版本文档,进一步扩展主题定制能力。

【免费下载链接】carbonA design system built by IBM项目地址: https://gitcode.com/GitHub_Trending/carbo/carbon

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询