什麼都要來點 module。
簡述
在 React 裡寫 style 除了 inline-style、className 和 CSS-In-JS 以外,還有一種寫法叫做 CSS Module,這種寫法還蠻有意思的,所以想記錄一下。
為什麼需要 module?
在講 module 以前,我覺得先認識一下「沒有 module」的世界長什麼樣?能夠幫助你釐清 module 的用途所在。
假設我有一個 Button 元件長這樣:
1 | export default function Button () { |
如果我想幫他加上一點 style,我可能會開一隻 button.css
來寫一個給 Button 用的 className:
1 | /* button.css */ |
接著在 Button
中引入這隻 CSS,再加上 className:
1 | import "./button.css"; |
這樣子 Button 就會顯示我們加上的樣式了,看起來好像很合理啊?有什麼問題嗎?
沒錯,這樣子確實可以讓 Button 吃到樣式,但有一件很重要的事情一定要搞清楚:
即便我只有在 Button 中引入 CSS 檔案,這也不代表這些樣式只會套用到 Button 上,他依然是 Global Style。
什麼意思?意思是說,假設我在別的元件中也用了 btn
這個 className,那他一樣會套用到樣式。
這個就是沒有 module 會有的問題,沒辦法產生 scope。
所以呢,CSS Module 就是用來解決 scope 的問題而誕生的一種寫法。
使用 CSS Moudle
要使用 CSS Module 的話,首先我們得建立一支 *.module.css
的檔案。這邊強調一下,這個不是因為命名慣例才這樣命名,而是一定要這樣子寫才能夠啟用 module 的功能。
所以跟剛剛一樣,把 style 寫進去:
1 | /* button.module.css */ |
接著引入的方式也會有點小不同,請看 code:
1 | import style from "./button.module.css"; |
跟剛剛不一樣的地方是我們不只是引入檔案而已,而是改用我們一般在使用 module 的方式來引入(style
),接著再透過 style
來把他放入 className 裡面。
這樣子做的差別是什麼?看下面這張圖就懂了:
className 會自動被加上亂碼,所以即便我現在到別的地方使用 btn
這個 className 也沒有用,因為真正被寫入 style 的 className 不是 btn
,而是 button_btn_sZruf
。
這是怎麼做到的?雖然我沒特別去查,不過用猜的話大概就是 React 在背後做了一些設定,只要碰到 .module.css
的 檔案就會在原本的 class 加上一串亂數,最後在包裝成一個 object 來 export 出去。
所以你最後 import 進來的東西就是已經被包裝(或想成是加工)過的 CSS 檔。
總而言之,你只要知道怎麼用?跟知道這樣做以後就能確保你的 CSS 只會作用在「引入的那個元件」中,這樣就差不多了。
以上就是 CSS Module 的使用方式。