storybook: Import Less not work.

Describe the bug Can’t import less file in JavaScript.

To Reproduce Steps to reproduce the behavior:

  1. Use Creaet-React-App create a default React template SPA
  2. cd <dir>, then Execute npx -p @storybook/cli sb init
  3. yarn add -D less less-loader
  4. modify .storybook/main.js:
  5. create 'src/stories/temp.less`, then write some style, and import it in story module:
import './temp.less';
span{background:black;}
// for test, it makes emojis container background in the template example Button story to be black

Expected behavior Import Less file successfully into story, then show styles defined by the less file.

Screenshots

I know the webpack doesn’t load less finally by devtools

image

However, when I wrote down options.errorFlag = true in rules delibrately, it throw a loader error, which proves it has already parse the imported less file. Why? 🤔

image

Code snippets

.storybook/main.js

const fs = require('fs')
const path = require('path')

module.exports = {
  stories: ['../src/**/*.stories.js'],
  addons: [
    '@storybook/preset-create-react-app',
    '@storybook/addon-actions',
    '@storybook/addon-links',
  ],
  webpackFinal: async (config, { configType }) => {
    config.module.rules.push({
      test: /\.less$/,
      use: [
        'style-loader',
        'css-loader',
        'resolve-url-loader',
        {
          loader: 'less-loader',
          options: {
            javascriptEnabled: true,
            sourceMap: true,
          }
        }]
    });
    return config;
  },
};

System:

  • System:
    • OS: Windows 10 10.0.18363
    • CPU: (8) x64 Intel® Core™ i5-8250U CPU @ 1.60GHz
  • Binaries:
    • Node: 12.14.0 - C:\Program Files\nodejs\node.EXE
    • Yarn: 1.19.2 - C:\Program Files\nodejs\yarn.CMD
    • npm: 6.4.1 - C:\Program Files\nodejs\npm.CMD
  • Browsers:
    • Chrome: 79.0.3945.131

Additional context

  • Storybook Version:

Using the newest stable 5.3.12.

If I change the .less extension to .css, it works! Why not less?

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 5
  • Comments: 15

Most upvoted comments

because cra’s file-loader intercept all other file, so the less file can’t go into less-loader; solution is to config the @storybook/preset-create-react-app; image there are some diffrent between storebook 5.3.0 and the 5.2.x ; can read https://github.com/storybookjs/presets/tree/master/packages/preset-create-react-app

I’ve been looking for the answers for a similar problem. In @storybook/preset-ant-design it mentions configuring CRA to exclude less from the file loader.

{
  "name": "@storybook/preset-create-react-app",
  "options": {
    "craOverrides": {
      "fileLoaderExcludes": ["less"]
    }
  }
}

May help.

I meet this problem too. This is my resolution.

{
  "@storybook/react": "^6.5.16"
  "@storybook/manager-webpack5": "^6.5.16"
  "@storybook/builder-webpack5": "^6.5.16",
  "less": "^4.1.3",
  "less-loader": "^11.1.0",
  "css-loader": "^6.7.3"
}
// main.js

webpackFinal: async (config) => {
    const lessLoaderChain = {
      test: /\.less$/,
      use: [
        'style-loader',
        'css-loader',
        {
          loader: 'less-loader',
          options: {
            lessOptions: {
              javascriptEnabled: true
            }
          }
        }
      ]
    }
    const oneOfRule = config.module.rules.find(rule => !!rule.oneOf);
    if (oneOfRule) {
      oneOfRule.oneOf.unshift(lessLoaderChain);
    } else {
      config.module.rules.unshift(lessLoaderChain);
    }
    
    return config;
},

Here’s an example using craco and semantic UI

module.exports = {
  stories: ['../src/**/*.stories.js'],
  addons: [
    '@storybook/preset-create-react-app',
    '@storybook/addon-actions',
    '@storybook/addon-links',
  ],
  webpackFinal: async (webpackConfig, { configType }) => {
    // `configType` has a value of 'DEVELOPMENT' or 'PRODUCTION'
    // You can change the configuration based on that.
    // 'PRODUCTION' is used when building the static version of storybook.
    const { loadCracoConfig } = require('@craco/craco/lib/config');
    const { getCraPaths } = require('@craco/craco/lib/cra');
    const context = {env: process.env.NODE_ENV};
    const cracoConfig = loadCracoConfig(context);
    context.paths = getCraPaths(cracoConfig);
    console.log(context);
    const {overrideWebpackConfig} = require('@semantic-ui-react/craco-less');
    overrideWebpackConfig({
      context,
      webpackConfig
    });

    // Return the altered config
    return webpackConfig;
  },
};

I find that less file was handled with file-loader or url-loader. But I don’t know how to fix this. 😢

import styles from './index.less'

console.log(style) // it's a url path

I have the same problem. I use index.module.lessmodule file which support in create-react-app 2.