Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to import LESS files from specific path using webpack less-loader?

I'm putting a react project together using webpack and LESS for styling. I'm using the component style structure like so:

/root
    /src
        /components
           /MyComponent
               -index.js
               -index.less
       /styles
          -colors.less

I want each component to reference it's own styles via an import:

//MyComponent.js

import React from 'react';
import styles from './index.less';

...
<div className={styles.someclass} >
...

Within index.less I want to import the common shared styles. Something like:

//index.less

@import "styles/colors.js";

.someclass {
   background: @themecolor;
}

Here is how I have the webpack.config files set up for less:

     resolve: {
    alias: {
        components: path.resolve(__dirname, 'src', 'components'),
        reducers:     path.resolve(__dirname, 'src', 'reducers'),
        actions:      path.resolve(__dirname, 'src', 'actions'),
        styles:       path.resolve(__dirname, 'src', 'styles'),
        images:       path.resolve(__dirname, 'src', 'images'),
        pages:        path.resolve(__dirname, 'src', 'pages'),
        lib:          path.resolve(__dirname, 'src', 'lib'),
        utils:        path.resolve(__dirname, 'src', 'utils'),
        examples:     path.resolve(__dirname, 'src', 'examples')
    },
    extensions: ['', '.js','.jsx', '.css', 'png', 'less']
  }, 

module: {
    loaders: [
        { test: /\.jsx$/,
            loader: 'babel',
            include: path.join(__dirname, 'src')
        },
        { test: /\.js$/,
            loader: 'babel',
            exclude: /node_modules/

        },
        {
          test: /\.css$/,
            loader: "css-loader!autoprefixer-loader"
        },
        { 
          test: /\.less$/,
            loader: "style!css!autoprefixer!less"
        },
        { test: /\.png$/,
            loader: "url-loader?limit=10000&minetype=image/jpg"
        }
    ]
},

...

As you can see I make extensive use of Webpack's alias resolve feature, so I don't have to worry about relative paths all over the place.

The problem is I can't get the styles to import. I have tried every which way based on google searches including:

@import "~styles/colors.less";  //not sure what the ~ does?
@import "/styles/colors.less";
@import  "styles/colors.less";
@import "../../styles/colors.less";

Either it compiles but the styles don't show, or I get an error that the file can't be resolved.

Is there a way to get webpack to resolve these using aliases also? I really don't want to have to figure out the relative path here, if I can avoid it, because my nesting will get quite deep. I will if I have to though, to get it to work.

How do I do this?

like image 520
Coco Avatar asked May 12 '16 19:05

Coco


People also ask

How do you use webpack less?

webpack.config.js less$/i, use: [ "style-loader", { loader: "css-loader", options: { sourceMap: true, }, }, { loader: "less-loader", options: { sourceMap: true, }, }, ], }, ], }, }; If you want to edit the original Less files inside Chrome, there's a good blog post.

When using webpack Why do we need loader?

They allow you to pre-process files as you import or “load” them. Thus, loaders are kind of like “tasks” in other build tools and provide a powerful way to handle front-end build steps. Loaders can transform files from a different language (like TypeScript) to JavaScript or load inline images as data URLs.


2 Answers

~ is a webpack less-loader convenience for loading less file from node_modules folder. check https://github.com/webpack-contrib/less-loader#imports

like image 97
tjfdfs Avatar answered Sep 20 '22 13:09

tjfdfs


You're half way there. Provided we have /styles under root, add the following resolve in your webpack config:

const path = require('path')

module.exports = {
  module: {
    rules: [
      {
        test: /\.less$/,
        use: [
          ...
          {
            loader: 'less-loader',
            options: {
              lessOptions: {
                paths: [path.resolve(__dirname)],     <------ here
              },
            },
          },
        ],
      },
    ],
  },
};

Then import with a path prefixed with ~:

@import "~styles/reset.less";

not sure what the ~ does?

~ allows you to import from a default node_modules plus any number of resolved paths you add into webpack config up there.

Alternatively if you want to import from /src under root, throw in a second parameter, as in:

paths: [path.resolve(__dirname, 'src')]
like image 30
Lucia Avatar answered Sep 19 '22 13:09

Lucia