本文於2015年底完成,釋出在個人部落格網站上。 考慮個人部落格因某種原因無法修復,於是在部落格園安家,之前釋出的文章逐步搬遷過來。
背景
前段時間研究使用YUI Compressor
壓縮專案裡的js和css檔案,研究了兩天之後,終於在週三晚上把YUI Compressor
整合進了打包流程中;於是週四(2015-11-12)早晨一到辦公室,第一件事就是把相關的構建指令碼提交至配置庫。
從詭異的問題開始
剛高興沒多久,測試MM就發現一個Bug,有個頁面的樣式出了問題,導致自動化用例執行失敗,要求開發儘快處理。
起初沒太注意,感覺只是個小問題,於是直接讓對應特性的開發責任人去定位。一個小時之後,測試MM過來問進展,我才發現小問題不簡單,一個小時過去了,但開發人員並沒有找到問題原因。
開發人員很無奈,因為現象確實比較奇怪:
- 目前發現僅在Linux部署的那套環境上出現了樣式出錯的現象;
- 在開發人員、測試人員本地搭建的環境上,並沒有類似的現象;
- 開發人員定位的結果,頁面引用的樣式檔案中,從某個定義開始,後面的樣式全部都未生效;
- 出問題的頁面本週有新特性開發,但引用的樣式檔案本週並沒有人做過更新;
對於現象本身,有來自測試人員進一步的反饋:
- 自動化用例驗證昨天的版本時,並沒有發現樣式的問題;
- 測試人員反饋,早晨升級Linux環境前,人工驗證時並沒有發現樣式的問題;
結合這些資訊,突然想到上午我才把css壓縮相關的構建指令碼合入配置庫,而出現問題的版本正好是使用更新過的構建指令碼打包出來的,那麼會不會是壓縮工具引入的問題?帶著這個疑問登入到Linux部署環境上,使用vim
檢視對應的css檔案,有如下發現:
- 樣式檔案被壓縮至一行;
- 在某一個字元後的內容,沒有高亮,感覺像是
vim
的語法高亮似乎有問題;
由於檔案內容壓縮之後檢視實在辛苦,於是開啟eclipse檢視問題相關的css檔案。這時在開發人員反饋的樣式定義附近,找到一處如下的css程式碼。
#wrapper {
display: block;
margin: 0 auto;
text-align: left;
min-width": 720px; 看到這行程式碼的問題了嗎?
max-width: 1000px;
}
問題找到了,原來是開發人員定義樣式時,本意是書寫min-width: 720px;
,但在min-width
後面多打了一個"
,於是成了min-width": 720px;
。
問題原因
找到這裡,我有一個猜測,對於未壓縮的樣式,瀏覽器在載入到前述樣式定義時,會直接忽略掉min-width
的定義,但max-width
和後續的樣式定義還是有效的;但當樣式檔案被工具壓縮到一行之後,min-width
的錯誤會導致後續的樣式定義全部被忽略掉,於是出現了前述測試MM反饋的問題。
為了證實我的想法,決定拿問題環境做個實驗,直接在環境上修改css檔案。
於是登入Linux環境,使用vim
修改對應的css檔案,將多餘的"
刪除掉,這時vim
的語法高亮恢復了正常。然後使用瀏覽器登入頁面,清除快取後訪問之前有問題的頁面,發現頁面的樣式恢復正常。
問題解決之後
問題雖然解決了,但問題本身值得回味。
css是指令碼,和js不同,瀏覽器在載入css時不會校驗語法,遇到錯誤不報錯,反而會安靜的忽略。這次的問題發現了,解決了,那麼下次呢?下次也要花費三人時來定位和解決嗎?這就糾結了,畢竟類似前述的問題靠人眼來檢查css檔案的語法,其實挺痛苦的。
那麼有沒有什麼工具可以檢查css的語法,在開發時就能提前發現問題,避免類似問題發生?在網上搜尋了一圈,找到了csslint
。
csslint
什麼是csslint
如下擷取自專案主頁。
CSS Lint is a tool to help point out problems with your CSS code. It does basic syntax checking as well as applying a set of rules to the code that look for problematic patterns or signs of inefficiency. The rules are all pluggable, so you can easily write your own or omit ones you don't want.
程式碼主頁https://github.com/CSSLint/csslint,線上檢查工具http://csslint.net。
使用方法
專案的官方文件非常詳細,由此可見專案的開發人員非常用心。從文件看,csslint的使用很簡單。
命令列方式
進入命令列,執行如下命令,將檢查test.css
。
java -jar js.jar csslint-rhino.js test.css
與Ant整合
在構建指令碼中增加如下的的target
。
<target name="csslint">
<apply executable="java" failonerror="true" parallel="true">
<fileset dir="${src.dir}" includes="**/*.css" />
<arg line="-jar"/>
<arg path="${lib.dir}/js.jar"/>
<arg path="${lib.dir}/csslint-rhino.js" />
<!-- your customized arguments go here -->
<arg line="--warnings=box-model,floats --errors=ids,important"/>
<srcfile/>
</apply>
</target>
src.dir
,待檢查的css檔案的儲存路徑。lib.dir
,基於Rhino
的csslint
工具和jar
檔案的儲存路徑。
可以使用antcall
來呼叫名為csslint
的target
,注意傳入正確的src.dir
和lib.dir
。
工具選項
檢查報告的格式
使用--format
選項可以指定csslint
工具以何種格式輸出檢查報告。
可選的格式
- text,預設格式。
- compact,壓縮格式,
warning
類的資訊在一行中輸出。 - lint-xml,通用的XML格式。
- csslint-xml,與
lint-xml
格式類似。 - checkstyle-xml,可被
CheckStyle
工具識別的格式。 - junit-xml,可被多數
CI
工具識別的格式。
使用樣例
csslint --format=lint-xml test.css
檢查規則
透過在命令列中呼叫--list-rules
可以檢視當前使用的csslint
支援的規則及描述。
指定檢查項和級別
csslint
在輸出報告時有兩種級別,error
和warning
。透過使用--warnings
和--errors
可以指定檢查過程中啟用的檢查項及對應的級別;如命令列中未使用--warnings
或--errors
,則預設啟用全部的檢查項及其級別的定義。
使用樣例
如下樣例將規則box-model
和ids
定義為warning
。
csslint --warnings=box-model,ids test.css
如下樣例將規則box-model
和ids
定義為error
。
csslint --errors=box-model,ids test.css
忽略規則
透過使用--ignore
選項,可以忽略某些檢查規則。
使用樣例
csslint --ignore=box-model,ids test.css
嵌入css檔案的選項
除了在命令列指定檢查項,csslint
同時允許將工具執行時的配置資訊寫入到css檔案中,作為檔案專屬的樣式檢查項配置。
使用方法
將規則集寫在css檔案的頭部,工具檢查檔案時,以檔案內的規則集為準。
使用樣例
/*csslint empty-rules: false, important: true*/
.button {}
在專案中應用csslint
參照文件,把csslint工具整合到打包指令碼中,對專案的css檔案進行檢查,找到兩類問題。老實說,即便是參照報告來查詢錯誤,想要搞清楚問題,仍然不容易,比如:
-
雙引號問題。
#wrapper { display: block; margin: 0 auto; text-align: left; min-width": 720px; 看到這行程式碼的問題了嗎? max-width: 1000px; }
-
單位問題。
.wrapper { display: block; margin: 0 auto; text-align: left; max-width: 1000x; 看到這行程式碼的問題了嗎? }