В настоящее время мы используем последнюю версию nextJs (v14) с реакцией (v18). Я попытался использовать модуль nextJs css (примечание: он работает с scss, однако в документации об этом не упоминается). Но обнаружил некоторые ограничения при работе с ним:
.toastSuccess {
color: green;
.undo {
color: blue;
}
}
.toastError {
color: red;
.undo {
color: blue;
}
}
Когда я импортирую его в файл .tsx и пытаюсь применить, он не работает:
import styles from "./toast.module.scss";
return (
<div className = {isSuccess ? styles.toastSuccess : styles.toastError}>
<div className = "undo">undo</div>
...
</div>
</div>
)
Теперь мне просто интересно, какой лучший подход в 2024 году — хранить и применять стили в «огромном» проекте NextJs, реагирующем на реакцию. Я нашел следующее:
className = "d-flex flex-row m-4"
Я думаю, что последний вариант лучше, поскольку определения стилей взяты из Figma, и лучше всего хранить их отдельно от файла .tsx (но близко к нему). Также гарантирует уникальность названий стилей и то, что каждая модификация имеет небольшое и предсказуемое влияние. Но это решение для стилизации модуля nextjs кажется не лучшим.
Есть ли другой подход или какое-то решение, которое работает лучше, чем это?
Я понял ваш совет, спасибо за него! Однако в этом случае я также должен вычислить вложенные имена классов, что противоречит тому, как об этом думает CSS, поэтому это нехорошо. Могут произойти и другие сложные случаи. Наше приложение на самом деле не такое уж большое, но над ним работают несколько разработчиков пользовательского интерфейса, поэтому могут возникнуть коллизии имен. При использовании шаблона атомарного проектирования бывает, что компонент с таким же именем существует на атомной/молекулярной/сложности. Трудно найти действительно уникальное имя для класса scss.
Чтобы уточнить мой ответ: Для атомов/молекул я бы не использовал обычные классы, они предназначены только для более сложных компонентов, таких как панель навигации или, например, отображение продукта. Используя стилизованные компоненты, я бы сделал:
const Component = styled((props) => {
return <div {...props}>
<div class = "header" />
<div class = "content" />
</div>
})`
display: grid;
grid-template: 200px 1fr / 1fr;
& > .header {
// .header styles
}
& > .content {
// .content stlyes
}
`;
Для более сложных компонентов вы можете придерживаться полной генерации имени класса SC, но я также создал несколько приложений и обнаружил, что конфликт имен классов никогда не был такой уж большой проблемой, а использование только компонентов или модулей SC для каждого имени класса кажется обременительным.
const TextInner = styled.span``;
const Text = styled((props) => {
const {component: Component = "p", ...rest} = props;
return <Component {...rest}>
<TextInner>{children}</TextInner>
</Component>
})`
${TextInner} {}
`;
Чтобы стили работали, вам необходимо передать
.toastSuccessUndo
или.toastErrorUndo
элементу.undo
. CSSModules не поддерживают вложенность. Я бы использовал css mpodules только для небольших компонентов и вернулся к обычному css для более сложных компонентов, потому что считаю, что это слишком громоздко. Вам следует спросить себя, насколько огромно ваше приложение на самом деле, и подумать о том, как часто будут возникать конфликты стилей, и достаточно часто это не проблема, поэтому вы также можете просто использовать обычный scss или использовать стилизованные компоненты для генерации имени класса для корневого элемента и стиля дочерних элементов с помощью обычное имя класса.