跳转到内容

Next.js Emotion

来自代码酷
Admin留言 | 贡献2025年5月1日 (四) 23:14的版本 (Page creation by admin bot)

(差异) ←上一版本 | 已核准修订 (差异) | 最后版本 (差异) | 下一版本→ (差异)

Next.js Emotion[编辑 | 编辑源代码]

Next.js Emotion 是一种在 Next.js 框架中使用的 CSS-in-JS 样式解决方案,它结合了 Emotion 库的强大功能和 Next.js 的服务端渲染(SSR)及静态生成(SSG)能力。Emotion 提供了高性能的样式编写方式,支持动态样式、主题切换和组件化 CSS,同时保持优秀的开发体验。

介绍[编辑 | 编辑源代码]

Emotion 是一个流行的 CSS-in-JS 库,允许开发者直接在 JavaScript 或 TypeScript 中编写样式。在 Next.js 中集成 Emotion,可以充分利用其 SSR 和 SSG 优化能力,同时享受 Emotion 的灵活性和性能优势。

Emotion 的主要特点包括:

  • 支持静态提取 CSS,减少运行时开销
  • 提供 `css` prop 和 `styled` API 两种主要使用方式
  • 支持嵌套选择器、伪类和媒体查询
  • 内置自动厂商前缀和源映射支持
  • 与 React 组件深度集成

安装与配置[编辑 | 编辑源代码]

要在 Next.js 项目中使用 Emotion,首先需要安装必要的依赖:

npm install @emotion/react @emotion/styled
# 或
yarn add @emotion/react @emotion/styled

对于 TypeScript 用户,还需要安装类型定义:

npm install --save-dev @types/emotion__react @types/emotion__styled

基本用法[编辑 | 编辑源代码]

Emotion 在 Next.js 中有两种主要使用方式:通过 `css` prop 和 `styled` API。

使用 css prop[编辑 | 编辑源代码]

/** @jsxImportSource @emotion/react */
import { css } from '@emotion/react'

function MyComponent() {
  return (
    <div
      css={css`
        background-color: hotpink;
        &:hover {
          color: white;
        }
      `}
    >
      This has a hotpink background.
    </div>
  )
}

使用 styled API[编辑 | 编辑源代码]

import styled from '@emotion/styled'

const Button = styled.button`
  background: transparent;
  border-radius: 3px;
  border: 2px solid palevioletred;
  color: palevioletred;
  margin: 0.5em 1em;
  padding: 0.25em 1em;

  &:hover {
    background-color: palevioletred;
    color: white;
  }
`

function MyComponent() {
  return <Button>Styled Button</Button>
}

高级特性[编辑 | 编辑源代码]

主题支持[编辑 | 编辑源代码]

Emotion 提供了完整的主题支持,可以通过 `ThemeProvider` 在整个应用中共享主题变量:

import { ThemeProvider } from '@emotion/react'

const theme = {
  colors: {
    primary: 'hotpink',
    secondary: 'blue'
  }
}

function App() {
  return (
    <ThemeProvider theme={theme}>
      <MyComponent />
    </ThemeProvider>
  )
}

在组件中使用主题:

import { useTheme } from '@emotion/react'

function ThemedComponent() {
  const theme = useTheme()
  return (
    <div css={{ color: theme.colors.primary }}>
      This text uses the primary color from theme
    </div>
  )
}

服务端渲染[编辑 | 编辑源代码]

Next.js 与 Emotion 的 SSR 集成需要额外配置。在 `_document.js` 中添加:

import Document, { Head, Html, Main, NextScript } from 'next/document'
import { extractCritical } from '@emotion/server'

export default class MyDocument extends Document {
  static async getInitialProps(ctx) {
    const initialProps = await Document.getInitialProps(ctx)
    const styles = extractCritical(initialProps.html)
    return {
      ...initialProps,
      styles: (
        <>
          {initialProps.styles}
          <style
            data-emotion-css={styles.ids.join(' ')}
            dangerouslySetInnerHTML={{ __html: styles.css }}
          />
        </>
      )
    }
  }

  render() {
    return (
      <Html lang="en">
        <Head />
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    )
  }
}

性能优化[编辑 | 编辑源代码]

Emotion 在 Next.js 中提供了多种性能优化选项:

1. 静态提取:通过 Babel 插件提取静态 CSS 2. 缓存:利用 Emotion 的缓存机制减少重复样式计算 3. 关键 CSS:使用 `extractCritical` 只发送渲染首屏所需样式

实际应用案例[编辑 | 编辑源代码]

以下是一个完整的 Next.js 页面组件示例,展示了 Emotion 的实际应用:

/** @jsxImportSource @emotion/react */
import { css } from '@emotion/react'
import styled from '@emotion/styled'

const Container = styled.div`
  max-width: 1200px;
  margin: 0 auto;
  padding: 20px;
`

const Title = styled.h1`
  color: ${props => props.theme.colors.primary};
  text-align: center;
`

function HomePage() {
  return (
    <Container>
      <Title>Welcome to Next.js with Emotion</Title>
      <div css={css`
        display: grid;
        grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
        gap: 20px;
      `}>
        {[1, 2, 3].map(item => (
          <div key={item} css={{
            padding: '20px',
            border: '1px solid #ddd',
            borderRadius: '4px'
          }}>
            Card {item}
          </div>
        ))}
      </div>
    </Container>
  )
}

export default HomePage

与其他样式方案比较[编辑 | 编辑源代码]

特性 Emotion CSS Modules Styled JSX Tailwind CSS
SSR 支持 ✔️ ✔️ ✔️ ✔️
动态样式 ✔️ 部分 部分
主题支持 ✔️ 通过配置
学习曲线 中等 中等
运行时大小 中等

最佳实践[编辑 | 编辑源代码]

1. 对于可重用组件,优先使用 `styled` API 2. 对于一次性样式,使用 `css` prop 3. 合理组织主题变量,避免硬编码颜色和尺寸 4. 利用 Emotion 的 `@emotion/babel-plugin` 进行编译时优化 5. 在大型项目中,考虑将样式与组件分离到单独文件中

常见问题[编辑 | 编辑源代码]

为什么需要 @jsxImportSource 注释?[编辑 | 编辑源代码]

这是为了告诉 Babel 使用 Emotion 的 JSX 转换而不是 React 的默认转换。在 Next.js 中,也可以通过修改 Babel 配置来全局设置。

如何禁用 Emotion 的开发样式标签?[编辑 | 编辑源代码]

在生产环境中,Emotion 会自动使用更高效的样式标签。如果需要手动控制,可以设置:

import { CacheProvider } from '@emotion/react'
import createCache from '@emotion/cache'

const cache = createCache({
  key: 'my-prefix',
  speedy: process.env.NODE_ENV === 'production'
})

function App() {
  return (
    <CacheProvider value={cache}>
      {/* 你的应用 */}
    </CacheProvider>
  )
}

总结[编辑 | 编辑源代码]

Next.js Emotion 提供了强大而灵活的样式解决方案,特别适合需要动态样式、主题支持和 SSR 优化的项目。通过合理使用 Emotion 的各种特性,开发者可以创建高性能、可维护的样式系统,同时享受优秀的开发体验。