前言
日常积累,欢迎指正
正文
什么是 css 模块化?
配置
css 模块化最重要的一个目底就是解决 css global 问题,最简单的使用方式就是在 webpack 中配置 cssLoader.modules = true
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: [
{
loader: 'style-loader',
},
{
loader: 'css-loader',
options: {
// modules: true
modules: {
localIdentName: '[path][name]__[local] --[hash:base64:5]',
}
}
},
{
loader: 'postcss-loader'
}
]
}
]
},
}
使用
js
import React from 'react'
import style from './index.css'
export default function Test(){
return <div className = {style.container}>
{/* return <div className = 'container'> */}
hello test
</div>
}
css
/* Test */
.container {
color: red;
height: 600px;
width: 800px;
background-image: url(../static/images/sunfloewr.png);
}
运行效果
这样虽然达到了效果却存在一些问题(来自babel-plugin-react-css-modules#css-module):
- You have to use camelCase CSS class names. - css 名称必须驼峰命名
- You have to use styles object whenever constructing a className. - 必须将 css 导入为 样式对象,并用在 className 上
- Mixing CSS Modules and global CSS classes is cumbersome. - CSS Modules 和 global CSS 的 class 是混合的
- Reference to an undefined CSS Module resolves to undefined without a warning.
babel-plugin-react-css-modules 使用 styleName 属性自动做 CSS Modules,如:
import React from 'react';
import './table.css';
export default class Table extends React.Component {
render () {
return <div styleName='table'>
<div styleName='row'>
<div styleName='cell'>A0</div>
<div styleName='cell'>B0</div>
</div>
</div>;
}
}
babel-plugin-react-css-modules 还具备以下优点:
-
You are not forced to use the camelCase naming convention. - 不用强制命名为拖分形式
-
You do not need to refer to the styles object every time you use a CSS Module. - 不需要将 css 导入为样式对象
-
能清晰区分模块化和全局 css e.g.
<div className='global-css' styleName='local-module'></div>
babel-plugin-react-css-module + less
关于 babel-plugin-react-css-modules 的使用 gitHub 上有一些说明,同时也提供了它的使用 demo 但该 demo 中使用的 css-loader 与 webpack 等包的版本都过于低,如下:
{
"private": true,
"scripts": {
"start": "webpack-dev-server"
},
"dependencies": {
...
"webpack": "^2.7.0"
},
"devDependencies": {
...
"babel-plugin-react-css-modules": "^4.0.0",
"css-loader": "^0.26.1",
"webpack-dev-server": "^2.11.3"
}
}
当前(2020-03-26)我项目中的相关工具版本如下:
{
"name": "code",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"scripts": {
"start": "webpack-dev-server --config webpack.dev.config.js",
"build": "webpack --config webpack.prd.config.js",
},
"devDependencies": {
...
"babel-plugin-react-css-modules": "^5.2.6",
"css-loader": "^3.4.2",
"webpack": "^4.42.1",
"webpack-cli": "^3.3.11",
"webpack-dev-server": "^3.10.3"
},
"dependencies": {
...
}
}
因为版本差异相关配置也有一定差异,现将我的完整使用过程记录如下:
安装依赖
$ yarn add babel-plugin-react-css-modules -D
$ yarn add postcss-less -D
$ # or
$ npm install ...
添加配置
webpack.*.config.js
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: [
{
loader: 'style-loader', // 开发模式使用
// loader: MiniCssExtractPlugin.loader, // 打包模式使用
},
{
loader: 'css-loader',
options: {
modules: {
localIdentName: '[path][name]__[local]',
}
}
},
{
loader: 'postcss-loader'
}
]
}
]
}
}
.babelrc
{
...
"plugins": [
[
"react-css-modules",
{
"generateScopedName": "src-[path][name]__[local]"
}
]
]
}
或 .babelrc.js(推荐)
module.exports = {
...
plugins: [
[
'react-css-modules',
{
generateScopedName: 'src-[path][name]__[local]',
}
]
]
}
注意 react-css-modules 的 generateScopedName 与 css-loader 的 css-loader.options.modules.localIdentName 的取值
然后就不用给不同的组件即时有相同的样式名称也不会出现冲突
效果演示
测试代码
三个具有相同样式名称 container
js
less
运行效果
css 打包结果
.src-Test-T1-index__container{height:100px;width:800px;background-color:#ff69b4}
.src-Test-T2-index__container{height:100px;width:800px;background-color:#7cfc00}
.src-Test-index__container{color:red;height:600px;width:800px;background-image:url(../static/images/6a9da3.png)}.src-Test-index__test-class{font-size:36px}.src-Test-index__test-class2{color:#000}
babel-plugin-react-css-module + sass
与 less 的配置雷同
安装依赖
$ yarn add babel-plugin-react-css-modules -D
$ yarn add postcss-scss -D
$ # or
$ npm install ...
添加配置
webpack.*.config.js
module.exports = {
module: {
rules: [
{
test: /\.scss$/i,
use: [
{
loader: 'style-loader',
},
{
loader: 'css-loader',
options: {
modules: {
localIdentName: '[path][name]__[local]',
}
}
},
{
loader: 'postcss-loader'
},
{
loader: 'sass-loader'
},
],
},
]
}
}
.babelrc.js
const path = require('path')
const context = path.resolve(__dirname, 'src')
module.exports = {
plugins: [
[
'react-css-modules',
{
context,
generateScopedName: 'src[path][name]__[local]',
webpackHotModuleReloading: true,
exclude: 'node_modules',
filetypes: {
'.scss': {
syntax: 'postcss-scss'
}
},
autoResolveMultipleImports: true
}
]
]
}
使用
同 less
babel-plugin-react-css-module + css
css 也可以使用 babel-plugin-react-css-module 做模块化以使用 babel-plugin-react-css-module 带来的优秀特性,css 的配置相对于 less/sass 是最简单的,只许要在 cssLoader.modules = true 的基础上添加 .babelrc.js 相关配置
module.exports = {
plugins: [
[
'react-css-modules',
{
context,
generateScopedName: '[path][name]__[local]--[hash:base64:5]',
exclude: 'node_modules',
autoResolveMultipleImports: true
}
]
]
}
使用 babel-plugin-react-css-module 后需要考虑的一些问题
待亲测后整理补充