- How to configure SCSS modules for Webpack
- How to add support for SCSS and SCSS modules in Webpack
- Summary
- text
- 1. Introduce CSS into JS: style loader and CSS lodaer
- Test1
- 2. From CSS to SCSS: sass loader + node sass
- Test2
- 3. CSS Module implements namespace isolation: CSS loader
- Test3
- 3.1 using CSS Module in typescript scenario
- Bonus: pit record
- epilogue
- Other resources
- Reference connection
- Complete code example
- Hot Categories
- Hot Tags
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.
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;
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 (); >; export default Test1;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 (); >; export default Test2;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 (>); >; export default Test3;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