Sass с CSS-модулями и Webpack
Я создавал проект на некоторое время с помощью модулей Webpack, Sass и CSS. Обычно в моих файлах .scss
я определяю класс как:
:local(.button) {
color: white;
}
и в моих компонентах React, в методе render
, мне нужны стили:
render = () => {
const styles = require('./MyStyles.scss');
<div className={ styles.button } />
}
и все хорошо с миром. Все работает так, как ожидалось.
Теперь сегодня я читал страницу CSS-модулей и заметил, что ни один из селекторов не был включен :local()
как мой, и, кроме того, они импортировали стили как:
import styles from './MyStyles.scss';
И я подумал: "Ух, это выглядит намного приятнее, проще видеть, где он импортируется, и т.д. И я бы хотел не использовать :local()
и просто по умолчанию локально". Поэтому я попробовал это и сразу столкнулся с несколькими проблемами.
1) `import styles from../MyStyles.scss ';
Поскольку я использую ESLint в своих файлах React, я сразу же получаю сообщение об ошибке, что MyStyles.scss
не имеет экспорта по умолчанию, который обычно имеет смысл, но страница CSS-модулей заявлена:
При импорте модуля CSS из модуля JS он экспортирует объект со всеми сопоставлениями из локальных имен в глобальные имена.
поэтому я, естественно, ожидал, что экспорт по умолчанию в таблицу стилей будет объектом, к которому они тоже относятся.
2) Я попробовал import { button } from './MyStyles.scss';
Это пропускает linting, но button
регистрируется как undefined.
3) Если я вернусь к методу require
импорта моих стилей, все, что не указано в :local
, равно undefined.
Для справки, мой загрузчик веб-пакетов (я также включаю Node-Neat и Node-Bourbon, две удивительные библиотеки):
{ test: /.(scss|css)$/, loader: 'style!css?sourceMap&localIdentName=[local]___[hash:base64:5]!resolve-url!sass?outputStyle=expanded&sourceMap&includePaths[]=' + encodeURIComponent(require('node-bourbon').includePaths) +
'&includePaths[]=' + encodeURIComponent(require('node-neat').includePaths[1]) + '&includePaths[]=' + path.resolve(__dirname, '..', 'src/client/') }
Мои вопросы, следуя всем этим, следующие:
1) При использовании CSS-модулей с Sass я ограничился использованием :local
или :global
?
2) Поскольку я использую webpack, это также означает, что я могу только require
мои стили?
Ответы
Ответ 1
Вскоре после публикации я понял решение. Проблема, которая, по моему мнению, была довольно запутанной, была в моей конфигурации Webpack. Первоначально мой загрузчик выглядел так:
loader: 'style!css?sourceMap&localIdentName=[local]___[hash:base64:5]!resolve-url!sass?outputStyle=expanded&sourceMap
который дал мне 1) require
мой Sass и 2) обернуть мои стили в :local
.
Однако загрузчик css отсутствовал в опции modules
, чтобы он выглядел так:
loader: 'style!css?modules&sourceMap&localIdentName=[local]___[hash:base64:5]!resolve-url!sass?outputStyle=expanded&sourceMap
Теперь я могу import
мои стили, и мне не нужно их обертывать в :local
(хотя я полагаю, что все еще могу, если захочу).
Что я нашел наиболее интересным во всем этом, так это то, что без опции modules
все еще можно использовать функции CSS Modules-esque, хотя и несколько ограничивающие.
ИЗМЕНИТЬ:
Что-то, что я заметил, будущим предупреждением тому, кто смотрит на этот ответ, является то, что вы используете eslint-plugin-import, чтобы импортировать импорт в код javascript, он будет вызывать ошибку при импорте стилей, например:
import styles from './MyStyles.scss';
из-за того, как CSS-модули экспортируют полученный объект стилей. Это означает, что вам нужно будет require('./MyStyles.scss')
обойти любые предупреждения или ошибки.