Using Webpack to Compile Sass (and keep class names local)

It's been a long journey trying to configure my Webpack setup to compile Sass, and the process has become quite overwhelming. In my quest for answers, I encountered numerous Github issues, Stackoverflow threads, and blog posts discussing how to integrate Sass with Webpack, each with its own unique approach. The sheer number of people encountering problems only reinforces my belief that Webpack's documentation needs improvement. Sigh.

After successfully configuring Webpack to compile Sass and serve it from /static, I realized that I want the class names to be locally scoped. Isn't that one of the advantages of using modular CSS with React components?

Here's an example of locally scoped class names: .foo__container___uZbLx {...}

Let me share my Webpack configuration file:

const webpack = require('webpack');
const path = require('path');
const ExtractTextPlugin = require('extract-text-webpack-plugin');

module.exports = {
    devtool: 'source-map',
    entry: {
        bundle: './src/js/app'
    },
    output: {
        path: __dirname,
        filename: '[name].js',
        publicPath: '/static'
    },
    plugins: [
        new webpack.optimize.OccurrenceOrderPlugin(),
        new ExtractTextPlugin('[name].css', {allChunks: true})
    ],
    module: {
        loaders: [
            {
                test: /\.js$/,
                exclude:  /node_modules/,
                include: path.join(__dirname, 'src'),
                loader: 'babel'
            },
            {
                test: /\.scss$/,
                exclude:  /node_modules/,
                include: path.join(__dirname, 'src'),
                loader:  ExtractTextPlugin.extract('style', 'css?sourceMap!sass')
            }
        ]
    }
};

While I managed to make it work for regular CSS:

{
    test: /\.css$/,
    exclude:  /node_modules/,
    include: path.join(__dirname, 'src'),
    loader:  ExtractTextPlugin.extract('style', 'css?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]')
}

Despite my success, I find the parameter-like syntax with all the ? marks confusing, and I'm unsure of where to look for documentation on this topic.

In case you're interested, here's what my React component looks like, showcasing how I import the styles:

import React, { Component } from 'react';
import s from './foo.css';

class Foo extends Component {
    render() {
        return (
            <div className={s.container}>
                <h1 className="title">Welcome!</h1>
                <p className="body">This is a dummy component for demonstration purposes.</p>
            </div>
        );
    }
}

export default Foo;

Furthermore, I have three unrelated questions:

  • What's the purpose of the output.path property if Webpack only serves the file from memory via /static?
  • Is webpack-dev-server necessary for the current setup, as it seems to focus on hot module replacement and automatic refreshing?
  • Are my exclude and include properties redundant? Does excluding node_modules improve compilation time, reducing the processing load?

Answer №1

After some trial and error, I managed to make it work by including the following code:

loader:  ExtractTextPlugin.extract('style', 'css?modules&localIdentName=[name]__[local]___[hash:base64:5]!sass')

Surprisingly, all I had to do was add !sass at the end of the query. It's frustrating that there isn't more comprehensive documentation available for this; the search for proper information seems never-ending...

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the best way to style only textboxes with CSS without affecting other input types such as checkboxes?

If attribute selectors were universally supported by all browsers, we could effortlessly implement the following styling: input[type='text'] { font:bold 0.8em 'courier new',courier,monospace; } input[type='radio'] { margin:0 ...

How can I ensure a div always moves to the right by using margin-right auto?

How can I align a div to the right using margin-right auto? I attempted margin-right: auto; and margin: 0 0 0 auto; but it was not successful. ...

Can a C# MVC List<int> be transformed into a JavaScript array?

Can a MVC C# List be converted to a JavaScript array? var jsArray = @Model.IntList; I would really appreciate any assistance on this matter. ...

Does JavaScript array filtering and mapping result in a comma between each entry in the array?

The code snippet above showcases a function that retrieves data from a JSON array and appends it onto a webpage inside table elements. //define a function to fetch process status and set icon URL function setServerProcessesServer1761() { var url = "Serv ...

Tapping on a DIV element that overlays a YouTube video on an iPad does not trigger any action

Currently, I am working on a webpage specifically designed for iPad and I have encountered an issue: I am trying to embed a YouTube video using an iframe and also need a div element to remain on top of it. To achieve this, I have added "?wmode=transparen ...

Organizing an angular expansion panel

I am currently dealing with an expansion panel that has a lot of content. The layout is quite messy and chaotic, as seen here: https://ibb.co/Y3z9gdf It doesn't look very appealing, so I'm wondering if there is a way to organize it better or ma ...

What is the reason behind external JavaScript files being able to access the functions of other external JavaScript files, and what measures can

While I may not be an expert in JavaScript, I find it intriguing that within a project containing 3 JavaScript files, any of these files can access functions from the others. The real puzzle lies in figuring out how to prevent this from happening. For in ...

Tips for managing nested objects within React state and keeping them updated

Could someone kindly point out where I might be going wrong with this code? Upon checking the console.log, it seems like the date function is functioning correctly. However, despite using this.setState, the timestamp remains unchanged. Any help would be gr ...

Submitting forms through Vanilla JavaScript using AJAX

Can anyone assist me in implementing an AJAX form submission using Vanilla JavaScript instead of jQuery? I have the following jQuery code that needs to be converted: document.addEventListener('DOMContentLoaded', function() { document.querySelec ...

Ways to display additional text with a "Read More" link after three lines of content without relying on a

I am currently working on an application where I need to display text in a limited space of 3 lines. If the text exceeds this limit, I want to show either "Read More" or "Hide". Below is the code snippet that I am using for this functionality. class Cust ...

Tips for adding npm modules in StackBlitz?

Is it possible to install npm packages for Angular on StackBlitz without a terminal? I'd like to know the process. ...

Is Joi's existence a myth?

I've been using Joi for validation, and I've encountered a situation that I'm having trouble with. I have an object that sometimes includes an id field (for editing) and other times it doesn't (for creating). My goal is to validate tha ...

JSdom, automation, web scraping, handling dynamic iframes

I am currently in the process of automating my tasks on the website provided at the link below: I need to fill out forms and submit them automatically. So far, I have been successful in automating using Greasemonkey and I am now considering switching to ...

When using the <Routes> component, it will not render a component that acts as a container for multiple <Route> elements

Upon wrapping my component in <Routes>, I encountered this warning: Warning: [Categories] is not a <Route> component. All component children of <Routes> must be a <Route> or <React.Fragment> In App.js: const App = () => ...

JQuery UI Autocomplete - Issue with loading data object

I've been attempting to implement autocomplete with JQuery UI, but I'm encountering difficulties when passing in a label & value object. var individuals = []; var test = new Array(); var dataObject = jQuery.parseJSON(data) ...

Utilizing a Mocking/Spying Tool in Angular Unit Testing

I have a file named myHelpers.ts which contains multiple functions: myHelpers.ts export function multiply(a, b) { return a * b; } export function add(a, b) { return a + b; } export function subtract(a, b) { return a - b; } The above file al ...

You cannot render objects as a React child (discovered: object containing keys {id, name}). To display a collection of children, make sure to use an array instead

My goal is to retrieve data from an API and present it in a table using the material-table library. I suspect that I am struggling to properly manipulate objects and arrays. The response from my API is as follows: { "data": [ { " ...

Combining multiple snippets of CSS classes in Material UI Emotion/Styled: How to do it effectively?

In previous versions, Material UI styled components allowed for the use of the className property to selectively apply styles. For example, a component could be styled like this: const styles = (theme: ThemeType) => ({ root: { width: '1 ...

Adjust the input value with CSS when hovering

Whenever I click on a button, the name of that button is displayed on the site. However, I am looking to change this button name when hovering over it but I am not sure how to do it. echo '<form id="button" method="POST" >&ap ...

error": "Unable to access undefined properties (reading 'SecretString')

Encountering the error message Cannot read properties of undefined (reading 'SecretString') when utilizing @aws-sdk/client-secrets-manager? It's a sign that you should consider updating your code to accommodate the latest version. ...