css模块化

后来看到阮一峰老师的博客,写得简洁易懂,引用了几段示例代码。在构建项目的时候,css modules本质上只是借助构建工具对css文件进行编译实现类名的局域化和依赖管理而已。

----------------------------

这几年前端的发展确实处在一个急剧变化的时期,ES6、前端工程化、数据操纵视图的思想、各种框架和工具的诞生和普及。但是随着这段时期的变革,我觉得往后的一段时间技术社区应该会回归一段相对稳定的生态。

这些年来,相比于前端走向工程化、模块化的推进和JS层面上的革新和众多工具框架的诞生,css的发展相对缓慢。虽然sass、less等预处理器给我们带来了便利,但并没有解决模块化开发的一个痛点--全局污染。

目前社区的探索分两个方向,一部分人试图将css纳入js操纵的范畴,比如用js写css,方便动态更新样式;一部分人只是用js来管理css的依赖,代表作是css modules

在css modules中,一个css module其实就是一个css文件,这个文件中的类名和动画名默认处于局部作用域中。当这个css文件被引入到一个js文件中使用时,css文件的输入是作为一个js对象被调用的。

/* style.css */
.className {
  color: green;
}

import styles from "./style.css";
// import { className } from "./style.css";

element.innerHTML = '<div class="' + styles.className + '">';

这跟js模块是不是很类似?

网上不少文章在介绍css modules时,使用的都是webpack的css-loader,因为它对css modules支持很好,而且使用方便。

 1   module: {
 2     loaders: [
 3       {
 4         test: /\.jsx?$/,
 5         exclude: /node_modules/,
 6         loader: 'babel',
 7         query: {
 8           presets: ['es2015', 'stage-0', 'react']
 9         }
10       },
11       {
12         test: /\.css$/,
13         loader: "style-loader!css-loader?modules"
14       },
15     ]
16   }

在css-loader的配置项中,“?”后面添加了modules字段表示打开css modules功能。

局部作用域:

css modules 推荐本地命名 类名称 的时候采用驼峰写法className而不是class-name。这是为了方便使用点语法(style.className)。当然class-name写法也是可以的。编译后,css文件和html文档中的类名会被编译成一个哈希值,以实现命名区分。

全局作用域:

css modules提供了一个:global(.className)语法,允许我们定义全局的类名,在html文档中直接写全局类名即可:

:global(.title) {
  color: green;
}
export default () => {
  return (
    <h1 className="title">
      Hello World
    </h1>
  );
};

定制哈希值:

css modules默认哈希算法是[hash:base64],但我们可以在webpack中自己定义格式:

1 module: {
2   loaders: [
3     // ...
4     {
5       test: /\.css$/,
6       loader: "style-loader!css-loader?modules&localIdentName=[path][name]---[local]---[hash:base64:5]"
7     },
8   ]
9 }

composes组合样式:

css modules并不是单纯管理css文件的依赖和实现局部类名,也提供了一些灵活的方式让我们实现样式代码复用,比如composes关键字实现类的样式继承,就像sass中的mixin:

.className {
  background-color: blue;
}

.title {
  composes: className;
  color: red;
}

继承其他css模块的类样式:

.title {
  composes: className from './another.css';
  color: red;
}

变量:

 css modules也可以使用变量,但是需要安装postcss和插件postcss-modules-values

将postcss引入webpack.config.js

下面是阮一峰老师博客上的示例:

//colors.css
@value blue: #0c77f8;
@value red: #ff0000;
@value green: #aaf200;
//app.css
@value colors: "./colors.css";
@value blue, red, green from colors;

.title {
  color: red;
  background-color: blue;
}

可见,css modules借助postcss插件实现的变量机制主要是用@value做变量定义,在其他地方引用。感觉没有sass简洁灵活。

 

posted @ 2017-11-21 12:33  瓶子2333  阅读(279)  评论(0编辑  收藏  举报