question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

with-ant-design-less can't work together with cssModule

See original GitHub issue

Examples bug report

Example name

with-ant-design-less

Describe the bug

Using ant-design-less with cssModule makes all ant design style disappear.

To Reproduce

  1. Go to ‘next.config.js’
  2. Add this code snippets into withLess option
cssModules: true,
cssLoaderOptions: {
  importLoaders: 1,
  localIdentName: '[local]___[hash:base64:5]',
},
  1. Save
  2. All ant design style is gone

Expected behavior

The example should apply ant design style when cssModule option is set to true.

Screenshots

Before apply cssModule Screen Shot 2562-07-29 at 16 35 22

After apply cssModule Screen Shot 2562-07-29 at 16 36 41

System information

  • OS: macOS
  • Browser: Any browser
  • Version of Next.js: 9.0.2

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Reactions:5
  • Comments:7 (2 by maintainers)

github_iconTop GitHub Comments

28reactions
phakphumicommented, Jul 29, 2019

After taking the time to research I found that setting cssModule to true turn the whole project to use cssModule but some node_modules like antd doesn’t implement by using cssModule.

So, I customized @zeit/next-less to support work like this.

next-antd-less.config.js

var cssLoaderConfig = require('@zeit/next-css/css-loader-config');

module.exports = (nextConfig = {}) => {
  return Object.assign({}, nextConfig, {
    webpack: (config, options) => {
      if (!options.defaultLoaders) {
        throw new Error(
          'This plugin is not compatible with Next.js versions below 5.0.0 https://err.sh/next-plugins/upgrade'
        );
      }

      const { dev, isServer } = options;
      const {
        cssModules,
        cssLoaderOptions,
        postcssLoaderOptions,
        lessLoaderOptions = {},
      } = nextConfig;

      options.defaultLoaders.less = cssLoaderConfig(config, {
        extensions: ['less'],
        cssModules,
        cssLoaderOptions,
        postcssLoaderOptions,
        dev,
        isServer,
        loaders: [
          {
            loader: 'less-loader',
            options: lessLoaderOptions,
          },
        ],
      });

      config.module.rules.push({
        test: /\.less$/,
        exclude: /node_modules/,
        use: options.defaultLoaders.less,
      });

      // disable antd css module
      config.module.rules.push({
        test: /\.less$/,
        include: /node_modules/,
        use: cssLoaderConfig(config, {
          extensions: ['less'],
          cssModules: false,
          cssLoaderOptions: {},
          dev,
          isServer,
          loaders: [
            {
              loader: 'less-loader',
              options: lessLoaderOptions,
            },
          ],
        }),
      });

      if (isServer) {
        const antStyles = /antd\/.*?\/style.*?/;
        const origExternals = [...config.externals];
        config.externals = [
          (context, request, callback) => {
            if (request.match(antStyles)) return callback();
            if (typeof origExternals[0] === 'function') {
              origExternals[0](context, request, callback);
            } else {
              callback();
            }
          },
          ...(typeof origExternals[0] === 'function' ? [] : origExternals),
        ];
  
        config.module.rules.unshift({
          test: antStyles,
          use: 'null-loader',
        });
      }

      if (typeof nextConfig.webpack === 'function') {
        return nextConfig.webpack(config, options);
      }

      return config;
    }
  });
};

then use it in next.config.js

const withNextAntdLess = require('./next-antd-less.config');
module.exports = withNextAntdLess({
    cssModules: true,
    cssLoaderOptions: {
      importLoaders: 1,
      localIdentName: '[local]___[hash:base64:5]',
    },
})

In my case, it usually works. Hopefully, It will help someone to solve the problem to work with antd together with cssModule.

Related example/issues/modules which I use to compose the solution. #8054 #7957 with-ant-design-less next-antd-aza-less

Anyway, if there is an official solution for this issue it will be very good. In my opinion, it will be a common issue.

4reactions
phucvo0709commented, Aug 13, 2019

After taking the time to research I found that setting cssModule to true turn the whole project to use cssModule but some node_modules like antd doesn’t implement by using cssModule.

So, I customized @zeit/next-less to support work like this.

next-antd-less.config.js

var cssLoaderConfig = require('@zeit/next-css/css-loader-config');

module.exports = (nextConfig = {}) => {
  return Object.assign({}, nextConfig, {
    webpack: (config, options) => {
      if (!options.defaultLoaders) {
        throw new Error(
          'This plugin is not compatible with Next.js versions below 5.0.0 https://err.sh/next-plugins/upgrade'
        );
      }

      const { dev, isServer } = options;
      const {
        cssModules,
        cssLoaderOptions,
        postcssLoaderOptions,
        lessLoaderOptions = {},
      } = nextConfig;

      options.defaultLoaders.less = cssLoaderConfig(config, {
        extensions: ['less'],
        cssModules,
        cssLoaderOptions,
        postcssLoaderOptions,
        dev,
        isServer,
        loaders: [
          {
            loader: 'less-loader',
            options: lessLoaderOptions,
          },
        ],
      });

      config.module.rules.push({
        test: /\.less$/,
        exclude: /node_modules/,
        use: options.defaultLoaders.less,
      });

      // disable antd css module
      config.module.rules.push({
        test: /\.less$/,
        include: /node_modules/,
        use: cssLoaderConfig(config, {
          extensions: ['less'],
          cssModules: false,
          cssLoaderOptions: {},
          dev,
          isServer,
          loaders: [
            {
              loader: 'less-loader',
              options: lessLoaderOptions,
            },
          ],
        }),
      });

      if (isServer) {
        const antStyles = /antd\/.*?\/style.*?/;
        const origExternals = [...config.externals];
        config.externals = [
          (context, request, callback) => {
            if (request.match(antStyles)) return callback();
            if (typeof origExternals[0] === 'function') {
              origExternals[0](context, request, callback);
            } else {
              callback();
            }
          },
          ...(typeof origExternals[0] === 'function' ? [] : origExternals),
        ];
  
        config.module.rules.unshift({
          test: antStyles,
          use: 'null-loader',
        });
      }

      if (typeof nextConfig.webpack === 'function') {
        return nextConfig.webpack(config, options);
      }

      return config;
    }
  });
};

then use it in next.config.js

const withNextAntdLess = require('./next-antd-less.config');
module.exports = withNextAntdLess({
    cssModules: true,
    cssLoaderOptions: {
      importLoaders: 1,
      localIdentName: '[local]___[hash:base64:5]',
    },
})

In my case, it usually works. Hopefully, It will help someone to solve the problem to work with antd together with cssModule.

Related example/issues/modules which I use to compose the solution. #8054 #7957 with-ant-design-less next-antd-aza-less

Anyway, if there is an official solution for this issue it will be very good. In my opinion, it will be a common issue.

how to add withSass in config

Read more comments on GitHub >

github_iconTop Results From Across the Web

Module.css is not working in React.So css can't proceed either ...
As shown in the picture above, classname was assigned to the div tag, but there was a problem that could not be applied...
Read more >
Using CSS Module Scripts to import stylesheets - web.dev
With the new CSS module scripts feature, you can load CSS style sheets with import statements, just like JavaScript modules.
Read more >
What are CSS Modules and why do we need them?
I've been intrigued by CSS Modules lately. If you haven't heard of them, this post is ... First, remember how HTML and CSS...
Read more >
How to configure CSS Modules for webpack - LogRocket Blog
In the following code block, css-loader and style-loader are used together. Similar to babel-loader , we can load CSS files to style our...
Read more >
Using CSS Modules in React - OpenReplay Blog
A different way to work with CSS styling in React apps. ... random CSS classes that are only visible when the page is...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found