I am building a workflow for a react starter and would like to have my browser auto reload when I make a change to my scss files.
Currently, webpack will hot reload when I make a change in my index.js file (set as my entry point). However when I change/add scss code in my scss file, it gets compiled, but the css doesn't get output anywhere and does not trigger a browser reload.
I am new to webpack would really appreciate some insight here.
Here is my webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
module.exports = {
entry: ['./src/js/index.js', './src/scss/style.scss'],
output: {
path: path.join(__dirname, 'dist'),
filename: 'js/index_bundle.js',
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader'
}
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
},
{
test: /\.scss$/,
use: [
{
loader: 'file-loader',
options: {
name: '[name].css',
outputPath: 'css/'
}
},
{
loader: 'extract-loader'
},
{
loader: 'css-loader'
},
{
loader: 'postcss-loader'
},
{
loader: 'sass-loader'
}
]
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
})
]
}
My index.js entry point file
import React from 'react';
import ReactDOM from 'react-dom';
import App from '../components/App';
ReactDOM.render(
<App/>,
document.getElementById('App')
);
And my App component
import React, {Component} from 'react';
import '../../dist/css/style.css';
class App extends Component {
render() {
return (
<div>
<p>Test</p>
</div>
)
}
}
export default App;
Get Startedwebpack-dev-server supports a hot mode in which it tries to update with HMR before trying to reload the whole page. See the Hot Module Replacement guide for details.
Hot Module Replacement (or HMR) is one of the most useful features offered by webpack. It allows all kinds of modules to be updated at runtime without the need for a full refresh. This page focuses on implementation while the concepts page gives more details on how it works and why it's useful.
Actually, style-loader
is the one that is responsible for CSS HMR.
You should add it at the end of the style pipeline, only for dev. For production, you can remain your config.
It should look something like that:
const devMode = process.env.NODE_ENV !== 'production'
{
test: /\.scss$/,
use: [
devMode ? 'style-loader' : MiniCssExtractPlugin.loader,
{
loader: 'css-loader'
},
{
loader: 'postcss-loader'
},
{
loader: 'sass-loader'
}
]
}
Pay attention, the best practice of extracting css into a separate file is to use MiniCssExtractPlugin
if you are using webpack 4, or ExtractTextWebpackPlugin
, if you are using webpack < 4.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With