less-loader, css-modules配置
配置结果分享
配置好的文件和测试案例,都已经上传到gitee , 仓库地址:
https://gitee.com/guozia007/css-modules-lessloader
如以下配置过程有不明确的地方,可以查看该分享内容。
准备工作
默认已经安装了react最新版脚手架
暴露webpack配置
react的webpack配置是默认隐藏的,封装在react脚手架包里。
要想加入自己的配置,需要暴露出webpack文件。
npm run eject
会显示出默认的配置文件:
里面有个webpack.config.js 文件,就是我们要写自己的配置的地方。
版本说明
React: ^17.0.2
webpack: 4.44.2
如果版本不同,可能会出现配置方法不一致的情况。
如果暴露出的webpack文件有两个,分别是webpack.config.dev.js 和webpack.config.prod.js ,这是老的脚手架版本,你大概需要这么配置css-modules:
https://blog.csdn.net/tuzi007a/article/details/121617342?spm=1001.2014.3001.5501
配置less-loader
安装less和less-loader
npm install less --save
npm install less-loader@5.0.0 --save
注:
less-loader不选择版本时,默认安装10.x版本。
而该版本不支持lessOptions的方法,会出现报错:
./src/index.less (./node_modules/css-loader/dist/cjs.js??ref--5-oneOf-8-1!./node_modules/postcss-loader/src??postcss!./node_modules/resolve-url-loader??ref--5-oss) TypeError: this.getOptions is not a function
所以安装less-loader时,应选择合适的版本。
本人测试了10.0.0-6.0.0都不支持。 测试了5.0.0版本,是支持的。
配置方法
以下内容均在webpack.config.js 文件中操作,
所以以下提到的内容,都去该文件中找到和修改。
找到如下语句:
const cssRegex = /\.css$/;
const cssModuleRegex = /\.module\.css$/;
复制后放在这个语句后面,
并把css 换成less :
即 less语句如下,可直接复制后添加进去:
const lessRegex = /\.less$/;
const lessModuleRegex = /\.module\.less$/;
找到如下语句:
const getStyleLoaders = (cssOptions, preProcessor) => {
const loaders = [...
在cssOptions 后添加 lessOptions
该语句就变成了这样:
const getStyleLoaders = (cssOptions, lessOptions, preProcessor) => {
const loaders = [...
同时,紧挨着下面 找到语句:
{
loader: require.resolve('css-loader'),
options: cssOptions,
},
并把下面这一句,添加到上一句的下面。
{
loader: require.resolve('less-loader'),
options: lessOptions,
},
结果如下:
找到这一段代码:
{
test: sassRegex,
exclude: sassModuleRegex,
use: getStyleLoaders(
{
importLoaders: 3,
sourceMap: isEnvProduction
? shouldUseSourceMap
: isEnvDevelopment,
},
'sass-loader'
),
sideEffects: true,
},
{
test: sassModuleRegex,
use: getStyleLoaders(
{
importLoaders: 3,
sourceMap: isEnvProduction
? shouldUseSourceMap
: isEnvDevelopment,
modules: {
getLocalIdent: getCSSModuleLocalIdent,
},
},
'sass-loader'
),
},
复制上面代码, 把sass 改成less ,然后把修改好的代码添加到该代码下面,
修改后的代码如下:
{
test: lessRegex,
exclude: lessModuleRegex,
use: getStyleLoaders(
{
importLoaders: 3,
sourceMap: isEnvProduction
? shouldUseSourceMap
: isEnvDevelopment,
},
'less-loader'
),
sideEffects: true,
},
{
test: lessModuleRegex,
use: getStyleLoaders(
{
importLoaders: 3,
sourceMap: isEnvProduction
? shouldUseSourceMap
: isEnvDevelopment,
modules: {
getLocalIdent: getCSSModuleLocalIdent,
},
},
'less-loader'
),
},
到此,less , less-loader配置完成。配置完成后, 需要重启项目。
案例测试
写个带有less语法的例子,测验一下,less配置是否可以用。
/src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.less';
function App() {
return (
<div>
<h3 className="color1">hello react!</h3>
</div>
)
}
ReactDOM.render(
<div>
<App />
</div>,
document.querySelector('#root')
)
/src/index.less
@def: pink;
.color1 {
color: @def;
}
重启项目,npm start
页面内字体颜色显示粉红色,则说明配置正常。
最简单的模块化
最简单的方法,就是啥配置项都不改动的方法。这是脚手架2.0版默认支持的,不需要任何配置,所以也不需要暴露webpack文件。
只需要改动css/less文件的文件名,即可实现样式的模块化。
原因是,react的默认配置里,已经打开了模块化设置,只不过是对文件名有要求, 需要把文件名写作xx.module.css 或者 xx.module.less 的形式。
写个案例测试一下,还用上面写过的例子。然后我们做如下改动:
- 1,改样式文件名:
index.less --> index.module.less - 2,改动引入方式:
import './index.module.less'; --> import styles from './index.module.less'; - 3,改动标签内类名写法:
<h3 className="color1">hello react!</h3> --> <h3 className={styles.color1}>hello react!</h3>
此时,重启项目。 npm start
可以查看到,页面的字体依然为粉红色。
而且,重点是:
打开控制台,可以看到, 这里的类名变了。 变成了 一种文件名_类名__hash值(截取前5位) 的格式。
也就是说, 这时, 已经实现了样式的模块化。
但是,为了习惯上的样式文件名, 怎么做既能不改动样式文件名, 又能实现样式模块化呢?这时,我们就想到了上面的auto 选项的值。
配置css-loader实现css-modules
css-modules不是单独的库,也不是插件,而是css-loader中的一个可选项,激活该可选项,即可实现样式的模块化,且无需改动原有的文件名。
既然需要自己配置,我们就需要自己打开该功能。
找到这几项代码,css less sass分别有一项,应该是一共有3项这种代码:
test: --ssRegex,
exclude: --ssModuleRegex,
use: getStyleLoaders({
importLoaders: --,
sourceMap: isEnvProduction
? shouldUseSourceMap
: isEnvDevelopment,
}),
把这里都做如下修改:
test: --ssRegex,
exclude: --ssModuleRegex,
use: getStyleLoaders({
importLoaders: --,
modules: true,
sourceMap: isEnvProduction
? shouldUseSourceMap
: isEnvDevelopment,
}),
modules: true, 意思是打开css-modules功能。不需要把文件命名为.modules.xx 的形式了。
当然,为了类名更符合规则,我们还需要做其他更改,把上面的代码改成如下形式:
test: cssRegex,
exclude: cssModuleRegex,
use: getStyleLoaders({
importLoaders: 1,
modules: {
mode: "local",
localIdentName: "[path][name]__[local]--[hash:base64:5]",
},
sourceMap: isEnvProduction
? shouldUseSourceMap
: isEnvDevelopment,
}),
localIdentName 这里表示编译后的类名规则。
path: 文件路径
name: 文件名
local: 类名
hash:base64:5 表示 取base64字符串的前五位
写个案例测试一下吧:
我们仍然用上述案例,
只不过这次把文件名中的module去掉,
index.module.less --> index.less
修改后,重启项目:
可以看到,页面字体颜色呈现粉红色。
打开控制台,还可以看到新的类名:
至此,我们的css-modules配置,也已经完成。
其他参数配置
以上配置满足了基本的css-modules使用。如果需要其他配置,可以参考官方资料的案例:
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
loader: "css-loader",
options: {
modules: {
mode: "local",
auto: true,
exportGlobals: true,
localIdentName: "[path][name]__[local]--[hash:base64:5]",
localIdentContext: path.resolve(__dirname, "src"),
localIdentHashSalt: "my-custom-hash",
namedExport: true,
exportLocalsConvention: "camelCase",
exportOnlyLocals: false,
},
},
},
],
},
};
这里面列举出了很多可配置项。 都在加在上面modules对象里的。
参考资料
- 老版本webpack配置文档
https://github.com/css-modules/webpack-demo - css-loader官方说明
https://github.com/webpack-contrib/css-loader - 官方less-loader文档
https://webpack.docschina.org/loaders/less-loader/
|