Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using .less files with React

Tags:

reactjs

less

I am trying to use .less files with a minimalist React app (created with create-react-app). I've added less and less-loader to my package.json as well as a module rule in my webpack.config.js file. The class reference is not being added to the HTML element however (should have class="customColor").

<p>Hello world in a custom color.</p>

I'm wondering what I'm doing wrong.

App.js

import React from 'react';
import './App.css';
import styles from './custom.less';

function App() {
  return (
    <div className="App">
      <header className="App-header">
        <p className={styles.customColor}>
          Hello world in a custom color.
        </p>
      </header>
    </div>
  );
}

export default App;

custom.less

@custom-color: red;

.customColor {
  color: @custom-color;
}

package.json

{
  "name": "sample",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "react": "^16.9.0",
    "react-dom": "^16.9.0",
    "react-scripts": "3.1.1"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": "react-app"
  },
  "devDependencies": {
    "less": "^3.10.3",
    "less-loader": "^5.0.0"
  }
}

webpack.config.js

module.exports = {
    rules: [{
        test: /\.less$/,
        use: [{
            loader: 'style-loader',
        }, {
            loader: 'css-loader', // translates CSS into CommonJS
        }, {
            loader: 'less-loader', // compiles Less to CSS
        }],
    }],
}
like image 548
Joe P Avatar asked Sep 01 '19 21:09

Joe P


3 Answers

If you're using CRA, I would suggest going without ejecting.

First install less, less-watch-compiler and concurrently:

npm install less less-watch-compiler concurrently --save-dev

Then in your root directory create less-watcher.config.json and set the configuration:

{
    "watchFolder": "src/",
    "outputFolder": "src/",
    "runOnce": false,
    "enableJs": true
}

Rename App.css to App.less

Replace start script in package.json with the following:

"scripts": {
    "start": "concurrently --kill-others \"less-watch-compiler --config less-watcher.config.json\" \"react-scripts start\"",
    "build": "react-scripts build",
    ....
}

and run the application. Enjoy :)

like image 134
Maksym Koshyk Avatar answered Sep 22 '22 20:09

Maksym Koshyk


to use less files in a react project created with create-react-app follow these steps:

  1. npm run eject
  2. npm i less less-loader
  3. open webpack.config.js file located at config folder created after eject script:

look at the return value of exported function(that's the main config)

find where last style-loader added which is sass-loader

       {
          test: sassModuleRegex,
          use: getStyleLoaders(
            {
              importLoaders: 3,
              sourceMap: isEnvProduction && shouldUseSourceMap,
              modules: {
                getLocalIdent: getCSSModuleLocalIdent,
              },
            },
            'sass-loader'
          ),
        },

and add less-loader under sass-loader like this:

       {
          test: sassModuleRegex,
          use: getStyleLoaders(
            {
              importLoaders: 3,
              sourceMap: isEnvProduction && shouldUseSourceMap,
              modules: {
                getLocalIdent: getCSSModuleLocalIdent,
              },
            },
            'sass-loader'
          ),
        },
        {
          test: /\.less$/,
          use: getStyleLoaders(
            {
              modules: true,
              importLoaders: 3,
              sourceMap: isEnvProduction && shouldUseSourceMap,
            },
            'less-loader'
          ),
          // Don't consider CSS imports dead code even if the
          // containing package claims to have no side effects.
          // Remove this when webpack adds a warning or an error for this.
          // See https://github.com/webpack/webpack/issues/6571
          sideEffects: true,
        },

importLoaders option inside less-loader should be 3.

two loaders from getStyleLoaders + our less-loader.

The option importLoaders allows you to configure how many loaders before css-loader should be applied to @imported resources.

why module option is true?

// index.less file

.header {
  background-color: skyblue;
}

if you want to use stylesheet file like this:

import styles from './index.less';

<div className={styles.header}></div>

you should set modules: true

but if you want to use it like below:

import './index.less';

<div className="header"></div>

you should set modules: false

like image 34
armin yahya Avatar answered Sep 20 '22 20:09

armin yahya


CRA (Create React App) by default supports only SASS and CSS if you want to use LESS you need to do npm run eject first and then modify webpack configs.

However there is a way to do that w/o ejecting tho I have to say I personally prefer ejecting. You can find instructions here

like image 32
Edward Chopuryan Avatar answered Sep 23 '22 20:09

Edward Chopuryan