初識CSS Modules

前端的發展太快了,之前拜讀了一篇在 2016 年學 JavaScript 是一種什么樣的體驗?,不禁感慨,放一個三年前的前端來看待現在的前端圈子,估計也是懵逼的。

言歸正傳

我取標題的能力也是挺瞎的……


引言吐槽了一下javascript的蓬勃發展,其實并非是壞事,例如ES2015的發布和使用確實讓我感受到敲代碼時候很大的方便,比如箭頭函數(笑)。但相對而言的,CSS的發展卻并不是那么快。
可以想到的無非是各種預處理器

  • LESS
  • SASS
  • 以及以后比較流行的postcss

但是他們還是沒有解決一個問題,命名的痛苦……

試想一下,一個大的項目,css命名滿天飛,一不留神就覆蓋了全局的class名怎么辦?

** css究竟怎么了?**

  1. 全局污染
  2. 命名混亂
  3. 依賴管理不徹底
怎么辦,試試BEM唄

你還真別說,業界確實有一個非常不錯的css命名規范,BEM(不展開了),有興趣的自行搜索一下吧,BEM規范的好處在于盡可能的解決了css命名全局污染的問題。但是,它的規則真的太麻煩了,還不好記。

舉個例子

.block{} /* 塊 */
.block__element{} /* 元素 */
.block--modifier{} /* 修飾符 */

啥都別說了……

CSS modules來了

要說js模塊化,這幾年真是講爛了,什么AMD,CMD,UMD各種,以及ES2015原生都開始支持js模塊化。講真,在我開始接觸了模塊化js之后確實給我帶來了很多的方便(點個贊)。
同樣,CSS module的帶來或許也可能解決目前大家最頭疼的CSS 全局污染問題了。

CSS modules語法篇

一切開始前,要表示一下,CSS modules不是一個新語言,而只是CSS in JS一直實現方式,最值得重視的是,它的規則特別少,幾乎0成本!這部分參考了阮一峰大神的CSS Modules 用法教程

1. 局部作用域

說白了,使用CSS modules ,每一個class都可以生成一個唯一的class名

例如
創建一個button.css文件,并寫入代碼

.red{
   color:red  
}

引入到另一個index.js(省略了一部分代碼)

import buttons from "./buttons.css";
element.innerHTML = `<div class="${buttons.red}">`

那么,在渲染到html文件里面的時候,這里的class可能就是_3N_PGYCwi_3X8rf_WN50yo(命名規則其實是可以自行調整的,下面會提到)

2. 全局作用域

CSS Modules 允許使用:global(.className)的語法,聲明一個全局規則。凡是這樣聲明的class,都不會被編譯成哈希字符串。

.title { color: red;}
:global(.title) { color: green;}

第二個渲染的class依然是.title

CSS Modules 還提供一種顯式的局部作用域語法:local(.className),等同于.class,所以上述的css文件也可以寫成下面這樣。

:local(.title) { color: red;}
:global(.title) { color: green;}
3. 定制哈希類名

配合webpack食用更佳
舉個配合webpack使用的例子

//webpack.config.js文件
……
module: { 
loaders: [  // ... 
{ 
 test: /\.css$/, 
 loader: "style-loader!css-loader?modules&localIdentName=[path][name]---[local]---[hash:base64:5]" },
]
}

依然是上面的例子
創建一個button.css文件,并寫入代碼

.red{
   color:red  
}

那么,渲染的class可能是 .buttons__red___3N_PG

4. Class 的組合

在 CSS Modules 中,一個選擇器可以繼承另一個選擇器的規則,這稱為"組合"("composition")。

直接上代碼
創建一個button.css文件,并寫入代碼

.red{
   color:red  
}
.button{
  composes:red
}

使用composes繼承了class名為red的屬性,有點類似于sass里面的@extend。

此外還支持兩個模塊的引入
例如
創建一個button.css文件,并寫入代碼

.red{
   color:red  
}

同目錄創建一個button2.css文件,并寫入代碼

.button{
  composes:red from './button.css'
}

通過** composes:red from './button.css'**實現了兩個文件之間的組合。

5. 輸入變量

接觸不多,具體實現詳見原文。

CSS modules 使用實例

*這里使用 webpack *

項目結構

  • src (文件夾)
  • node_modules (文件夾)
  • .babelrc
  • index.html
  • webpack.config.js
  • package.json

假設項目的文件夾是 app, 在app文件夾內npm init 生成 package.json 文件
然后(請確認已全局安裝webpack), npm install -D babel-core babel-loader babel-preset-es2015 extract-text-webpack-plugin css-loader webpack

在webpack.config.js中寫入以下內容

var path = require('path')
var ExtractTextPlugin = require("extract-text-webpack-plugin");

module.exports = {
    entry: './src',
    output: {
        path: 'bulid',
        filename: 'bundle.js'
    },
    module: {
        loaders: [{
            test: /\.js$/,
            loader: 'babel-loader',
            include: path.resolve(__dirname, './src')
        }, {
            test: /\.css$/,
            loader: ExtractTextPlugin.extract('css?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]'),
            include: path.resolve(__dirname, 'src'),
        }]
    },
    plugins: [
        new ExtractTextPlugin("styles.css")
    ],
    devtool: "source-map"
}

在.babelrc文件中寫入

{
 "presets": ["es2015"]
}```

在index.html中寫入

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document name</title>
<link rel="stylesheet" href="bulid/styles.css">
</head>
<body>
<h1>CSS Modules demo</h1>

<script src="bulid/bundle.js"></script>

</body>
</html>


準備工作做完,我們在src文件夾中進行具體的內容操作

###### step1 
在src中新建 index.js,內容

import buttons from './buttons.css'

let element = <div class="${buttons.red}"> <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Consequatur laudantium recusandae itaque libero velit minus ex reiciendis veniam. Eligendi modi sint delectus beatae nemo provident ratione maiores, voluptatibus a tempore!</p> </div>;
document.write(element);

###### setp2 
在src文件夾中新建buttons.css,內容

.red{
color:red
}


###### setp3 
在命令行中執行webpack任務,生成bulid文件夾。

命令行 輸入   ```webpack``` 嘗試一下吧!!
***
在上述的項目中,css modules的核心是webpack.config.js中 

{
test: /.css$/,
loader: ExtractTextPlugin.extract('css?modules&importLoaders=1&localIdentName=[name][local]_[hash:base64:5]'),
include: path.resolve(__dirname, 'src'),
}




# 文章參考
[CSS Modules入門Ⅰ:它是什么?為什么要使用它?
](https://zhuanlan.zhihu.com/p/23571898)
[CSS Modules入門Ⅱ:快速上手](https://zhuanlan.zhihu.com/p/23602046)
[CSS Modules 用法教程](http://www.bshare.cn/share)
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,460評論 6 538
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,067評論 3 423
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,467評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,468評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,184評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,582評論 1 325
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,616評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,794評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,343評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,096評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,291評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,863評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,513評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,941評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,190評論 1 291
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,026評論 3 396
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,253評論 2 375

推薦閱讀更多精彩內容