本文相当于带读 @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
作用。
并说明如何理解、调试、验证。