@bem-react/core

中文文档
6.1.1发布于 2026/08/18MPL-2.0TypeScriptESM + CJS近 30 天下载 3485

BEM 反应核心

中文使用文档
文档目录6 节
  1. 安装
  2. 使用量
  3. 使用再出口来改进DX
  4. 优化. 懒惰负载为修饰剂.
  5. 简单修改器( 仅属于 CSS 类)
  6. 调试

@ bem- react/ core # # # 时间轴 npm (scoped) npm bundle size (minified + gzip)

核心软件包帮助组织和管理组件 BEM 修改器 在反应.

安装

npm i -S @bem-react/core

使用量

例如,您有一个初始的 App 文件结构如下:

App.tsx
Components/
  Button/
    Button.tsx

你需要设置两种可选的按钮类型,这些按钮不同于 Button.tsx。 。 。 . (在我们的例子中,这些将是主题"动作"和类型"link"的按钮)

你可以处理那些使用 @ bem- react/ core (英语)。 。 。 .

随入向导.

步骤1.

在你身边 Components/Button/index.tsx,您定义了按钮可以在延伸的界面中获取的道具类型 分类Name 从“ @ bem- react/ core” 开始 :

import { ReactType } from 'react'
import { IClassNameProps } from '@bem-react/core'
import { cn } from '@bem-react/classname'

export interface IButtonProps extends IClassNameProps {
  as?: ReactType
}

export const cnButton = cn('Button')

步骤二.

设置 基本按钮 如果 无修改符 道具设置在母组件中. 在你体内 Components/Button/Button.tsx数字 :

import React, { FC } from 'react'

import { IButtonProps, cnButton } from './index'

export const Button: FC<IButtonProps> = ({
  children,
  className,
  as: Component = 'button',
  ...props
}) => (
  <Component {...props} className={cnButton({}, [className])}>
    {children}
  </Component>
)

步骤3.

设置 带有按钮TypeLink的选项 财务报告和审定财务报表 按钮主题动作选项 如果 {type: 'link'} 和(或) {theme: 'action'} 修改器分别设置在母组件中. 在你体内 Components/Button/ 您添加文件夹 _type/ 与 Button_type_link.tsx 文件中的文件和 _theme/ 与 Button_theme_action.tsx 。 。 。 .

App.tsx
Components/
  Button/
    Button.tsx
    index.tsx
+   _type/
+     Button_type_link.tsx
+   _theme/
+     Button_theme_action.tsx

设置变体:

记着! 第二个参数在 withBemMod() 是应用此组件的条件.

1. 联合国. 单位 Components/Button/_type/Button_type_link.tsx

import React from 'react'
import { withBemMod } from '@bem-react/core'

import { IButtonProps, cnButton } from '../index'

export interface IButtonTypeLinkProps {
  type?: 'link'
  href?: string
}

export const withButtonTypeLink = withBemMod<IButtonTypeLinkProps, IButtonProps>(
  cnButton(),
  { type: 'link' },
  (Button) => (props) => <Button {...props} as="a" />,
)

2. 联合国. 单位 Components/Button/_theme/Button_theme_action.tsx

import { withBemMod } from '@bem-react/core'

import { cnButton } from '../index'

export interface IButtonThemeActionProps {
  theme?: 'action'
}

export const withButtonThemeAction = withBemMod<IButtonThemeActionProps>(cnButton(), {
  theme: 'action',
})

步骤4.

终于,在你 App.tsx 你需要帮助 编曲 只需要带基本按钮的变体. 注意进口订单 - 它直接影响您的 CSS 规则 .

注: 如果你想使用具有不同数值的同一种修饰符,则应使用 composeU 用于正确输入.

import React, { FC } from 'react';
import { compose, composeU } from '@bem-react/core';

import { Button as ButtonPresenter } from './Components/Button/Button';
import { withButtonTypeLink } from './Components/Button/_type/Button_type_link';
import { withButtonThemeAction } from './Components/Button/_theme/Button_theme_action';
import { withButtonThemeDefault } from './Components/Button/_theme/Button_theme_default';

import './App.css';

const Button = compose(
  composeU(withButtonThemeAction, withButtonThemeDefault),
  withButtonTypeLink,
)(ButtonPresenter);

export const App: FC = () => (
  <div className="App">
    <Button>I'm basic</Button>
    // Renders into HTML as: <button class="Button">I'm Basic</button>

    <Button type="link" href="#stub">I'm type link</Button>
    // Renders into HTML as: <a href="#stub" class="Button Button_type_link">I'm type link</a>

    <Button theme="action">I'm theme action</Button>
    // Renders into HTML as: <button class="Button Button_theme_action">I'm theme action</button>

    <Button theme="action" type="link">I'm all together</Button>
    // Renders into HTML as: <a class="Button Button_theme_action Button_type_link">I'm all together</a>
  </div>
);

记着! 在按钮Presenter上构成的可选组件的顺序很重要:如果您的布局不同,需要应用多个修改符,则 首个 一个在作曲方法内 将会得到! 例如,这里:

export const Button = compose(
  withButtonThemeAction,
  withButtonTypeLink,
)(ButtonPresenter)

如果你和Button的动作有点像

<button className={className}>{children}</button>

您的JSX组件:

<Button type="link" theme="action">Hello</Button>

将生成 HTML :

<a class="Button Button_theme_action Button_type_link">Hello</a>

使用再出口来改进DX

关键是: 如果 树摇晃 启用

示例

Block/Block.tsx
Block/[email protected]
Block/_mod/Block_mod_val1.tsx
Block/_mod/Block_mod_val2.tsx
Block/_mod/Block_mod_val3.tsx

按平台为索引文件中的所有修饰符创建再导出:桌面,电话,amp等.

// Block/index.ts
export * from './Block'
export * from './Block/_mod'

// Block/desktop.ts
export * from './Block@desktop'
export * from './Block/_mod'

// Block/phone.ts
export * from './' // for feature if not created platform version

// Block/_mod/index.ts
export * from './Block_mod_val1.tsx'
export * from './Block_mod_val2.tsx'
export * from './Block_mod_val3.tsx'

用法 :

// App.tsx
import { Block as BlockPresenter, withModVal1 } from './components/Block/desktop'

const Block = withModVal1(BlockPresenter)

优化. 懒惰负载为修饰剂.

用React.lazy和动态导入来分拆更好的代码的解决方案

页:1 如果您需要 SSR 替换 React.lazy 装载方法 Block_mod.async.tsx 模块改为 @ 可装入/ 组件 或者说 可反应加载

// Block/_mod/Block_mod.async.tsx
import React from 'react'
import { cnBlock } from '../Block'

import './Block_mod.css'

export const DynamicPart: React.FC = () => <i className={cnBlock('Inner')}>Loaded dynamicly</i>

// default export needed for React.lazy
export default DynamicPart
// Block/_mod/Block_mod.tsx
import React, { Suspense, lazy } from 'react'
import { cnBlock } from '../Block'

export interface BlockModProps {
  mod?: boolean
}

export const withMod = withBemMod<BlockModProps>(cnBlock(), { mod: true }, (Block) => (props) => {
  const DynamicPart = lazy(() => import('./Block_mod.async.tsx'))

  return (
    <Suspense fallback={<div>Updating...</div>}>
      <Block {...props}>
        <DynamicPart />
      </Block>
    </Suspense>
  )
})

用法 :

// App.tsx
import {
    Block as BlockPresenter,
    withMod
} from './components/Block/desktop';

const Block = withMod(BlockPresenter);

export const App = () => {
    return (
        {/* chunk with DynamicPart not loaded */}
        <Block />

        {/* chunk with DynamicPart loaded */}
        <Block mod />
    );
}

简单修改器( 仅属于 CSS 类)

在大多数情况下,您只需要更改 CSS 类。 这种模式不会将modififer值传递给道具. 它不会为组件创建回声包,这样更好.

import React from 'react'
import { cnBlock } from '../Block'

export interface BlockModProps {
  simplemod?: boolean
}

export const withSimpleMod = createClassNameModifier<BlockModProps>(cnBlock(), { simplemod: true })

调试

帮助您调试“ @ bem- react/ core” 支持开发模式 .

对于 <Button type="link" theme="action">Hello</Button> (从 示例 ), React DevTools 将显示:

<WithBemMod(Button)[theme:action] ...>
  <WithBemMod(Button)[type:link] className="Button Button_theme_action" ...>
    <a className="Button Button_type_link Button_theme_action">Hello</a>
  </WithBemMod(Button)[type:link]>
</WithBemMod(Button)[theme:action]>

版本与发布记录

@bem-react/core 共发布 62 个版本,首次发布于 2018/08/29;过去 12 个月发布了 4 个版本。

版本发布日期距今
6.1.1latest2026/08/182 个月前
6.1.02026/02/278 个月前
6.0.1-dev.1next2026/02/258 个月前
6.0.02026/02/069 个月前
5.2.02025/06/151.4 年前
5.1.1-dev.42025/06/111.4 年前

其他发布通道:canary → 1.3.1,next → 6.0.1-dev.1。

关于 @bem-react/core 的常见问题

@bem-react/core 是什么?

BEM 反应核心

如何安装 @bem-react/core?

在项目目录运行 npm install @bem-react/core,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:react(^19.0.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@bem-react/core 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@bem-react/core 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@bem-react/core 可以商用吗?

@bem-react/core 使用 MPL-2.0 许可。弱 Copyleft:可以商用,也可以和闭源代码一起使用;但如果分发时修改了 MPL 授权的文件,这些文件的修改需以 MPL 开源。以上为概括,不构成法律意见,请以许可原文为准。

@bem-react/core 的下载量有多少?

根据 npm 官方下载统计,@bem-react/core 在 2026/10/08 – 2026/11/06 这 30 天内被下载 3,485 次,日均约 116 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@bem-react/core 还在维护吗?

最新版本 6.1.1 发布于 2026/08/18(2 个月前);至今共发布 62 个版本,其中过去 12 个月发布了 4 个;首次发布于 2018/08/29。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。