webpack live hot reload for sass
Asked Answered
C

2

20

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;
Chuckle answered 27/8, 2018 at 16:48 Comment(1)
I've opened a more specific question about MiniCSS two days ago. This bounty also applies to that: #56319491Indies
W
29

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.

Westerfield answered 27/8, 2018 at 19:7 Comment(3)
i added this in however now when use my build command I am not getting a compiled.generated css file in my dist directoryChuckle
In dev mode you will use style-loader, that means that your css will be inside is file. Only in production mode you will get an external css fileWesterfield
That's exactly what I was missing. For some reason webpack-dev-server doesn't apply the stylesheet (import 'styles.css') when importing without (only tested without) using css modules...Prolactin
T
-2

Try using Parcel instead of Webpack. I used to spend hours configuring Webpack to get things like hot reload working. With Parcel, most things just "work" without a configuration file. For example, I wanted to start using Pug templates. Parcel recognized the .pug extension and automatically downloaded the required NPM dependencies!

In your case, just include the SCSS file in your app like this: import '../scss/style.scss' (notice the path is to the .scss source file relative to index.js). Parcel will automatically do the "sensible" thing.

Here are some references to get started with Parcel + React + SASS:


Notable advantages and disadvantages of Parcel vs WebPack:

  • Parcel requires minimal configuration; often no configuration.
  • Parcel usually builds much faster than WebPack.
  • The WebPack dev server seems more stable. (The Parcel dev server needs to restarted once in a while and doesn't play nice with Dropbox. Apparently this should be fixed in version 2.0.)
  • When (an uncommon) configuration is required, it might not be obvious how to do that in Parcel; at least in WebPack, all the configuration is in one place.
  • Sometimes Parcel's automatic configuration does thing people don't expect, confusing them.
Titleholder answered 30/5, 2019 at 10:47 Comment(1)
I agree on everything about Parcel. Unfortunately, the project I'm on was built with WebPack and keeping it is an absolute requirement. So I need to go through MiniCSS, as explained in my own question: #56319491Indies

© 2022 - 2024 — McMap. All rights reserved.