React-CSS Module

什麼都要來點 module。

簡述

在 React 裡寫 style 除了 inline-style、className 和 CSS-In-JS 以外,還有一種寫法叫做 CSS Module,這種寫法還蠻有意思的,所以想記錄一下。

為什麼需要 module?

在講 module 以前,我覺得先認識一下「沒有 module」的世界長什麼樣?能夠幫助你釐清 module 的用途所在。

假設我有一個 Button 元件長這樣:

1
2
3
export default function Button () {
return <button>click me</button>
}

如果我想幫他加上一點 style,我可能會開一隻 button.css 來寫一個給 Button 用的 className:

1
2
3
4
5
6
7
/* button.css */
.btn {
color: white;
background-color: dodgerblue;
padding: 4px 8px;
border: unset;
}

接著在 Button 中引入這隻 CSS,再加上 className:

1
2
3
4
5
import "./button.css";

export default function Button () {
return <button className="btn">click me</button>
}

這樣子 Button 就會顯示我們加上的樣式了,看起來好像很合理啊?有什麼問題嗎?

沒錯,這樣子確實可以讓 Button 吃到樣式,但有一件很重要的事情一定要搞清楚:

即便我只有在 Button 中引入 CSS 檔案,這也不代表這些樣式只會套用到 Button 上,他依然是 Global Style。

什麼意思?意思是說,假設我在別的元件中也用了 btn 這個 className,那他一樣會套用到樣式。

out-side-the-component

這個就是沒有 module 會有的問題,沒辦法產生 scope。

所以呢,CSS Module 就是用來解決 scope 的問題而誕生的一種寫法。

使用 CSS Moudle

要使用 CSS Module 的話,首先我們得建立一支 *.module.css 的檔案。這邊強調一下,這個不是因為命名慣例才這樣命名,而是一定要這樣子寫才能夠啟用 module 的功能。

所以跟剛剛一樣,把 style 寫進去:

1
2
3
4
5
6
7
/* button.module.css */
.btn {
color: white;
background-color: dodgerblue;
padding: 4px 8px;
border: unset;
}

接著引入的方式也會有點小不同,請看 code:

1
2
3
4
5
import style from "./button.module.css";

export default function Button () {
return <button className={style.btn}>click me</button>
}

跟剛剛不一樣的地方是我們不只是引入檔案而已,而是改用我們一般在使用 module 的方式來引入(style),接著再透過 style 來把他放入 className 裡面。

這樣子做的差別是什麼?看下面這張圖就懂了:

use-module

className 會自動被加上亂碼,所以即便我現在到別的地方使用 btn 這個 className 也沒有用,因為真正被寫入 style 的 className 不是 btn,而是 button_btn_sZruf

這是怎麼做到的?雖然我沒特別去查,不過用猜的話大概就是 React 在背後做了一些設定,只要碰到 .module.css 的 檔案就會在原本的 class 加上一串亂數,最後在包裝成一個 object 來 export 出去。

所以你最後 import 進來的東西就是已經被包裝(或想成是加工)過的 CSS 檔。

總而言之,你只要知道怎麼用?跟知道這樣做以後就能確保你的 CSS 只會作用在「引入的那個元件」中,這樣就差不多了。

以上就是 CSS Module 的使用方式。

一個 import 的小技巧 再來談談-淺拷貝與深拷貝的雷
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×