通过 Babel 实现 jsx 中无感知使用 cssModules
npm install babel-plugin-jsx-css-modules通过 Babel 实现 JSX 中无感知使用 CSS Modules
不需要显式调用 styles 变量或自定义 props 如 styleName
需确保已启用 CSS Modules 功能
Babel 6/7 均可用
- - -
1. 安装插件
``bash`
npm install babel-plugin-jsx-css-modules --save
2. 配置 .babelrc 文件
`json`
{
"plugins": [
"jsx-css-modules"
]
}
cssModules
3. 调整构建配置以启用 功能
启用方式可参考:
- https://github.com/css-modules/css-modules#implementations
- https://github.com/webpack-contrib/css-loader#modules
- https://github.com/css-modules/postcss-modules
注意:未启用 cssModules 功能的样式文件不会有效果
- - -
`javascript
import './styles.module.scss'
const Example = ({ customerClassName }) => (
将转化为
`javascript
import styles from './styles.module.scss'
const matcher = classNames =>
classNames.split(' ').map(className => styles[className] || className).join(' ')const Example = ({ customerClassName }) => (
Example
Example
)
`以上是对该插件运作方式的简单解释,实际上,
matcher 函数还可完成对全局样式的甄选,参考如下说明- - -
区分全局、局部样式
依照 cssModules 规则,在类名上拓展了
:global / :local 修饰器语法,以区分全局、局部样式未添加修饰器的类名默认属于
:local 样式,此行为通过 prefer 参数修改`javascript
import './styles.module.scss'const Example = () => (
:global(global_1 global_2)
:local(module_1 module_2)
rest_1 rest_2
}>
Example
)
`注意:不支持嵌套使用修饰器,不支持形如
:global(xxx :global(yyy zzz) aaa) 的使用方式- - -
配置项
`json
{
"plugins": [
["jsx-css-modules", {
"styleFileReg": [
"\\.(css|scss|sass|less)$"
],
"prefer": "local",
"helperImportType": "cjs"
}]
]
}
`| 名称 | 类型 | 默认值 | 描述
| - | - | - | -
| styleFileReg |
Array of RegExp | [/\.(css\|scss\|sass\|less)$/] | 用以匹配需要处理的 css 模块文件
| prefer | String | 'local' | 声明未修饰的类名归属于何种类型,取值为 'local' 或 'global'
| helperImportType | String | 'cjs' | 声明辅助函数的导入方式,取值为 'cjs' 或 'esm'- - -
注意事项
当存在多个
cssModules 样式文件时,若文件内存在同名模块,则只会保留最后被引用文件内的模块`scss
// style1.module.scss
.test {
color: red;
}// style2.module.scss
.test {
color: blue;
}
`
`javascript
import './style1.module.scss'
import './style2.module.scss'const Example = () => (
我将会是蓝色的
)
`- - -
$3
考虑到插件功能关注点不同,目前不太清楚是否有必要支持如下两种、或更多可能性的书写方式,可以在 issue 中交流
若添加如下特性,插件有可能需要进行更名,含义类似于
className-all-in-one 或 jsx-className-expansion- [x] ~~无感知使用
CSS Modules~~
- [ ] 兼容 styleName(prefer 选项固定为 'global')
- [ ] 无感知集成 classnames 功能,示例如下
`javascript
const Example = () => (
className={{
xxx: true,
yyy: false
}}
/>
className={[
'zzz',
{
xxx: 1,
yyy: 0
}
]}
/>
)
``- - -
- 手把手教你开发一个 babel-plugin
- Babel 插件手册
- @babel/types
- AST Explorer