tiny-vue/gulp/themeJson.mjs

145 lines
4.3 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import gulp from 'gulp'
import fs from 'fs-extra'
import transform from 'gulp-transform'
import xlsx from 'node-xlsx'
import aliasCompName from './themeJson.alias.mjs'
const build = gulp.series(parseVars, writeJson, buildExcel)
build.description = '生成theme.json 和 themeExcel文件'
export default build
// 指定哪些目录的`vars.less`不需要处理
const ignoreNames = ['src', 'base']
// css规则的正则: '--color: var(--color);' => [str, --color, var(--color)]
const ruleReg = /([\w|\-|_]*): *([\w|\-|\_|(|)]*);/
function formatRule(name, key, value, desc) {
const hasHide = desc.includes('(hide)')
desc = desc.replace('(hide)', '')
return `
"${key}": {
"id": "${key}",
"key": "${key}",
"variable": "${value}",
"value": "${value}",
"desc": "${desc}",
"descEn": "${desc}",
"component": "${name}",
"componentDesc": "",
"componentDescEn": "",
"selector": ".tiny-${name}",
"type": "",
"group": "",
"isImportant": "false",
"ui": "",
"show": 1,
"configurable": ${hasHide ? 0 : 1},
"isOpen": true
},`
}
// 处理一个vars.less文件
function parseFile(component) {
const name = aliasCompName[component.name] || component.name
let formated = []
let lessLines = component.content.split('\n')
lessLines = lessLines.map((line) => line.trim())
// 以 .component-css.........为起点行搜索。没找到,则跳出
let startRow = 0
while (startRow < lessLines.length && !lessLines[startRow].startsWith('.')) {
startRow++
}
if (startRow === lessLines.length) {
return []
}
let desc = '未知变量'
for (let row = startRow + 1; row < lessLines.length; row++) {
const line = lessLines[row]
// 跳过空行
if (line.length === 0) continue
// 注释行
if (line.startsWith('//')) {
desc = line.slice(2).trim()
continue
}
// 规则行
const matches = line.match(ruleReg)
if (matches) {
if (desc === '未知变量') component.noDescCount++
let [_, key, value] = matches
formated.push(formatRule(name, key, value, desc))
desc = '未知变量'
}
}
component.ruleCount = formated.length
return formated
}
const components = []
// 解析每个文件,将结果保存到 components 数据
function parseVars() {
return gulp.src('packages/theme/src/**/vars.less').pipe(
transform('utf8', (content, fileObj) => {
const path = fileObj.path
const name = path.split('\\').slice(-2)[0]
if (!ignoreNames.includes(name)) {
components.push({
name,
content: parseFile({ name, content, ruleCount: 0, noDescCount: 0 })
})
}
return '' // 不写文件
})
)
}
// 将 components 数据写入文件
function writeJson(cb) {
// 此处应用使用reduce插件来合并结果。 但gulp的reduce不好用。
const parsed = components.map((comp) => comp.content).flat()
let writedContent = parsed.join('').slice(1, -1) // 去除最后一个逗号
writedContent = `{\n${writedContent}\n}`
fs.writeFileSync('packages/theme/scripts/theme.json', writedContent)
cb()
}
const titleArr = (
'id,key,variable可选,value可选,desc,descEn,component,componentDesc,componentDescEn,' +
'selector,type,group,isImportant,ui所属的框架,show,configurable'
).split(',')
const fileName = 'themeExcel'
export function buildExcel(cb) {
let themeData = fs.readFileSync('packages/theme/scripts/theme.json', 'utf-8').toString()
themeData = JSON.parse(themeData)
const openXlsxObj = {} // 输出: {button:[ [标题行], [每一个变量的一行值] ]}
Object.values(themeData)
.filter((item) => item.isOpen)
.forEach((item) => {
delete item.isOpen
item.ui = '@opentiny/vue'
openXlsxObj[item.component] = openXlsxObj[item.component]
? [...openXlsxObj[item.component], Object.values(item)]
: [titleArr, Object.values(item)]
})
// 输出: [ {name:button, data:[ [],[] ]}]
const excelData = Object.entries(openXlsxObj).map(([key, value]) => {
return { name: key + '配置化', data: value }
})
// 写excel
const buffer = xlsx.build(excelData)
fs.writeFile(`packages/theme/scripts/${fileName}.xlsx`, buffer, (err) => {
if (err) {
return console.warn(`写入${fileName}失败`)
}
})
cb()
}