Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ---
- sidebar_position: 4
- sidebar_class_name: sidebar-item--wip
- pagination_next: reference/index
- ---
- import WIP from '@site/src/shared/ui/wip/tmpl.mdx'
- # Кросс-импорты
- <WIP ticket="220" />
- > Кросс-импорты появляются тогда, когда слой или абстракция начинает слишком сильно насыщаться логикой. Поэтому методология выделяет новые слои, которые разрешают связанные с ними проблемы.
- ## Введение {#start}
- Перед тем, как разбираться, как работать с кросс-импортами для соответствия методологии FSD, стоит разобраться, что такое "кросс-импорт" в принципе.
- **Кросс-импорт** - ситуация, при которой внутри FSD слоя появилась необходимость импорта одного слайса в другой.
- :::warning Важно
- Речь в статье идёт только о конфликтных ситуациях при импортах между **слайсами**. Внутри одного слайса фрагменты не запрещено импортировать друг в друга.
- :::
- Рассмотрим абстрактный пример:
- - `📂 entities`
- - `📂 countries`
- - `📁 lib`
- - `📄 getCountriesList `
- - `📁 cities`
- - `📁 lib`
- - `📄 getCitiesByCountryName`
- В данном примере для вызова метода `getCitiesByCountryName` необходимо получить результат вызова метода `getCountriesList`.
- Получить результат работы метода `getCountriesList` напрямую нельзя, так как это нарушит принцип низкой связности и усложнит поддержку проекта в дальнейшем.
- Как разрешать ситуации, когда появилась захотелось сделать кросс-импорт? Рассмотрим в этой статье.
- ## Варианты решения кросс-импортов {#solutions}
- ### Объединение нескольких слайсов в один {#slices-merge}
- Как видно из примера выше, доменная область методов `getCitiesByCountryName` и `getCountriesList` похожа, а значит возможно создать один слайс из двух уже имевшихся, где оба метода хранились бы в одной директории
- Результат объединения слайсов `countries` и `cities`:
- - `📂 entities`
- - `📂 geography`
- - `📁 lib`
- - `📄 getCountriesList`
- - `📄 getCitiesByCountryName`
- Как видно из примера, мы избавились от ситуации, когда один слайс импортирует данные из другого и достигли высокой сцепленности и низкой связности в рамках сегмента одного слайса
- ### Разбиение слайсов на разные слои {#slices-moving}
- Данный вариант скорее подходит для тех случаев, для которых объединение нескольких слайсов в один затруднено или невозможно.
- Вероятно, что слайс, который импортирует информацию из другого слайса сильно насыщен логически, и этот слайс стоит на слой выше, дабы устранить связность этих слайсов внутри одного слоя.
- Результат разбиения слайсов `countries` и `cities` на разные слои:
- - `📂 entities`
- - `📂 countries`
- - `📁 lib`
- - `📄 getCountriesList `
- - `📂 features`
- - `📁 cities`
- - `📁 lib`
- - `📄 getCitiesByCountryName`
- Переместив слайс `cities` на слой `features` (не обязательно на него, подойдёт любой слой выше по иерархии), мы более конкретно уточнили его доменную область и создали правильный с точки зрения иерархии слоёв механизм импортов.
- ### Дублирование кода {#duplication-code}
- Если объем информации, который импортируется из другого слайса невелик, возможно стоит продублировать её в текущий слайс. Тем не менее, такой вариант не стоит рассматривать приоритетным над указанными выше.
- ## А если кросс-импорт неизбежен? {#cross-import-is-inevitable}
- :::caution Внимание
- Информация в этом разделе **не является руководством к действию** и не отражает официальную позицию авторов методологии Feature Sliced Design.
- Тем не менее, в экзотических ситуациях, информация раздела может быть полезна
- :::
- Если в проекте необходим кросс-импорт и два описанных выше способа не помогли, сообщество Feature Sliced Design предлагает следующий вариант решения проблемы
- - `📂 entities`
- - `📂 countries`
- - `📁 lib`
- - `📄 getCountriesList `
- - `@x`
- - `📁 cities`
- - `📁 lib`
- - `📄 getCitiesByCountryName`
- - `@x`
- ### @x {#export-private-api}
- **@x** - это подход, когда внутри слайса возможно создать явный публичный экспорт только тех модулей, которые можно использовать в рамках нескольких слайсов одного слоя
- Рассмотрим пример:
- ```ts title="entities/countries/@x.ts"
- export { getCountriesList } from './lib/getCountriesList.ts';
- ```
- Метод внутри слайса, которому необходим кросс-импорт:
- ```ts title="entities/cities/lib/getCitiesByCountryName"
- import { getCountriesList } from '/entities/countries/@x/getCountriesList';
- const countries = getCountriesList();
- const getCitiesByCountryName = (countryName: string) => {} // logic
- return getCitiesByCountryName(countries[0]);
- ```
- Как видно по пути импорта в файле `getCitiesByCountryName`, благодаря экспорту из файла @x, явно видно, что данный модуль не предназначен для публичного использования, а существует только для того, чтобы быть импортированным внутрь другого слайса
- ### Отмена запрета на кросс-импорты {#disable-cross-imports-rule}
- Если Вы попробовали все способы в статье, но по каким-либо причинам всё равно не смогли избавиться от кросс-импортов, возможно, стоить задуматься о том, чтобы снять запрет на них в рамках конкретных слайсов, либо всего проекта в целом.
- Однако, важно понимать, что отмена запрета на кросс-импорты, может негативно сказываться на общей структуре проекта.
- ## Полезные ссылки {#useful-links}
- 1. Команда Feature Sliced Design разработала инструмент, позволяющий автоматически проверить наличие кросс-импортов в проекте: [Steiger](https://github.com/feature-sliced/steiger)
- 2. Больше информации о правиле кросс-импортов: [Steiger-Forbidden-Imports](https://github.com/feature-sliced/steiger/blob/master/packages/steiger-plugin-fsd/src/forbidden-imports/README.md)
- ## См. также {#see-also}
- - [(Тред) Про предполагаемую неизбежность кросс-импортов](https://t.me/feature_sliced/4515)
- - [(Тред) Про резолвинг кросс-импортов в сущностях](https://t.me/feature_sliced/3678)
- - [(Тред) Про кросс-импорты и ответственность](https://t.me/feature_sliced/3287)
- - [(Тред) Про импорты между сегментами](https://t.me/feature_sliced/4021)
- - [(Тред) Про кросс-импорты внутри shared](https://t.me/feature_sliced/3618)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement