前言:
CSS是前端领域中进化最慢的一块.由于ES6的快速普以及webpack等工具的迅猛发展,相较于JavaScript,CSS被远远甩在了后面,逐渐成为各类大型项目工程化的痛点,也变成了前端走向彻底模块化前必须要解决的一个问题。
CSS模块化的解决方案有很多,但主要有两类。
- InlineStyle.这种方案彻底抛弃CSS,使用JavaScript或JSON来写样式,能给CSS提供JavaScript那样强大的模块化能力。但缺点同样明显,InlineStyle几乎不能利用CSS本身的特性,比如级联、媒体查询等,
:hover ;:active
等伪类处理起来比较复杂。 - CSS Modules。依旧使用CSS,但使用JavaScript来管理样式依赖。CSS Modules能最大化地结合现有CSS生态和JavaScript模块化能力。
CSS模块化遇到过哪些问题?
CSS模块化重要的是解决好以下两个问题:- CSS样式的导入与导出。
- 灵活按需导入以便复用代码,导出时要能够隐藏内部作用域,以免造成全局污染。
FaceBook工程师抛出了在react项目中遇到的一系列CSS相关问题有以下几点(这些问题也是我们在项目中经常会遇到的问题):
- 全局污染:CSS使用全局选择器机制来设置样式,优点是方便重写样式。缺点是所有的样式都是全局生效,样式可能会被覆盖。
- 命名混乱:由于全局污染的问题,多人在协作开发时为了避免样式冲突会形成多种不同的风格,很难统一。样式多变后,命名将更加混乱。
- 依赖管理不彻底:组件应该相互独立,引入一个组件时,应该只引入它所需要的CSS样式。而现在的做法是除了要引入JavaScript还要引入它的CSS。如果能让JavaScript来管理CSS依赖是很好的解决办法,而webpack的css-loader提供了这种能力。
- 无法共享变量:复杂组件要使用JavaScript和CSS来共同处理样式,就会造成有些变量在JavaScript和CSS中冗余。
- 代码压缩不彻底
CSS Modules的使用方法:
我们需要的是用JavaScript来管理CSS的能力,结合webpack的css-loader,就可以在CSS中定义样式,在JavaScript文件中导入。一、局部作用域:
产生局部作用域唯一的方法就是是用一个独一无二的class名字
下面是react项目中APP.js的代码:
import React from 'react';
import style from './App.css';
export default () => {
return (
<div>
<h1 className={style.title}>
Hello World
</h1>
<div className={style.box1}>
<p>我是盒子一</p>
</div>
</div>
);
};
APP.css里面的代码是:
.title {
color: red;
}
.box1{
background-color: aquamarine;
width: 500px;
height: 500px;
}
webpack.config.js中代码:
module.exports = {
entry: __dirname + '/index.js',
output: {
path: '/',
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"
},
]
}
};
构建工具会将style.title编译成一个哈希字符串,也会将App.css进行编译。