3

【原子样式实践】第5篇 为微信小程序生成原子样式

 1 year ago
source link: https://blog.51cto.com/u_13556371/5763638
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

【原子样式实践】第5篇 为微信小程序生成原子样式

精选 原创

原子样式的web实现有很多,tailwind, windy, unocss 等。原子样式使用最麻烦的地方是在动态生成上,而这与工程类型、IDE皆有关系。如果原子样式项目是集成到某个项目的,事情就会变得更加复杂,实现进度和完成度都会滞后。而这,与原子样式本身的简洁特点是不符合的。

1 类似工具支持情况

1.1 快速使用

到目前为止,还没有特别适合微信原生小程序的原子样式生成工具。我们可以从现有工具的特点吸收优点进行改进。

(1) windicss ,在 CLI 模式下,一行命令安装,一行命令生成代码。

npm i -g windicss
windicss './**/*.wxml' -to windi.css

CLI 模式下使用已经是极简。其他模式下配置也不复杂。

但生成的结果不理想,没有针对微信小程序优化,编译器报告 wxss 编译错误。

(2)unocss 通过 CLI 方式在 windows powershell 下运行失败,适配还没有完全做好。

1.2 问题分析

当然,主要原因是微信内置的浏览器不是标准的WEB浏览器,各工具没有完全适配。这一点会随着标准的公开和时间的推进而越来越好。

就小程序而言,要快而小,样式无需太复杂,在手机上是全屏运行,场景更加简单。微信小程序的原子样式工具应该更加简单。

2 工具研发

2.1 特定需求

(1)​​app.wxss​​ 为全局样式,默认启用。

(2)页面根元素使用 ​​page​​​,而不是 ​​body​​。

(3)页面样式属性对应 ​​class ​​​和​​ hover-class​​​ 和  ​​placeholder-class​​。

2.2 建设思路

基于上一篇通过样式生成css代码的函数,生成微信小程序所需的样式代码,只需要从样式文件中提取样式名称即可。

提取样式只需解析 wxml 文件,从匹配的样式属性中提取样式名称,去重即可。

2.3 技术实现

本地文件 wxmp-atomic-css-generate.ts

import {htmltok, TokenType} from 'https://deno.land/x/[email protected]/mod.ts';

const RootDir = "./miniprogram"
const ConfigFileName = `${RootDir}/app.json`

interface CountMap {
[index: string]: number
}

const fullPagePath = (page: string): string => `${RootDir}/${page}.wxml`

const isClassAttr = (attrName: string): boolean => attrName == "class" || attrName == "hover-class" || attrName == "placeholder-class"

const readWxmpPages = (app: any): string[] => [...app.pages, ...app.subpackages.map((pkg: any) => pkg.pages.map((page: string) => `${pkg.root}/${page}`)).flat()]

const extraClassItem = (className: string): string[] => {
if (className == "" || className.length <= 2) {
return []
}
if (className.match(/^[\s\da-z-\\.]+$/)) {
return className.trim().split(/\s+/)
}
const result = className.trim().match(/[\w-]+/g)
if(!result) {
return []
}
return result.filter(m=> m.length > 1 && !/[A-Z]/.test(m))
}

const parseClassItem = (page: string, countMap: CountMap) => {
const xml = Deno.readTextFileSync(fullPagePath(page))
let attrName = ""
for (const token of htmltok(xml)) {
if (token.type == TokenType.ATTR_NAME) {
attrName = token.getValue()
} else if (isClassAttr(attrName) && token.type == TokenType.ATTR_VALUE) {
const items = extraClassItem(token.getValue())
items.forEach((s:string)=> {
countMap[s] = (countMap[s] || 0) + 1
})
}
}
}

const readAllClassItems = async () => {

const classNameMap: CountMap = {}
const pages = await Deno.readTextFile(ConfigFileName)
.then((data: string) => readWxmpPages(JSON.parse(data)))
.then((pages: any) => pages.map((page: string) => parseClassItem(page, classNameMap)))
return [...Object.keys(classNameMap)]
}

const classItems = await readAllClassItems()
console.log(classItems)
deno run --allow-read ./wxmp-atomic-css-generate.ts

也可以将 wxmp-atomic-css-generate.ts 文件放到代码仓库,在小程序代码下直接执行。

本文介绍了基于 deno 实现 CLI 模式的微信小程序原子样式代码生成方式,一个文件即可。微信小程序适配的主要工作任务是从页面文件中提取样式名称,通过正则表达式和函数组合可以提取。复杂点在于识别微信表达式,提取样式名称不遗漏。

  • 收藏
  • 评论
  • 分享
  • 举报

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK