The cause of

Less module import styles from ‘./login.module.less’ when creating a project using the React-create-app scaffolding, I found myself quoting an error in TSX.

The initial conditions can be found on the ANTD website. I’m writing in typescript

yarn add @craco/craco
Copy the code

Then create a craco.config.js file in the project root directory to modify the default configuration

Their online baidu reference, and then summed up the following changes, I hope to help you

The first way

Simple and crude; /\.module\.(less)$/; Detailed you can study the craco-less source code

/* eslint-disable @typescript-eslint/no-var-requires */
const CracoAntDesignPlugin = require('craco-antd')
const CracoLessPlugin = require('craco-less')
const { resolve } = require('path')

module.exports = {
  plugins: [
    {
      plugin: CracoAntDesignPlugin,
      options: {
        customizeTheme: {
          '@primary-color': '#1DA57A'
        }
      }
    },
    {
      plugin: CracoLessPlugin,
      options: {
        modifyLessRule: (lessRule, context) => {
          return {
            test: /\.less$/,
            use: [
              'style-loader',
              {
                loader: 'css-loader',
                options: {
                  modules: 
                    localIdentName: '[path][name]__[local]'
                  }
                }
              },
              'less-loader'
            ]
          }
        }
      }
    }
  ],
  webpack: {
    alias: {
      '@': resolve(__dirname, 'src')
    }
  }
}
Copy the code

Rewrite the less rule directly

LocalIdentName Explains supported template strings:

  • [name]Source file name
  • [path]Source file relative tocompiler.contextormodules.localIdentContextRelative path of configuration items.
  • [file]– File name and path.
  • [ext]– File extension name.
  • [hash]– Hash value of a string. Based on thelocalIdentHashSalt,localIdentHashFunction,localIdentHashDigest,localIdentHashDigestLength,localIdentContext,resourcePath 和 exportNameGenerated.
  • [<hashFunction>:hash:<hashDigest>:<hashDigestLength>]– Hash with hash Settings.
  • [local]– Original class name

Advice:

  • Development environment Usage'[path][name]__[local]'
  • Use in production environment'[hash:base64]'

The second way

/* eslint-disable @typescript-eslint/no-var-requires */
const CracoAntDesignPlugin = require('craco-antd')
const { resolve } = require('path')


/* craco-plugin-webpack-config.js */
const lessConfig = {
  overrideWebpackConfig: ({
    webpackConfig,
    cracoConfig,
    pluginOptions,
    context: { env, paths }
  }) => {
    if (pluginOptions.preText) {
      console.log(pluginOptions.preText)
    }
    const oneOfRule = webpackConfig.module.rules.find((rule) => rule.oneOf)
      
    oneOfRule.oneOf.push({
      test: /\.module\.(less)$/,
      use: [
        {
          loader: 'style-loader'
        },
        {
          loader: 'css-loader',
          options: {
            importLoaders: 3,
            sourceMap: true,
            modules: {
              localIdentName: '[path][name]__[local]'
            }
          }
        },
        'less-loader'
      ]
    })

    // Always return the config object.
    return webpackConfig
  }
}

module.exports = {
  plugins: [
    {
      plugin: CracoAntDesignPlugin,
      options: {
        customizeTheme: {
          '@primary-color': '#1DA57A'
        }
      }
    },
    {
      plugin: lessConfig,
      options: { preText: 'Will log the craco config:' }
    }
  ],
  webpack: {
    alias: {
      '@': resolve(__dirname, 'src')
    }
  }
}

Copy the code

Cacro Less imports global variables

const {
  getLoader,
  loaderByName,
  addBeforeLoader,
  addAfterLoader,
  throwUnexpectedConfigError
} = require('@craco/craco')

const styleResourcesLoader = {
  loader: 'style-resources-loader',
  options: {
    patterns: resolve(__dirname, './src/styles/index.less'),
    injector: 'append'
  }
}
addAfterLoader(
  webpackConfig,
  loaderByName('less-loader'),
  styleResourcesLoader
)
Copy the code

Complete configuration

/* eslint-disable @typescript-eslint/no-var-requires */
const CracoAntDesignPlugin = require('craco-antd')
const CracoLessPlugin = require('craco-less')
const { resolve } = require('path')
const {
  getLoader,
  loaderByName,
  addBeforeLoader,
  addAfterLoader
} = require('@craco/craco')

/* craco-plugin-log-webpack-config.js */
const lessConfig = {
  overrideWebpackConfig: ({
    webpackConfig,
    cracoConfig,
    pluginOptions,
    context: { env, paths }
  }) => {
    if (pluginOptions.preText) {
      console.log(pluginOptions.preText)
    }

    const oneOfRule = webpackConfig.module.rules.find((rule) => rule.oneOf)

    const styleResourcesLoader = {
      loader: 'style-resources-loader',
      options: {
        patterns: resolve(__dirname, './src/styles/index.less'),
        injector: 'append'
      }
    }
    addAfterLoader(
      webpackConfig,
      loaderByName('less-loader'),
      styleResourcesLoader
    )
    oneOfRule.oneOf.push({
      test: /\.module\.(less)$/,
      use: [
        {
          loader: 'style-loader'
        },
        {
          loader: 'css-loader',
          options: {
            importLoaders: 3,
            sourceMap: true,
            modules: {
              localIdentName: '[name]__[local]'
            }
          }
        },
        'less-loader'
      ]
    })

    console.log(oneOfRule.oneOf)
    // Always return the config object.
    return webpackConfig
  }
}

module.exports = {
  plugins: [
    {
      plugin: CracoAntDesignPlugin,
      options: {
        customizeTheme: {
          '@primary-color': '#1DA57A'
        }
      }
    },
    {
      plugin: lessConfig,
      options: { preText: 'Will log the craco config:' }
    }
  ],
  webpack: {
    alias: {
      '@': resolve(__dirname, 'src')
    }
  }
}
Copy the code

mock-api

Yarn add mock – API, the following is the configuration, in the root directory to create a new overrideDevServerConfig. Js

overrideDevServerConfig.js

/* eslint-disable @typescript-eslint/no-var-requires */
const apiMocker = require('mocker-api')
const { resolve } = require('path')

module.exports = {
  overrideDevServerConfig: ({
    devServerConfig,
    cracoConfig,
    pluginOptions,
    context: { env, paths, allowedHost }
  }) => {
    if (pluginOptions.preText) {
      console.log(pluginOptions.preText)
    }

    devServerConfig.port = 3003
    devServerConfig.before = (app, server, compiler) => {
      apiMocker(app, resolve(__dirname, './mock/index.ts'))
    }

    // Always return the config object.
    return devServerConfig
  }
}

Copy the code

mock/index.ts

const proxy = {
  'GET /menu': {
    test: 'menu'
  }
}

module.exports = proxy

Copy the code

craco.config.js

const devServerConfig = require('./overrideDevServerConfig')
Copy the code
module.exports = {
  plugins: [
    {
      plugin: CracoAntDesignPlugin,
      options: {
        customizeTheme: {
          '@primary-color': '#1DA57A'
        }
      }
    },
    {
      plugin: devServerConfig,
      options: { preText: 'Will log the craco config:' }
    }
  ],
  webpack: {
    alias: {
      '@': resolve(__dirname, 'src')
    }
  }
}
Copy the code

Refer to the link

Reference 1

Reference 2

Reference 3

Reference 4