1. 什么是CSS Modules?
Official definition[https://github.com/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文件。
Background:
我们都知道,CSS(层叠样式表)不是一门编程语言,但是为了让它能更方便程序员的开发,相继出现了很多的东西,Less, Sass, 到后来的 PostCSS,再到最近的 CSS in JS 都是为了让他想一门编程语言。但CSS module仅仅只是加入局部作用域和模块依赖,很容易学,因为它的规则少,同时又非常有用,可以保证某个组件的样式,不会影响到其他组件。
2. CSS Modules 如何保证局部作用域的?
产生局部作用域的唯一方法,就是使用一个独一无二的class的名字,不会与其他选择器重名。这就是 CSS Modules 的做法。
让我们来看一个Demo: https://github.com/ruanyf/css-modules-demos/tree/master/demo01
JS file
import React from 'react';
import style from './App.css';
export default () => {
return (
<h1 className={style.title}>
Hello World
</h1>
);
};
Question: 为什么可以通过 style.title 拿到CSS文件中的title对应的CSS属性
Answer: When importing the CSS Module from a JS Module, it exports an object with all mappings from local names to global names.
CSS file
.title {
color: red;
}
After compile
我们可以看到,这个时候经过编译的className 已经是一个哈希值了,而这个哈希值也会是一个全局的哈希值,不会和任何的className重名。
3. 为什么会编译成一个独一无二的哈希值?
CSS Modules提供了很多的插件,支持不同的构建工具, 其中支持最好的并且最常用的是 css-loader
webpack-config.js
var webpack = require('webpack');
module.exports = {
entry: __dirname + '/index.js',
output: {
publicPath: '/',
filename: './bundle.js'
},
module: {
loaders: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: 'babel',
query: {
presets: ['es2015', 'stage-0', 'react']
}
},
{
test: /\.css$/,
loader: "style-loader!css-loader?modules"
},
]
},
plugins: [
new webpack.optimize.UglifyJsPlugin({
compress: { warnings: false }
})
]
};
可以看到在css-loader
后面加上modules
这个参数,表明开启CSS Modules 这个功能
同时,我们也可以配置css-loader`的参数, 来对CSS Module进行配置和扩展https://webpack.js.org/loaders/css-loader/
4. CSS Module基本用法
- scoped CSS
- global CSS
- compose other classname
- composition from other files
- CSS module also support using variables, but need to add
postcss-loader
and postcss-modules-values
Demo show time
5. 为什么要使用CSS Modules?
- No more conflicts
- Explicit dependencies(显示的依赖关系)