2021.11.29 每天进步一点点:用你懂的方法,说说css-modules


前言

之前用react做开发时,简单用过css-modules 。但是也只是简单用过,并不了解。

以我浅薄的知识来说,我一直以为css-modules是一个库,或者是react绑定的一个插件。

然而, 都不是。 它只是css-loader中的一个功能罢了。

在需要用到时,再去开启。 当然, 这需要用到webpack配置项。

提到webpack,不要慌,因为配置确实很简单。后续内容会逐步解释。

以下将根据css-nodules在github的文档、并伴随demo进行解释。

开发工具版本
  • react: ^17.0.2
  • webpack: 1.14.0 (写博客的时候才发现是1.0版本…)
  • webpack-dev-server: 1.16.2

webpack配置

抛开实践而讨论问题本身,就是耍流氓。

所以,要想从实际意义上了解,就必须先会用。

要使用,就必须先做webpack配置。

css-modules依赖的是css-loader。 换句话说,要使用css-modules,就需要在css-loader中开启。

注意:本文只说明在react中的应用和配置,在其他框架中的使用方法,请参考最下方官方文档。(不清楚在其他框架中是否也这么用的…)

准备工作

css-modules是依赖css-loader的, 而css-loader又依赖style-loader ,所以,

如果未安装loader,需要先安装:

npm install css-loader --save

npm install style-loader --save

暴露webpack配置

webpack配置在react中是封装起来的。

需要运行npm run eject

把配置暴露出来。

运行后,是这样的文件结构:

在这里插入图片描述
/config下有两个webpack配置文件:

webpack.config.dev.js 对应开发环境的配置

webpack.config.prod.js 对应生产环境的配置

在dev环境的配置

/config/webpack.config/dev.js中找到这一段配置:

{
  test: /\.css$/,
  loader: 'style!css?importLoaders=1!postcss'
  },

把loader替换成如下配置:

{
  test: /\.css$/,
  loader: 'style!css-loader?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]',
 },

这一段配置的意思是:

开启样式模块化,在css-loader 之后指定1个数量的loader(即 postcss-loader)来处理import进来的资源,把类名转换成css文件名__类名__哈希值取base64编码的前五位

举个例子:

在index.css文件中,写一个类名为color的类:
在这里插入图片描述

转换后,类名变成了这样:
在这里插入图片描述

在生产模式的配置

在生产模式下,同样需要配置,

来到/config/webpack.config.prod.js进行配置:

找到这一段代码:

{
  test: /\.css$/,
  loader: ExtractTextPlugin.extract(
  'style',
  'css?importLoaders=1!postcss',
  extractTextPluginOptions
  )
  // Note: this won't work without `new ExtractTextPlugin()` in `plugins`.
  },

更改成如下:

{
  test: /\.css$/,
  loader: ExtractTextPlugin.extract(
    'style-loader',
    'css-loader?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]!postcss-loader',
    )
        // Note: this won't work without `new ExtractTextPlugin()` in `plugins`.
},

再往下找,可以看到这个配置,更改后如下:

new ExtractTextPlugin('style.css', { allChunks: true }),

这一步配置的意思是:

提出css样式,打包后放在style.css样式文件里。

allChunks设置为true,意思是异步css样式也会提取。

执行npm run build之后, 就可以看到提取到的文件了:

在这里插入图片描述

好了。 到这一步, 配置完成。 准备工作,初步做好。

看着写了那么长,其实总共就改了三行代码(*_^)


css-modules怎么用

先会用,再深入原理。 这是我的方法。

好处是, 可以一步步获取成就感, 学习兴趣更加。

在做深入了解后,能有更强的代入感。

不然的话,学了半天,不会用,感觉啥都不会, 肯定就扔一边去了23333…

我们来写个例子:

/src/index.js:

import React from 'react';
import ReactDOM from 'react-dom';
import styles from './index.css'; // 引入样式

function App() {
    console.log('styles-0: ', styles);
    return (
        <div>
        	// 使用样式
            <h3 className={styles.color}>hello react!</h3>
        </div>
    )
}

ReactDOM.render(
    <App />
    document.querySelector('#root')
);

/src/index.css

.color {
    color: red;
}

启动项目npm start

这时候就可以看到这样的效果:

在这里插入图片描述

可以看出,这里应用可以分为三步:

1, 写css样式。 就像我们平时写css一样。

2,引入样式
import styles from './index.css';

3,用样式
className={styles.color}

写法和应用都很符合日常的开发,不会有什么不适应。


styles是什么

看了上面的例子, 肯定会有这么一问:

styles是什么?

为什么引入的是styles?

className后面不是应该用'color'形式吗?

回头看上面的例子,我们在/src/index.js文件里,预留了一个打印语句:

console.log('styles-0: ', styles);

打开控制台,可以看到如下结果:

在这里插入图片描述
我们引入的文件,变成了styles对象,

对象的属性是我们自己写的类名,

属性的值是新生成的一个类名。

当我们用styles.color时,对应的结果就是新生成的类名。

这样有个好处,

就是我们需要用到哪个类名,就styles.类名即可。

不需要的类名,我们就可以不调用。

再看下标签里的类名是什么:

在这里插入图片描述

可以看到,标签里是通过webpack编译后生成的新类名了。

看到这里, 我们肯定对css-modules有一定的了解了。

那么,它到底是什么? 又是用来做啥的呢?


css-modules是啥
释义

根据官方文档:A CSS Module is a CSS file in which all class names and animation names are scoped locally by default 。 简而言之,一个css模块就是把所有类名和动画名,都放到一起形成局部范围样式的文件。

比如上面说的index.css就是被当作一个css模块进行引入的,生成了一个styles对象。

既然是模块化, 那么就可以引入。

引入

它有两种引入形式:

  • import styles from 'index.css'

  • url(...)

被当作模块引入后, 就会形成一个包含模块内所有样式的对象。 比如上面例子中的styles

命名

官方文档建议我们用驼峰命名法来给类名命名

比如.showWrap

主要是因为, 这些类名被引入后,都是放在一个对象里的。

我们要是调用对象里的属性,习惯于obj.aB

而不喜欢这样调用obj['a-b']对吧。

作用域转换

把局部作用域转换成全局作用域:

:global(类名)

如果是动画名称要转换为全局,可以这么用:

@keyframes:global(xxx)

把全局类名转换成局部类名:

:local(类名)

组合使用

语法:composes: xxx from './style.css'

写个demo验证一下:

还是用上面的例子,

我们再同样目录下,写一个index1.css

.backColor {
    background-color: darkkhaki;
}

index.css中进行组合使用:

.color {
    color: red;
    composes: backColor from './index1.css';
}

查看结果:

在这里插入图片描述

可以看到, 背景颜色发生了变化。 组合效果起了作用。


打包

用法和语法已经有了基本了解,

可以试着打包一下,

执行npm run build

可以看到生成的/build文件夹结构:

在这里插入图片描述


参考文档
  • css-modules in github: https://github.com/css-modules/css-modules
  • css-modules-webpackdemo for dev: https://github.com/css-modules/webpack-demo
  • css-modules-webpack prod: https://github.com/css-modules/webpack-demo/blob/master/webpack.config.js
  • https://www.ruanyifeng.com/blog/2016/06/css_modules.html
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值