本文相當於帶讀 @dcloudio/uni-nvue-styler
專案功能和結構,並介紹了如何驗證實際效果。
舉的例子是 uni-app-x
在 iOS 平台的例子,實際 Android 平台, nvue
平台操作步驟一樣。
平台限制#
在處理跨平台 css 處理時候,有一些需求和網頁端不同:
- 跨端不能完整支援所有 css 寫法,是 css 規則的子集
- 跨端自帶的 css 默認值需要和 web、小程序對齊
- 跨端 css 需要考慮 class 定義、style 定義、style 運行時切換定義
- 跨端子元素樣式不能繼承父元素樣式
這裡解釋 uni-app-x 的 ios 部分是如何解析樣式的。樣式是一個重要且特殊的邏輯部分。
技術上講,本質還是一些自定義的 postcss 插件來解析用戶傳遞的樣式,和客戶端平台配合,將一些特殊的樣式進行轉寫修改。
源碼位置#
uni-app 倉庫
是指 github 上的 next 分支。
存在 @dcloudio/uni-nvue-styler
包。
- 樣式測試文件
packages/uni-nvue-styler/__tests__/normalize.spec.ts
- 主邏輯
packages/uni-nvue-styler/src/index.ts
其中主邏輯部分邏輯入口文件
export { expand } from './expand'
export { normalize } from './normalize'
export { objectifier } from './objectifier'
export { parse } from './parse'
一條 css 規則轉換的奇妙旅行!
技術上解釋:
- 是自定義了兩個 postcss 插件
expand
和normalize
,交給 postcss 進行處理。 - 得到的結果交給
objectifier
轉為客戶端接受的對象類型
parse 字串解析#
這是核心主方法,通過 postcss 進行語法轉換,進一步轉成對象。
expand 展開#
兩個 postcss
插件之一。常見的 css 邏輯縮寫展開成多條最小規則
比如 border/background/transition
等等
舉例 transition: margin-top 500ms ease-in-out 1s
這一條樣式需要展開成多條規則
normalize 標準化處理#
兩個 postcss
插件之一。承接上一條拆開的 css 規則,將值進一步調整,比如長度單位、非法值統一處理。
比如 width:200px -> 去除單位 200
比如 width: a -> 非法值會忽略並告警
比如 color: #f00 -> 補全 #ff0000
比如transition/font-face
objectifier 字串轉對象#
處理好之後的 css 規則轉化為對象,形成當前頁面、組件下的樣式規則集合。
舉例,字串 .abc{color:red}
會轉換成類似下面的對象。這裡的空字串是為了支援其他的 css 選擇器,比如子代選擇器 .a .b
。比如直接子代選擇器 >
等。
舉例,處理 !important
在具體的樣式前面添加 !
var abc = {
"":{
color:'red'
},
".bar ":{
left: 2
}
}
閱讀理解源碼#
如果日常使用時候遇到了 bug,需要修復問題或者補充新功能,就需要閱讀、調試源碼。
因為這部分邏輯比較抽象,最適合的方案是閱讀測試用例,從而進一步理解每個步驟的作用。
如何驗證是否生效#
有時候會做 feature/fix
改動,如果完成了代碼改動,補充了對應的單元測試,如何驗證改動效果?
這裡做個流程總結:
- 構建
@dcloudio/uni-nvue-styler
產物 - 替換 HBuilderX 產物
- 驗證效果
構建產物#
修改 uni-nvue-styler
需要執行構建,可以直接執行
pnpm run build nvue-styler
得到產物包,定位 dist 文件夾
替換產物#
打開 HBuilderX 的包內容,注意我這裡是內部的 -Dev
版本:
/Applications/HBuilderX-Dev.app/Contents/HBuilderX/plugins/uniapp-cli-vite/node_modules/@dcloudio/uni-nvue-styler/dist
替換剛才的 dist 文件,應該是三個文件。
重啟後重新編譯,應該就可以看到修改後的效果了。
總結#
介紹了 uni-app
專案 next
分支的 @dcloudio/uni-nvue-styler
功能。
並說明如何理解、調試、驗證。