辛宝Otto

辛宝Otto 的玄酒清谈

北漂前端程序员儿 / 探索新事物 / Web Worker 主播之一/内向话痨
xiaoyuzhou
email

淺析 uni-app-x 樣式解析

淺析 uni-app-x 樣式解析

本文相當於帶讀 @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 插件 expandnormalize,交給 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 功能。

並說明如何理解、調試、驗證。

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。