起因
自己在用 react-create-app
脚手架创建项目时,用到less
模块化导入,即import styles from './login.module.less'
,发现自己在TSX
中引用时报错。
初始条件,自己可以参照 antd
官网,我是用的typescript
写的
yarn add @craco/craco
然后在项目根目录创建一个 craco.config.js
用于修改默认配置
自己网上百度参考,然后自己总结了如下改动,希望能帮到你
第一种方式
简单粗暴;自己发现craco-less
,这个插件默认排除了 /\.module\.(less)$/
;详细的自己可以研究下craco-less
源码
/* 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')
}
}
}
直接重写less
规则
localIdentName
解释
支持的模板字符串:
[name]
源文件名称[path]
源文件相对于compiler.context
或者modules.localIdentContext
配置项的相对路径。[file]
- 文件名和路径。[ext]
- 文件拓展名。[hash]
- 字符串的哈希值。基于localIdentHashSalt
、localIdentHashFunction
、localIdentHashDigest
、localIdentHashDigestLength
、localIdentContext
、resourcePath
和exportName
生成。[<hashFunction>:hash:<hashDigest>:<hashDigestLength>]
- 带有哈希设置的哈希。[local]
- 原始类名
建议:
- 开发环境使用
'[path][name]__[local]'
- 生产环境使用
'[hash:base64]'
第二种方式
/* 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')
}
}
}
cacro Less导入全局变量
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
)
完整配置
/* 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')
}
}
}
mock-api
yarn add mock-api
,接下来就是配置了,在根目录下新建一个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
}
}
mock/index.ts
const proxy = {
'GET /menu': {
test: 'menu'
}
}
module.exports = proxy
craco.config.js
const devServerConfig = require('./overrideDevServerConfig')
module.exports = {
plugins: [
{
plugin: CracoAntDesignPlugin,
options: {
customizeTheme: {
'@primary-color': '#1DA57A'
}
}
},
{
plugin: devServerConfig,
options: { preText: 'Will log the craco config:' }
}
],
webpack: {
alias: {
'@': resolve(__dirname, 'src')
}
}
}