我遇到了同样的问题,找到了以下方法来解决这个问题,你可以选择最适合你的
- 在 webpack 配置中定义两组用于解析 css/less 文件的规则。
- 第一条规则应该是包含所有全局样式,假设它保存在 /styles/ 或类似目录中。
- 第二条规则是处理所有局部范围的 css 样式,理想情况下,这些样式应位于其组件旁边。
- 您可以在定义规则时使用包含和排除选项来执行此操作
- 或者通过强制执行命名约定并相应地编写规则,例如所有 css 模块都将是[name].module.css并且您的测试将检查/.module.(less|css)$/并解析它。
下面给出一个示例:
// exclude all global styles for css modules
{
test: /\.(less|css)$/,
exclude: path.resolve(__dirname, './src/styles'),
use: [
{
loader: CssExtractPlugin.loader,
options: { hot: is_dev, reloadAll: is_dev }
},
{
loader: "css-loader",
options: {
modules: {
localIdentName: '[local]___[hash:base64:5]'
}
}
},
"postcss-loader",
"less-loader"
]
},
// process global styles without css modules
{
test: /\.(less|css)$/,
include: path.resolve(__dirname, './src/styles'),
use: [
{
loader: CssExtractPlugin.loader,
options: { hot: is_dev, reloadAll: is_dev }
},
"css-loader",
"postcss-loader",
"less-loader"
]
}
- 在编写 css/less 时使用:local 和 :global 。如果启用 css 模块,它将默认为本地模式,您可以在选项中指定模式,如下所示:
{
loader: "css-loader",
options: {
modules: {
localIdentName: '[local]___[hash:base64:5]',
mode: 'global',
}
}
},
如果您将模式定义为全局,则所有包含的 css 类都不会被散列名称替换,而只有您指定为 :local 的类将被赋予唯一名称。例如:
/* this will remain as is */
.header {
color: blue;
}
:local {
/* this will become something like item_xSH2sa */
.item {
color: yellow;
}
}
- 定义一个检查您的文件以确定它是 css 模块还是全局的函数,使用getLocalIdent选项完成。这是我目前在我的设置中使用的方法。这也要求你的文件有一些命名约定,[name].module.less用于 css 模块,[name].less 用于常规文件。请参见下面的示例:
// regex to test for modules, loaderUtils is part of webpack dependencies
const cssModuleRegex = new RegExp(/\.module\.(less|css)$/);
const loaderUtils = require("loader-utils");
// inside webpack rules
{
test: /\.(less|css)$/,
use: [
{
loader: CssExtractPlugin.loader,
options: { hot: is_dev, reloadAll: is_dev }
},
{
loader: "css-loader",
options: {
modules: {
localIdentName: '[local]___[hash:base64:5]',
getLocalIdent: getLocalIdent
}
}
},
"postcss-loader",
"less-loader"
]
}
// this is a copy of the default function, modified slightly to achieve our goal
function getLocalIdent(loaderContext, localIdentName, localName, options) {
// return local name if it's a global css file
if (!cssModuleRegex.test(loaderContext.resourcePath)) {
return localName;
}
if (!options.context) {
// eslint-disable-next-line no-param-reassign
options.context = loaderContext.rootContext;
}
const request = path
.relative(options.context, loaderContext.resourcePath)
.replace(/\\/g, '/');
// eslint-disable-next-line no-param-reassign
options.content = `${options.hashPrefix + request}+${localName}`;
// eslint-disable-next-line no-param-reassign
localIdentName = localIdentName.replace(/\[local\]/gi, localName);
const hash = loaderUtils.interpolateName(
loaderContext,
localIdentName,
options
);
return hash
.replace(new RegExp('[^a-zA-Z0-9\\-_\u00A0-\uFFFF]', 'g'), '-')
.replace(/^((-?[0-9])|--)/, '_$1');
}