Categories
Frontend React Webpack

How to setup Sass with Webpack

In previous posts we have been configuring Webpack / React / Babel and webpack-dev-server in order to run a very basic application.

I todays article I will teach you how to integrate Sass for doing the styling on the app.

If you are here without reading the previous post, I would recommend you to go ahead and read with, worst case scenario you will learn something new. If you already have your project, keep reading.

Step 1: Dependencies

We will need sass-loader, node-sass, css-loader, and style-loader. First I’ll try to explain how those libraries work, and then we will inject them into our webpack configuration.

Whenever webpack detects a scss or sass file it will process it with several loaders.

First we have scss-loader which it’s only task is to compiles sass into CSS. Internally scss-loader will need a sass compiler obviously, that compiler is written in C++ and is called LibSass. In order to make LibSass to work with our node app, we will need node-sass.

Then, after we have our CSS hot and ready we will pass it to the next player which is our css-loader. This loader will transform our CSS into CommonJS, yes you read it well, CSS into JavaScript. Remember that webpack produces a bundle.js file? Well, at the end of the day, everything needs to be JavaScript. css-loader will help us with that.

Finally, when we import our bundle.js created by webpack, we will need some instructions inside that bundle in order to import those javascript styles into real CSS again. That’s where style-loader will be handy.

Now that you know why we need those dependencies, let’s install them as dev dependencies.

npm install sass-loader css-loader style-loader node-sass --save-dev

Step 2: Loaders

We will user these loaders kind of how we did for .js files. Let’s add a new rule into our webpack configuration file.

# webpack.config.js
...
module: {
    rules: [
      {
        test: /\.s[ac]ss$/,
        exclude: /node_modules/,
        use: [
          'style-loader',
          'css-loader',
          'sass-loader'
        ]
      }
   ]
}
...

The Regex /.s[ac]ss$/ will help us to process any SCSS or SASS files

See how the loaders are in a certain order, that’s important because they act like a pipe in unix. The result of a loader is passed to the next one.

Step 3: SCSS

You can import Sass/SCSS files from any component from now on, let try to import a style file in our Homepage component.

I created a style inside public/stylesheets/styles.scss, our current file structure would be something like this.

index.html
package.json
webpack.config.js
public
-- stylesheets
---- styles.scss
---- index.js

Inside our index.js we created a component called MyComponent. Let’s import our styles.scss file there.

# public/index.js
...

import './stylesheets/styles.scss';

const MyComponent = () => {
  return (
    <div className='wrapper'>
      <h1>This is my first component</h1>
    </div>
  )
};

...

What will happen is, webpack will process the index.js file, and when it tries to resolve all the imports there, a scss file will be detected and all our loaders are going to take care of that.

I added a wrapper class to our main div of MyComponent, let’s add some basic styles just for testing.

# public/stylesheets/styles.scss

$main-color: #2B213A;
$wrapper-width: 90%;

body {
  font-family: 'Helvetica', 'Arial';
}

.wrapper {
  width: $wrapper-width;
  margin: auto;
  background-color: $main-color;
  padding: 20px;
  text-align: center;
  color: white;
}

Let’s run and open our app.

example component react

Vualá, the Scss file were compiled and injected inside our DOM. Open the Dev Tools and see where it was placed.

All the styles were placed inside a <style> tag, but we could use a different injection type like:

  • styleTag
  • singletonStyleTag
  • lazyStyleTag
  • lazySingletonStyleTag
  • linkTag

See the documentation for more details.

We are done for todays post, please if something wasn’t clear, let me know, send me a twitter DM, or leave a comment here in the post.

In the next post I will teach you how to split your CSS into a separate file than our bundle.js.