iT邦幫忙

2021 iThome 鐵人賽

DAY 16
3
Modern Web

排版神器 Tailwind CSS~和兔兔一起快速上手漂亮的元件開發!系列 第 17

Day 16:「寶藏,都藏在那裡了!」- Tailwind JIT 模式

Day16-Banner

JIT、JIT 的叫了這麼多天,終於就是今天了!
今天就是要來講解 JIT 模式哦~~

JIT 模式真的快非常非常多,
快到你覺得你前面幾天根本在浪費人生 XD

不過就是要這樣子先苦後甘才會特別珍惜啊 (X

火箭已經準備發射,前往滿是寶藏的星球。
按鈕按下去,我們出發!
 

carrotPoint 火箭實驗場

今天要用到的專案在這裡:點我前往太空總署

好啦,其實今天的專案,和昨天完成後的結果差不多 XD
也可以直接使用昨天的專案來做就好。

昨天說應該不會用到,就是 應該 嘛哈哈哈
 

carrotPoint JIT

「JIT ... JIT 一直 JIT 的叫!」
「說到底 JIT 到底是什麼啦兔兔!!」

喔喔,我沒說過嗎?
JIT,就是 Just In Time 的縮寫哦!

而這就要講到一個軟體開發中的一個專有名詞,即時編譯 (Just-In-Time Compilation)

即時編譯就是不斷的實時分析正在執行的程式碼內容,並認定程式中的某些內容,這樣內容更新時就只需要部份編譯,而不是從頭全部再編譯一遍,這樣可以使編譯速度超級大幅度的提升

然後像是 Android Runtime (ART)、JAVA的虛擬機 (JVM) 和 Chrome 及 NodeJS 的 V8 都是使用 JIT Compiler 進行編譯。

和這個概念相同,Tailwind 的即時模式也是透過實時的監控 purge 中所指定範圍內的檔案並進行編譯,且只編譯出一些如 Preflight 的基本共用樣式,以及你有用到的 class。

這麼一來就不需要像之前一樣全部都編譯過後再進行 Tree-Shake 而花了很久的時間。

正因為是隨時監控著你的原始碼內容,所以當你一有增加新的 class 或功能,一經比對馬上就可以發現,然後幫你多編譯出這些功能再加上去,而不是從頭來一遍了!

所以開啟 JIT 的 Tailwind 如獲神力一般,不但速度大大大大大提升,還支援了那些原本需要在配置檔中加上後才開啟的樣式功能,現在完全不需設定就可以直接使用

好了,維基百科介紹完了,
現在來實地感受一下吧!
 

carrotPoint 設定開啟 JIT 模式

「兔兔!既然 JIT 這麼神,會不會設定很繁瑣啊?」

完全不會! 我們只需要像這樣在 purge 上面多增加一行 mode: "jit",順便把 purge 設定修改如下:

module.exports = {
  mode: "jit",
  purge: [
    "./*.{html,js}",
    "./**/*.{html,js}",
  ],
  ...
}

這樣就開完了!

沒錯,不要懷疑~就是這麼輕鬆如意。

但是有一點必須要注意,我們之前有說過很多次,剛剛前面也有再提到,JIT 要監控 purge 設定範圍的內容,所以 有開啟 JIT 一定要 purge! 不然它只會把 Preflight 類的樣式編譯,到時候畫面上會完全沒有樣式哦!

加完之後我們就來編譯一次:

npm run build

這個速度簡直是之前的 10 倍對吧!

兔兔的電腦跑很慢,所以我想你們的應該比我跑更快~
然後那些警告不需要去管它哦! 都是一定會跳的。

接著我們來試著改一些樣式吧!
(你又要改!)
 

carrotPoint 樣式調整

我們一樣,調整顏色就好... 把方塊 3 改成紫色!

<div class="flex justify-evenly p-10 focus-within:bg-green-100 group">
  <box class="box bg-red-500 hover:bg-red-400 ring-red-300" tabindex="0">
    1
  </box>
  <box class="box bg-blue-500 hover:bg-blue-400 ring-blue-300" tabindex="1">
    2
  </box>

  <box class="box bg-purple-500 hover:bg-purple-400 ring-purple-300" tabindex="2">
    3
  </box>
</div>

「齁 ... 兔兔!」 (怒)
「又來了咩! 改了又沒樣式了欸! 難道我又要去寫那些難懂的正規表達式了嗎? 快是快很多啦 ... 但這真的很不人性化! 而ㄑ...」

欸欸欸好啦好啦~別再抱怨啦~
其實這正是我要你改樣式的目的呀!

因為我前面都有說哦~~~~~!
JIT 模式需要隨時監控 purge 設定的監聽範圍中的文件。

你真的以為多加了一行就能監控了嗎 XD
沒關係,讓我來講給你聽。
 

carrotPoint 監控伺服器 (Watch Server)

要開啟 watch server 也不難哦! 超簡單!

現在只要在 package.json 中的 script 區塊把 build 指令的名稱改為 watch,並在指令最後面加上 -w 這個參數:

{
  ...
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "watch": "tailwindcss -i tailwind.css -o style.css -w"
    // ↑↑ 這行最後面加上 `-w` ↑↑
  },
  ...
}

會把指令名稱從 build 改為 watch 是出於命名習慣。因為現在指令的用途已經改為 watch server,而非 build。

 
接著事不宜遲,立馬來執行吧:

npm run watch

對吧,改完立刻變成紫色了!

千萬別急著把 watch server 關掉,
讓我們馬上再改成其他顏色吧!
 

carrotPoint 再次調整樣式

接下來這次改顏色,我順便來講一個 JIT 模式限定的新語法。

前面說過,有了 JIT 之後,有許多樣式不需進入配置檔開啟就可以直接使用,但這個跟那些不一樣,它是支援你使用任意值的語法!

  • bg-[任意值]

這個語法可以直接填入既有的顏色名稱或是色碼,舉例我們把方塊 3 改為橘色系:

  • bg-[darkorange] 來取代 bg-purple-500
  • hover:bg-[orange] 取代 hover:bg-purple-400
  • ring-[#ffc966] 來取代 ring-purple-300
<div class="flex justify-evenly p-10 focus-within:bg-green-100 group">
  <box class="box bg-red-500 hover:bg-red-400 ring-red-300" tabindex="0">
    1
  </box>
  <box class="box bg-blue-500 hover:bg-blue-400 ring-blue-300" tabindex="1">
    2
  </box>

  <box class="box bg-[darkorange] hover:bg-[orange] ring-[#ffc966]" tabindex="2">
    3
  </box>
</div>

直接儲存後會發現 terminal 顯示它有重新編譯:

再來就是馬上看結果:

橘色系挑戰,大成功!
而且速度飛快的呢,修改樣式重新編譯只需要花 0.5秒!

那 watch server 打開後就暫時不要關了,
因為在開發過程中會需要隨時調整樣式,
當你開發完畢的瞬間,其實 css 也編譯完了。

而且不只這樣,因為 jit 必須要設定 purge,
所以這 css 不但已經是編譯完的,還是已經減肥過的!
是不是很棒呀~

然後還有一點就是開啟了 JIT 之後,Tailwind IntelliSense 也不會再像之前一樣只會提示基本樣式,而是全部所有 Tailwind 中有的樣式都會提供給你! 因為這些樣式有了 JIT 都不需要設定也能直接使用。

像這張圖中所提示的 peer 變化模式,就是 Tailwind 2.2 推出之後一個很強大的新功能,可以讓你的 css 設計更加靈活、可互動性更高。

接下來我就大略的介紹一下 JIT 限定的功能吧~
 

carrotPoint 限定功能

Tailwind 2.1

JIT 模式是 2.1 時推出的新功能,除了改善編譯速度上的問題外,也因為即時編譯所以可以把原本不可能組合在一起的功能直接全部串在一起,而且還能夠順利運作。

舉例, sm:hover:active:disabled:opacity-75 ...
說實在我都不知道該如何解讀它了,不過我們就來解讀一下吧!

  sm: {
    hover: {
      active: {
        disabled:opacity-75
      }
    }
  }

簡單來說這個功能就是:「在小尺寸螢幕寬度以上時,當你滑鼠懸停且按下,這個元素若是在停用狀態,不透明度就會變為 75%」

用想得都覺得累 ...
但這就是隨便你寫,它就想辦法幫你做到!

或者像是寬度、高度、色彩、程度等等都可以直接指定任意值,比如:

  • bg-[#FF00CC]
  • bg-opacity-[77%]
  • min-h-[50px]
  • w-[27.7rem]
  • duration-[33ms]
  • border-[7px]
  • space-y-[11px]
  • rounded-[29px]

大概就舉例這些,剩下自己以此類推嘿!

border[11px] 為例,其實它的原理就是動態編譯樣式成:

.border-\[11px\] {
  border-width: 11px;
}

Tailwind 2.2

到了 2.2,又增加了更多更方便的語法!

像是我們原本設定背景色彩的同時,若要設定背景不透明度,
我們必須這樣寫:

<box class="bg-red-500 bg-opacity-75">
  Tailwind 2.2
</box>

但為了讓這很常同時出現的功能可以使用的更快速,
現在可以這樣寫:

<box class="bg-red-500/75">
  Tailwind 2.2
</box>

所有的預設色彩都支援短語法的功能,但是任意值不行。也就是說你無法寫成 bg-[red]/75

2.2 還有一些新的變化模式,像是開始支援偽元素的功能:

  • before: (::before)
  • after: (::after)
  • first-letter: (::first-letter)
  • first-line: (::first-line)
  • marker: (::marker)
  • selection: (::selection)

或者是表單設計上常用的,可以設定表單元件狀態樣式的變化模式:

  • required:
  • invalid:
  • placeholder-shown:

甚至還可以設定打字時插入符號的顏色(就是會閃爍的那個游標),但最讚的果然還是這個功能:相鄰元素選擇器的變化模式 - peer

Peer

簡單來講解一下 peer 的用法。

我們可以簡單做到 hover A 方塊,然後 B 方塊會改顏色:

<box class="peer">
  A
</box>

<box class="peer-hover:bg-blue-300">
  B
</box>

A hover B 範例連結

 

所以也可以用這個做 Toggle Switch:

<label class="relative block w-20 h-10 m-5">
  <input type="checkbox" class="peer checked:bg-green-300 ..." />
  <div class="peer-checked:translate-x-full ..."></div>
</label>


Toggle Switch 範例連結

效果就是上面這樣。

主要就是藉由 checkbox 上有 peer,那麼跟它相鄰的 div 就可透過 peer 獲取 checkbox 的狀態,如果 checkbox 被打勾,變化模式 peer-checked: 就會生效,使白色圓形的 div 往右水平移動 100%。

這是一個非常簡單又有趣的小應用,關於 peer 變化模式應用的影片我會將連結放在下方,有興趣的人可以自己去看看哦!
 

小補充

這個也是 JIT 的限定功能。 (笑)

如果你想要像 bootstrap 一樣
可以強調很重要很重要的部分的話,
也是可以輕鬆辦到的哦!

Tailwind JIT 模式內建 !important 的寫法!

就是在 class 前面加上 ! 驚嘆號:

<div class="bg-red-200 bg-green-200">
  不重要!
</div>

<div class="bg-red-200 !bg-green-200">
  很重要!
</div>

來看一下效果,確實有覆蓋掉!
這樣你也能跟著 bootstrap 一起很重要囉~~
 

還有想玩 JIT 模式的人如果嫌安裝和設定很麻煩,可以直接去 Playground 上面玩,因為 Playground 預設就是開啟 JIT 模式哦!

呼~然後 ...

這樣 JIT 模式的介紹就全部結束啦!!!
同時也是這個系列 Tailwind 篇的最後一篇哦~

接下來,我們會踏入全新的領域!
我們要來講前端框架:Vue

因為最後那些元件就要用 Vue + Tailwind 來完成
不過寫 React 的人也別氣餒 ...

因為 Tailwind 切的版基本上可以直接挪過去用哦!
其實元件的操作邏輯也類似,可以參考參考~

那今天就到這裡了~
然後其實我放影片上來是很害羞的 ...
大家看看就好,別太挑剔嘿 ><

明天同一時間請繼續收看,烏龍派...
明天記得也要來看文章哦~
 

carrotPoint 給你們的回家作業:


關於兔兔們:


 


( # 免免小聲說 )

文字真的是一個奧妙的東西,
因為差一筆一劃如同差距千里。

之前大家在玩互換名字的時候,
有個人一直被誤認成我。

「大家好,我是免免」

乾 ... 可以,你真行!


上一篇
Day 15:「你真的不減肥嗎...?」- Tailwind 的生產環境優化
下一篇
Day 17:「我們,是好朋友哦~」- Vue 簡介
系列文
排版神器 Tailwind CSS~和兔兔一起快速上手漂亮的元件開發!32
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 則留言

1
jason06286
iT邦新手 5 級 ‧ 2021-09-27 14:31:36

Hi 兔兔
謝謝你詳細的 tailwind 教學 ,但我在設定 jit 模式遇到了些困難,
我發現 style.css 有順利隨著 index.html 變化編譯出來,
jit 模式下 .h-[200px] 有順利吃到效果,
.bg-[#FF8000] 查看 index.html 卻沒有顯示相關 class 名稱,
使用兔兔提供的範本可以順利運行,但自己建立的卻不行,懇請兔兔給我點方向!!
程式碼連結
https://ithelp.ithome.com.tw/upload/images/20210927/20124879KLPDYT4A0Y.png
https://ithelp.ithome.com.tw/upload/images/20210927/20124879ODdf9fgzpS.png

搋兔 iT邦新手 4 級 ‧ 2021-09-27 16:33:30 檢舉
  "devDependencies": {
    "autoprefixer": "^10.3.6",
    "postcss": "^8.3.8",
    "tailwindcss": "2.2.7"
  },

嗨你好~關於這個問題的答案其實很妙。
在 2.2.7 是正常的,2.2.8 開始到你所使用的最新版 2.2.16 都還是會出現你遇到的狀況。

所以把 package.json 中的 tailwind 版本從 "^2.2.16" 改成 "2.2.7" 後重新 npm install 一次來降版,再試試看應該就有效果囉!

除了降版之外的方法我過幾天研究過後再告訴你 XD

謝謝兔兔的回答
降版就可以順利運行了,不得不說 Vitawind 真香!
先預祝你完賽成功!!/images/emoticon/emoticon12.gif

0
碼農
iT邦新手 4 級 ‧ 2023-02-01 16:07:58

兔兔大師您好~
先祝您兔年行大運,記得去安太歲,因為有衝到XD

我想請教關於ring-(沒有粗框)和!important(不用!就可以覆蓋)的寫法

關於本文其他語法都可以成功 但上述提到這兩個就有問題

而且我明明有npm安裝 但還是需要用CDN才有完整效果

有去看您的github 有npm看ring的效果 但也沒有 不知道是什麼問題

在這邊請求兔兔開示!

奉上程式碼連結(註解有點多):
https://drive.google.com/drive/folders/1WOK5bE-DTMGY4-dDXXGV_GM63RB6xXJv?usp=sharing

我要留言

立即登入留言