前言
CSS 是前端领域中进化最慢的一块。在 React 中使用 css 是一件很痛苦的事情。从 从原生 css 到 css modules
到 CSS in JS
。各种解决方案层出不穷。
总结起来主要有两类:
- 彻底抛弃 CSS,使用 JS 或 JSON 来写样式,如时下的新宠
styled-components
(github上两万多star),还有styled-jsx
,react-style
等属于CSS in JS
这一类。优点是能给 CSS 提供 JS 同样强大的模块化能力。 - 依旧使用 CSS,但使用 JS 来管理样式依赖,代表是
CSS Modules
。CSS Modules
能最大化地结合现有 CSS 生态(预处理器/后处理器等)和 JS 模块化能力,几乎零学习成本。只要你使用 Webpack,可以在任何项目中使用。是目前最好的 CSS 模块化解决方案。这篇文章要介绍的babel-plugin-react-css-modules
就是一个CSS模块化的轻量级解决方案。
为什么要有CSS Modules
CSS Modules 模块化方案
CSS Modules
并不是React专用解决方法,适用于所有使用 webpack 等打包工具的开发环境。以 webpack 为例,在 css-loader
的 options 里打开modules:true
选项即可使用 Css Modules
。
一般配置如下1
2
3
4
5
6
7
8{
loader: "css-loader",
options: {
importLoaders: 1,
modules: true,
localIdentName: "[local]___[hash:base64:5]" // 为了生成类名不是纯随机
},
}
使用方式
1 | import React from 'react'; |
像这样,每次都要用style.xxx这种方式来写,如果有多个class还需通过字符串模板拼接,还可一使用classnames
动态控制样式的显示。1
2
3
4
5
6
7npm install classnames
import styles from './styles.css'
import classNames from 'classnames'
<div className={ styles.theTitle }>something</div>
<div className={ classNames(styles.theTitle, styles.title) }>something</div>
能不能更简单??? 终于到babel-plugin-react-css-modules
出场了。
babel-plugin-react-css-modules
先来个对比,className
换成styleName
就ok了,其他跟使用className
一样,有没有很简单1
2
3
4
5
6
7
8
9// css-modules
import styles from './styles.css'
<div className={ styles.theTitle }>something</div>
// babel-plugin-react-css-modules
import './styles.css'
<div styleName="the-title">something</div>
官方链接最早是react-css-modules这个插件,作者后来又开发了这个使用起来更为方便的新插件。配置起来也很简单。
安装依赖
需要注意的是,babel-plugin-react-css-modules有一个运行时依赖,所以用–save安装比较好1
npm i --save babel-plugin-react-css-modules
配置
配置主要注意一下两点:
- 配置项中的
generateScopedName
的作用和css-loader
中的localIdentName
是一样的,都是设置编译之后的类名的格式。generateScopedName
和localIdentName
必须要配置,并且值必须相同。否则即使编译成功,不报错,也还是无法达到预期效果。 - context要和webpack中context的配置一直,默认是项目根目录
1 | [ |
然后就可以愉快的使用了
支持SCSS
安装依赖
1 | // 该插件让‘babel-plugin-react-css-modules’支持‘scss’ |
配置
sass-loader
的配置很简单,就不说了,重点看下babel-plugin-react-css-modules
的配置
1 | ["babel-plugin-react-css-modules", { |
filetypes
这里是让这个插件支持scss。这里其实还可以添加插件,具体可以在官方文件中查看。
需要特别注意:所有从.js中引用
.scss
的代码,都不可以依赖webpack的resolve.modules
配置,只能写相对路径了。即原来写import 'common/scss/global.scss'
要改成import './common/scss/global.scss'
补充
styleName
出场了,className
干嘛?? 依然可以通过className
使用全局样式,babel-plugin-react-css-modules
会自动合并styleName
和className
。