Webpack css modules with sass

How to configure SCSS modules for Webpack

SCSS is a popular choice for styling websites, thanks to features such as; mixins, variables and functions, which CSS historically never had native support for. One of the most challenging aspects of styling using CSS is the Cascade, meaning that elements can inherit style properties from many other CSS selectors. This can be problematic, and SCSS can be a solution to make this problem more managable.

SCSS modules are usually directly tied to one specific component/element, and are not typically re-used.

This post explores how to configure Webpack to support standard SCSS ( your-styles.scss ) and SCSS modules ( your-component.module.scss ).

We assume that you already have a Webpack configuration file. If you need help getting started, please check out our post Webpack 4 from absolute scratch.

If you do not already have the following line in your Webpack configuration file, go ahead and add it;

const isDevelopment = process.env.NODE_ENV === "development"

This is used to optimize your bundles only when building for production, which should result in faster development builds.

How to add support for SCSS and SCSS modules in Webpack

We will focus on SCSS modules and global SCSS, so let’s get started.

Читайте также:  Binary to dec python

Run the following command in your terminal to install Sass and related tooling;

npm install --save-dev node-sass sass-loader style-loader css-loader mini-css-extract-plugin

What are these packages for?

  • node-sass provides binding for Node.js to LibSass, a Sass compiler.
  • sass-loader is a loader for Webpack for compiling SCSS/Sass files.
  • style-loader injects our styles into our DOM.
  • css-loader interprets @import and @url() and resolves them.
  • mini-css-extract-plugin extracts our CSS out of the JavaScript bundle into a separate file, essential for production builds.

We need to add two loaders, one for global styling and one for componentised styling, referred to as SCSS modules. SCSS modules play well with component-based libraries/frameworks like React.

By default, Webpack will include our compiled CSS in our JavaScript bundle ( main.js ). Whilst this works just fine for development builds, we do not want this for production. We will use Mini CSS Extract Plugin only when building for production, because it slows the build slightly and we want to keep our builds as efficient as possible.

Start by importing Mini CSS Extract Plugin into your webpack.config.js file as follows;

const MiniCssExtractPlugin = require("mini-css-extract-plugin")
module.exports =   ///.   plugins: [  ///.  + new MiniCssExtractPlugin( + filename: isDevelopment ? '[name].css' : '[name].[hash].css', + chunkFilename: isDevelopment ? '[id].css' : '[id].[hash].css' + >)  ] >

We add a hash to the filename of our bundles for easy and efficient cache busting.

Next, add our two new loaders, as follows;

module.exports =   ///.   module:   rules: [  ///.  +  + test: /\.module\.s(a|c)ss$/, + loader: [ + isDevelopment ? 'style-loader' : MiniCssExtractPlugin.loader, +  + loader: 'css-loader', + options:  + modules: true, + sourceMap: isDevelopment + > + >, +  + loader: 'sass-loader', + options:  + sourceMap: isDevelopment + > + > + ] + >, +  + test: /\.s(a|c)ss$/, + exclude: /\.module.(s(a|c)ss)$/, + loader: [ + isDevelopment ? 'style-loader' : MiniCssExtractPlugin.loader, + 'css-loader', +  + loader: 'sass-loader', + options:  + sourceMap: isDevelopment + > + > + ] + >  ///.   ]  >,  resolve:  - extensions: ['.js', '.jsx'] + extensions: ['.js', '.jsx', '.scss']  >  ///.  >

Note to simplify our imports in our JavaScript file, we should add the .scss file extension to resolve > extensions as shown above.

The first rule only applies to files with the .module.scss or .module.sass file extensions. First, SCSS is converted to CSS ( sass-loader ), then run through css-loader to process @import() , url() etc, then style-loader (to be appended to the DOM) or Mini CSS Extract Plugin to externalise the CSS when doing a production build.

The CSS loader is important here because it is also responsible for transforming our SCSS class names into a CSS modules convention. We are essentially breaking the cascade here to prevent our styles effecting other elements on the page and vice-versa.

The second rule is very similar to the first, except we do not transform the class names.

With all the configuration out of the way, we now need some styles so that we can test everything is working.

Under src , create a new file called app.module.scss and add the following coode;

Any element that gets the class red will have a red foreground colour.

Open app.js and import the SCSS file as follows;

import styles from "./app.module"

We do not need to include the file extension because we have already told Webpack to look for files with .scss file extensions automatically.

function App()  return h2 className=styles.red>>This is our React application!h2> >

Pretty straightforward huh? No matter how css-loader transforms our class name (it probably gets renamed to something random like _1S0lDPmyPNEJpMz0dtrm3F ), we can reference the style using the same name we gave it in the app.module.scss .

Next, we need some global styles.

Create a new file called global.scss under src and add the following;

body  background-color: yellow; >

This will give our webpage a lovely yellow background.

Open index.js and import the global styles as follows;

Webpack 4 CSS Modules

Beautiful. I should be a designer.

Summary

SCSS modules take quite a bit of effort to set up, needing no fewer than 5 primary Webpack plugins to get working properly, but the initial set up is well worth the effort. SCSS modules enable us to write compartmentalised styles, which can help make maintenance easier in the future as your application grows.

© 2023 — DeveloperHandbook.com — All rights reserved.

Источник

text

1. Introduce CSS into JS: style loader and CSS lodaer

The first part starts from the basic. In the scenario of not directly writing css to html, we need to parse and insert the css file as an independent module by webpack. At this time, we need style loader and css loader

$ yarn add style-loader css-lodaer -D

Next, we can directly import it into the JS file (take React as an example)

import React from 'react'; import './index.css'; const Test1 = () => < return ( 

Test1

); >; export default Test1;

2. From CSS to SCSS: sass loader + node sass

Next, the more css is written, it may be a little difficult to use, so next we choose Sass/Scss (of course, you prefer Less, which is the same)

$ yarn add sass-loader node-sass -D
import React from 'react'; import './index.scss'; const Test2 = () => < return ( 

Test2

); >; export default Test2;

3. CSS Module implements namespace isolation: CSS loader

However, scss is actually just a css syntax enhancement, but there will still be naming conflicts. At this time, we can choose to use the features of CSS Module (in fact, css loader has given relevant configuration properties, so no additional loader is required)

const config = < // . module: < rules: [ < test: /(\.module)?.(sass|scss)$/, use: [ 'style-loader', < loader: 'css-loader', options: < modules: < localIdentName: '[path][name]__[local]--[hash:base64:5]', >, sourceMap: true, >, >, 'sass-loader', ], >, ] >, // . >
import React from 'react'; import styles from './index.module.scss'; console.log('styles', styles); const Test3 = () => < return ( 
>

Test3

); >; export default Test3;

At this time, we can see that the name of css is added with directory information and even hash value, making it almost impossible for css names between multiple files to be duplicate

3.1 using CSS Module in typescript scenario

After using CSS Module, we need to use

import styles from './index.module.scss';

To get the correct style name, but ts can’t understand the. scss suffix file. At this time, we can create a type declaration file of styles.d.ts in the src directory

declare module '*.css' < const styles: < readonly Webpack css modules with sass: string >; export default styles; > declare module '*.scss' < const styles: < readonly Webpack css modules with sass: string >; export default styles; >

In this way, TS will no longer report errors

Bonus: pit record

If you encounter a lot of strange errors in the process of configuration, the following are some pits I have stepped on. You can check whether there are the same problems:

  • Node sass is not installed: to parse sass/scss, in addition to sass loader, node sass parser is also required to correctly parse the content
  • loader order: it’s an old saying, from back to front
  • Multiple similar configurations: one problem is that scss cannot repeatedly define rules in the same project, that is, it cannot decide to use CSS loader for some and not for others, otherwise a pile of incomprehensible error reports may be generated
  • The node sass download is slow enough: the reference link contains the method of configuring the yarn source repository

epilogue

This is the end of this article. In fact, it is about some configuration methods of webpack for your reference.

Other resources

Reference connection

Title Link
CSS loader — webpack official https://webpack.js.org/loaders/css-loader/
devtool — Webpack official https://webpack.js.org/configuration/devtool/
CSS Modules usage tutorial — Ruan Yifeng http://www.ruanyifeng.com/blog/2016/06/css_modules.html
Webpack introduces modules based on baseUrl and paths https://juejin.cn/post/6901081123078537224
typescript project css modules https://segmentfault.com/a/1190000021684206
yarn configure Ali source https://blog.csdn.net/qq_19107011/article/details/97992167

Complete code example

Posted by liduquan at Aug 07, 2021 — 10:29 AM Tag: Webpack sass css loader

Hot Categories

Hot Tags

  • Java × 8678
  • Python × 3398
  • Algorithm × 2157
  • Linux × 2069
  • Javascript × 1932
  • data structure × 1524
  • Spring × 1497
  • C++ × 1439
  • MySQL × 1163
  • Database × 1138
  • Front-end × 1057
  • Design Pattern × 1024

Источник

Оцените статью