Files

54 lines
2.7 KiB
JavaScript
Raw Permalink Normal View History

const fs = require('node:fs')
const path = require('node:path')
const { spawnSync } = require('node:child_process')
const runner = require.resolve('@tarojs/webpack5-runner')
const postcss = require(require.resolve('postcss', { paths: [runner] }))
const parseSelector = require(require.resolve('postcss-selector-parser', { paths: [runner] }))
const dist = path.resolve(__dirname, '../dist')
function collect(folder) {
return fs.readdirSync(folder, { withFileTypes: true }).flatMap(entry => {
const file = path.join(folder, entry.name)
return entry.isDirectory() ? collect(file) : file.endsWith('.wxss') ? [file] : []
})
}
function validateWxss(css, label) {
postcss.parse(css).walkRules(rule => {
if (rule.parent.type === 'atrule' && /keyframes$/i.test(rule.parent.name)) return
parseSelector(selectors => selectors.walkUniversals(() => {
throw new Error(`${label}:WXSS 不支持通配选择器 ${rule.selector}`)
})).processSync(rule.selector)
parseSelector(selectors => selectors.walkPseudos(pseudo => {
if (/^:(?:first|last|nth|only)-(?:child|of-type)$/.test(pseudo.value)
&& (!pseudo.prev() || pseudo.prev().type === 'combinator')) {
throw new Error(`${label}:WXSS 结构伪类前需明确元素或类名 ${rule.selector}`)
}
})).processSync(rule.selector)
})
}
function main() {
if (!fs.existsSync(path.join(dist, 'app.wxss'))) throw new Error('请先构建微信小程序')
const files = collect(dist)
for (const file of files) validateWxss(fs.readFileSync(file, 'utf8'), path.relative(dist, file))
console.log(`WXSS 选择器兼容检查通过:${files.length} 个文件`)
const compiler = process.env.WECHAT_WXSS_COMPILER
|| '/Applications/wechatwebdevtools.app/Contents/Resources/app.asar.unpacked/node_modules/wcc-exec/wcsc'
if (!fs.existsSync(compiler)) {
if (process.env.WECHAT_WXSS_COMPILER) throw new Error('指定的微信 WXSS 编译器不存在')
console.warn('未找到微信原生 WXSS 编译器:本次仅完成静态检查,仍需开发者工具编译验收。可设置 WECHAT_WXSS_COMPILER。')
} else {
// The native compiler resolves @import from its supplied file collection.
const result = spawnSync(compiler, ['-lc', '-pc', String(files.length), ...files.map(file => `./${path.relative(dist, file)}`)], {
cwd: dist, encoding: 'utf8', maxBuffer: 16 * 1024 * 1024
})
if (result.error) throw result.error
if (result.status !== 0) throw new Error(`微信原生编译失败:${result.stderr.slice(0, 3000)}`)
console.log(`微信原生 WXSS 编译通过:${files.length} 个文件`)
}
}
module.exports = { validateWxss }
if (require.main === module) main()