With css-loader
{
test: /\.s?css$/,
use: [
{ loader: 'style-loader' },
{ loader: 'css-loader',
query: {
modules: true,
localIdentName: '[name]-[local]-[hash:base64:8]'
}
},
{ loader: 'sass-loader'}
]
}
configured that way the css-loader seems to not find css rules under class names. The css rules listed under div.profile
doesn't get applied on the screen. The css-loader ver. 1.0.0 in my code runs with Node 10.x. Switching modules: false
gets the desired styling to show.
The code is posted below.
main.js:
require('babel-runtime/regenerator');
require('babel-register');
require('webpack-hot-middleware/client?reload=true');
require('./index.html');
index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Webpack 4</title>
</head>
<body>
<div class="profile">
<img src="./images/400.jpg" alt="">
<h1>Hello Webpack 4</h1>
<div id="react-root"></div>
</div>
<script src="/main-bundle.js"></script>
</body>
</html>
app.js:
import React from 'react';
import ReactDOM from 'react-dom';
import Counter from './counter';
import { AppContainer } from 'react-hot-loader';
const render = (Component) => {
ReactDOM.render(
<AppContainer>
<Component />
</AppContainer>,
document.getElementById('react-root')
);
};
render(Counter);
if (module.hot) {
module.hot.accept('./counter', () => {
render(require('./counter'));
});
}
counter.js:
import React, { Component } from 'react';
import { hot } from 'react-hot-loader';
import { css } from 'emotion';
import styled from 'react-emotion';
import styles from './main.scss';
const Fancy = styled('h1')`
color: ${props => props.wild ? 'hotpink' : 'gold'}
`;
const red = '#f00';
const className = css`
color: ${red};
font-size: 3rem;
`;
class Counter extends Component {
constructor(props) {
super(props);
this.state = { count: 0 };
this.addCount = this.addCount.bind(this);
}
addCount() {
this.setState(() => ({ count: this.state.count + 1 }));
}
render() {
const isWild = this.state.count % 2 === 0;
return (
<div className={styles.counter}>
<h1 onClick={this.addCount} className={className}>Count: {this.state.count}</h1>
<Fancy wild={isWild}>react-emotion lib allows to hook styles to component names</Fancy>
</div>
);
}
}
export default hot(module)(Counter);
main.scss:
body {
background-color: #a1b2c3;
}
.profile {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
height: 100vh;
img {
border-radius: 50%;
box-shadow: 0 0 20px #000;
}
h1 {
font-family: 'source-code-pro', 'sans-serif';
font-weight: 400;
}
}
.counter {
border: 3px solid green;
}
The reason was the .profile
class name in index.html is outside the counter.js scope. The css modules produce class names by the localIdentName
pattern but the .profile
class name was hard coded in index.html before css modules in counter.js came into play.
In counter.js
import styles from './main.scss';
console.log('styles:', styles);
outputs
styles: Object { profile: "main-profile-2P-yNf0J", counter: "main-counter-Pmp5YERO" }
How to get the main-profile-2P-yNf0J
class name to index.html remains unclear for me.