Skip to content

Commit 142cbae

Browse files
vegedclaude
andcommitted
docs: add Russian translations and restore Motivation article
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent dbb106f commit 142cbae

8 files changed

Lines changed: 317 additions & 2 deletions

File tree

README.ru.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# bem-react &middot; [![github (ci)](https://github.com/bem/bem-react/workflows/ci/badge.svg?branch=master)](https://github.com/bem/bem-react/workflows/ci/badge.svg?branch=master)
2+
3+
Набор инструментов для разработки пользовательских интерфейсов по [методологии БЭМ](https://ru.bem.info) на [React](https://github.com/facebook/react). BEM React поддерживает аннотации типов [TypeScript](https://www.typescriptlang.org/index.html).
4+
5+
## Пакеты
6+
7+
| Пакет | Версия | Размер |
8+
| ---------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
9+
| [`@bem-react/classname`](packages/classname) | [![npm (scoped)](https://img.shields.io/npm/v/@bem-react/classname.svg)](https://www.npmjs.com/package/@bem-react/classname) | [![npm bundle size (minified + gzip)](https://img.shields.io/bundlephobia/minzip/@bem-react/classname.svg)](https://bundlephobia.com/result?p=@bem-react/classname) |
10+
| [`@bem-react/classnames`](packages/classnames) | [![npm (scoped)](https://img.shields.io/npm/v/@bem-react/classnames.svg)](https://www.npmjs.com/package/@bem-react/classnames) | [![npm bundle size (minified + gzip)](https://img.shields.io/bundlephobia/minzip/@bem-react/classnames.svg)](https://bundlephobia.com/result?p=@bem-react/classnames) |
11+
| [`@bem-react/core`](packages/core) | [![npm (scoped)](https://img.shields.io/npm/v/@bem-react/core.svg)](https://www.npmjs.com/package/@bem-react/core) | [![npm bundle size (minified + gzip)](https://img.shields.io/bundlephobia/minzip/@bem-react/core.svg)](https://bundlephobia.com/result?p=@bem-react/core) |
12+
| [`@bem-react/di`](packages/di) | [![npm (scoped)](https://img.shields.io/npm/v/@bem-react/di.svg)](https://www.npmjs.com/package/@bem-react/di) | [![npm bundle size (minified + gzip)](https://img.shields.io/bundlephobia/minzip/@bem-react/di.svg)](https://bundlephobia.com/result?p=@bem-react/di) |
13+
| [`@bem-react/eslint-plugin`](packages/eslint-plugin) | [![npm (scoped)](https://img.shields.io/npm/v/@bem-react/eslint-plugin.svg)](https://www.npmjs.com/package/@bem-react/eslint-plugin) ||
14+
15+
## Участие в разработке
16+
17+
Bem React Core — библиотека с открытым исходным кодом, которая активно развивается и используется в [Яндексе](https://yandex.com/company/).
18+
19+
Если у вас есть предложения по улучшению API, отправьте нам [Pull Request](https://github.com/bem/bem-react-core/pulls).
20+
21+
Если вы нашли ошибку, создайте [issue](https://github.com/bem/bem-react-core/issues) с описанием проблемы.
22+
23+
Подробное руководство по участию в разработке — в [CONTRIBUTING.md](CONTRIBUTING.md).
24+
25+
## Лицензия
26+
27+
© 2018 [Яндекс](https://yandex.com/company/). Код распространяется под лицензией [Mozilla Public License 2.0](LICENSE.md).

website/docs/guides/lazy.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ export const withMod = withBemMod<BlockModProps>(
6363
)
6464
```
6565

66-
> **NOTE** If your need SSR replace React.lazy method for load `Block_mod.async.tsx` module to [@loadable/components](https://www.smooth-code.com/open-source/loadable-components/) or [react-loadable](https://github.com/jamiebuilds/react-loadable)
66+
> **NOTE** If your need SSR replace React.lazy method for load `Block_mod.async.tsx` module to [@loadable/component](https://www.smooth-code.com/open-source/loadable-components/) or [react-loadable](https://github.com/jamiebuilds/react-loadable)
6767
6868
## Usage
6969

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
---
2+
id: motivation
3+
title: Why BEM if there's React?
4+
---
5+
6+
This document covers tasks that web developers face every day. We describe how they are solved in [React](https://reactjs.org/) today and explain why those solutions are suboptimal. The bem-react-core library offers alternative solutions that are more efficient thanks to [redefinition levels](https://en.bem.info/methodology/redefinition-levels/) and the ability to declaratively manage [block modification](https://en.bem.info/methodology/block-modification/).
7+
8+
* [Decomposition](#decomposition)
9+
* [Code reuse](#code-reuse)
10+
* [Cross-platform development](#cross-platform-development)
11+
* [Experiments](#experiments)
12+
* [Sharing a component library across projects](#sharing-a-component-library-across-projects)
13+
14+
## Decomposition
15+
16+
A web component has to solve many tasks. As a result, its functionality grows more complex and the number of possible variations increases. This variability is usually expressed with arbitrary imperative conditions in code. A large number of `if` or `switch` statements makes it hard to quickly grasp everything the component can do, to modify it, or to produce the right combination of conditions evaluated at runtime.
17+
18+
Besides that, most of a React component's logic lives in the `render()` method. So moving or overriding a component's functionality means rewriting most of that method.
19+
20+
## Code reuse
21+
22+
The number of components keeps growing, and their functionality gets more complex. Components start to share common code that needs to be reused.
23+
24+
For code reuse, React today offers [Higher-Order Components](https://reactjs.org/docs/higher-order-components.html) or classic inheritance.
25+
26+
Inheritance doesn't let you combine several orthogonal features without completely redesigning the class hierarchy, and it comes with a number of [well-known](https://en.wikipedia.org/wiki/Composition_over_inheritance) problems.
27+
28+
## Cross-platform development
29+
30+
Cross-platform support is one of the core requirements for a web project. To support multiple platforms, teams usually either build a separate version for each platform or develop a single responsive version.
31+
32+
Building separate versions takes extra resources: the more platforms you need to support, the more effort development takes. Even if the project has enough resources to develop several versions, keeping product features in sync across them adds extra complexity. Having different versions also aggravates the code reuse problem.
33+
34+
A responsive version complicates the code and raises the skill requirements for developers. Another common problem with responsive versions is degraded performance, especially on mobile devices.
35+
36+
## Experiments
37+
38+
Developing a project for a large audience requires confidence in every change. A/B experiments are one way to gain that confidence.
39+
40+
The most common ways to organize code for experiments are:
41+
* branching the entire codebase and running separate service instances
42+
* targeted conditionals within a single codebase
43+
44+
If a project runs many long-lived experiments, branching the codebase can incur significant extra costs. Every experiment branch has to be kept up to date, with changes (bug fixes, product features) synchronized. Branching also makes overlapping experiments harder to run.
45+
46+
Targeted conditionals within a single codebase are more flexible but complicate the codebase itself: experiment conditions may touch different parts of the project's core code. A large number of conditions makes the code harder for humans to understand and hurts performance by increasing the amount of code shipped to the browser. After every experiment, the extra code has to be removed: either drop the conditions and make the code permanent, or delete the failed experiment entirely.
47+
48+
## Sharing a component library across projects
49+
50+
To use a shared component library in a project, you need to interact with its source code. For example, to change the API, improve and optimize the code, or add functionality.
51+
52+
There are several ways to modify library components for your project:
53+
* forking the library
54+
* inheritance
55+
* patching the library code at runtime
56+
57+
With a fork, you have to track upstream updates and apply patches.
58+
59+
Inheritance is used when you need a modified version of a library component. For example, you can create a `MyButton` component that inherits from the library's `Button`. But the inherited `MyButton` won't be applied to all library components that contain buttons. For example, the library may have a `Search` component built as a composition of `Input` and `Button`. In that case, the inherited `MyButton` won't appear inside the `Search` component.
60+
61+
Patching library code at runtime is impossible unless the library authors have provided a way to make external changes.
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
---
2+
id: lazy
3+
title: Ленивые модификаторы
4+
---
5+
6+
Более эффективное разделение кода с помощью React.lazy и динамических импортов.
7+
8+
## Структура
9+
10+
```
11+
src/components/Block/
12+
├── Block.tsx
13+
├── _mod
14+
│   └── Button_mod.async.tsx
15+
│   └── Button_mod.css
16+
│   └── Button_mod.tsx
17+
```
18+
19+
## Объявление
20+
21+
**Шаг 1.** Объявите часть кода, которая должна загружаться динамически.
22+
23+
```tsx
24+
// Block/_mod/Block_mod.async.tsx
25+
import React from 'react'
26+
import { cnBlock } from '../Block'
27+
28+
import './Block_mod.css'
29+
30+
export const DynamicPart: React.FC = () => <i className={cnBlock('Inner')}>Loaded dynamicly</i>
31+
32+
// default export нужен для React.lazy
33+
export default DynamicPart
34+
```
35+
36+
**Шаг 2.** Объявите модификатор.
37+
38+
```tsx
39+
// Block/_mod/Block_mod.tsx
40+
import React, { Suspense, lazy } from 'react'
41+
import { cnBlock } from '../Block'
42+
43+
export interface BlockModProps {
44+
mod?: boolean
45+
}
46+
47+
export const withMod = withBemMod<BlockModProps>(
48+
cnBlock(),
49+
{
50+
mod: true,
51+
},
52+
(Block) => (props) => {
53+
const DynamicPart = lazy(() => import('./Block_mod.async.tsx'))
54+
55+
return (
56+
<Suspense fallback={<div>Updating...</div>}>
57+
<Block {...props}>
58+
<DynamicPart />
59+
</Block>
60+
</Suspense>
61+
)
62+
},
63+
)
64+
```
65+
66+
> **Примечание.** Если вам нужен SSR, для загрузки модуля `Block_mod.async.tsx` используйте вместо React.lazy [@loadable/component](https://www.smooth-code.com/open-source/loadable-components/) или [react-loadable](https://github.com/jamiebuilds/react-loadable).
67+
68+
## Использование
69+
70+
```ts
71+
// App.tsx
72+
import {
73+
Block as BlockPresenter,
74+
withMod
75+
} from './components/Block/desktop';
76+
77+
const Block = withMod(BlockPresenter);
78+
79+
export const App = () => {
80+
return (
81+
{/* чанк с DynamicPart не загружен */}
82+
<Block />
83+
84+
{/* чанк с DynamicPart загружен */}
85+
<Block mod />
86+
)
87+
}
88+
```
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
---
2+
id: structure
3+
title: Структура компонента
4+
---
5+
6+
Обычно базовая структура компонента выглядит примерно так:
7+
8+
```
9+
src/components/Button/
10+
├── Button.css
11+
├── Button.tsx
12+
├── Button@desktop.css
13+
├── Button@desktop.tsx
14+
├── desktop.ts
15+
├── _view
16+
│ ├── Button_view_default.css
17+
│   └── Button_view_default.tsx
18+
└── hooks
19+
└── useCheckedState.ts
20+
```
21+
22+
## Платформы
23+
24+
Если у компонента есть особенности, специфичные для платформы, — например, состояние при наведении, — создайте реализацию для этой платформы и реэкспортируйте всё из общей реализации.
25+
26+
Общая реализация:
27+
28+
```tsx
29+
// src/components/Button/Button.tsx
30+
import React from 'react'
31+
import './Button.css'
32+
33+
export const Button = ({ children }) => <button className="Button">{children}</button>
34+
```
35+
36+
Реализация для десктопа:
37+
38+
```tsx
39+
// src/components/Button/Button@desktop.tsx
40+
export * from './Button'
41+
import './Button@desktop.css'
42+
```
43+
44+
## Публичный API
45+
46+
Публичный API позволяет контролировать, что должно быть доступно разработчику, а также скрывает от потребителя, что для конкретной платформы часть кода может отсутствовать.
47+
48+
> Очень важно, чтобы в проекте был настроен [tree shaking](https://webpack.js.org/guides/tree-shaking/), иначе в итоговый бандл может попасть неиспользуемый код.
49+
50+
Пример:
51+
52+
```ts
53+
// src/components/Button/desktop.ts
54+
export * from './Button@desktop'
55+
export * from './_view/Button_view_default'
56+
export * from './hooks/useCheckedState'
57+
```
58+
59+
Использование:
60+
61+
```ts
62+
// src/components/Feature/Feature.tsx
63+
import {
64+
Button as ButtonDesktop,
65+
withViewDefault,
66+
useCheckedState,
67+
} from 'components/Button/desktop'
68+
```

0 commit comments

Comments
 (0)