Local less stylesheets for React components
I started a React project using redux-easy-boilerplate (https://github.com/anorudes/redux-easy-boilerplate/tree/master/src)
I really like how each component in the boilerplate is styled with an individual local SCSS file. I'm actually porting an old app that relies on LESS, and I want to reuse the styling from that app.
I'm trying to just directly replace SCSS with LESS in this boilerplate and I'm running into an issue I can't understand. Here's a typical component in it: https://github.com/anorudes/redux-easy-boilerplate/tree/master/src/components/Footer .
It has a styles
directory containing two files - index.js
:
import 'style!./styles.scss';
export default require('./styles.scss').locals.styles;
and styles.scss
such as this:
:local(.styles) {
text-align: center;
padding: 70px 0 40px;
...
}
If I just rename scss file to less, I get error saying that cannot get property 'styles' of undefined (being locals), pointing to second line of index.js. I don't really know SCSS and don't understand what the first line of the scss file does and what would be the LESS equivalent for it.
BTW, I did add the LESS loader to webpack config:
{
test: /\.less$/,
loader: 'style!css!less',
},
Answer
I believe there's a couple things going on here.
The first thing is, you replaced the loader for the SCSS files
loader: 'css?localIdentName=[path]!postcss-loader!sass'
with this loader for Less files
loader: 'style!css!less'
but they aren't equivalent. In the former configuration, the sass
loader converts the SCSS syntax to regular CSS, postcss-loader
runs additional post-processing based on PostCSS, and the css?localIdentName
converts this all down to plain CSS after resolving imports and URLS — but additionally creates local scopes based on the ?localIdentName=[path]
query parameter. From the css-loader docs:
By default CSS exports all class names into a global selector scope. This is a feature which offer a local selector scope.
The syntax
:local(.className)
can be used to declareclassName
in the local scope. The local identifiers are exported by the module....
You can configure the generated ident with the
localIdentName
query parameter (default[hash:base64]
). Example:css-loader?localIdentName=[path][name]---[local]---[hash:base64:5]
for easier debugging.
So without that query parameter, you will not get the .locals.styles
property on your required CSS.
Additionally, you should not be using the style-loader as part of your loader config, because you don't want to inject the styles by default; you want to be able to require the styles (so you can get access to the locals) and additionally inject them. That's why the boilerplate has the following as part of styles/index.js
for each set of styles:
import 'style!./styles.scss';
export default require('./styles.scss').locals.styles;
The first line injects the styles, and the second line exports the locals.
So, I think you simply need to change your webpack configuration to:
test: /\.less$/,
loader: 'css?localIdentName=[path]!postcss-loader!less',
Related Questions
- → OctoberCMS - How to make collapsible list default to active only on non-mobile
- → How to disable assets combining on development in OctoberCMS
- → October CMS - Radio Button Ajax Click Twice in a Row Causes Content to disappear
- → How to dynamically add class to parent div of focused input field?
- → Expanding search bar not expanding before search
- → Include external javaScript CSS in laravel 5
- → Using css modules how do I define a global class
- → How to add a timer in HTML5 and Javascript?
- → Conditional BG Color on AngularJS
- → Divs aren't aware of screen resizing
- → Setting the height of a textarea inside a table
- → How can I get Greasemonkey to highlight visited image links?
- → How to handle onclick event of a button?