Files
deerflow-code/frontend-web/scripts/check-legacy-css.mjs
T

73 lines
2.8 KiB
JavaScript
Raw 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 fs from "node:fs";
import path from "node:path";
import postcss from "postcss";
/**
* 旧浏览器(麒麟 Chromium ~80)CSS 产物守卫:构建后运行,防止回归。
* 迁移后的结构性保证(见 tailwind.config.ts / postcss.config.js):
* - Tailwind v3 输出无 @layer(Chrome 99+)与 @property(Chrome 85+);
* - dark: 变体经 postcss-dark-descendant 改写为 .dark 后代形式,全库 :is( 为 0;
* - 媒体查询 range 语法(Chrome 104+)由 lightningcss 按 target 转译;
* - 手写 CSS 不使用 :is()(复杂参数无法安全降级,源头展开为逗号选择器);
* - color-mix()/oklch() 仅允许出现在 @supports 守护内或带前置回退声明。
* :has()(Chrome 105+)与 :where()(Chrome 88+)按渐进增强放行,不在检查范围。
*/
const unsupportedColor = /(?:color-mix|oklch|oklab|lab|lch)\(/i;
const assetsDir = path.resolve("dist/assets");
if (!fs.existsSync(assetsDir)) {
throw new Error("dist/assets 不存在,请先运行 pnpm build");
}
const cssFiles = fs.readdirSync(assetsDir).filter((f) => f.endsWith(".css"));
if (cssFiles.length === 0) throw new Error("dist/assets 中没有 CSS 构建产物");
const failures = [];
const hardTokens = [
[/@layer\b/, "@layer(Chrome 99+)"],
[/@property\b/, "@property(Chrome 85+)"],
[/:is\(/, ":is()(Chrome 88+)"],
[/\(width\s*>=|\(width\s*<=|\(height\s*>=/, "媒体查询 range 语法(Chrome 104+)"],
];
let guardedColors = 0;
for (const file of cssFiles) {
const raw = fs.readFileSync(path.join(assetsDir, file), "utf8");
for (const [re, label] of hardTokens) {
const hits = raw.match(new RegExp(re.source, "g")) || [];
if (hits.length > 0) failures.push(`${file}: ${hits.length} 处 ${label}`);
}
const root = postcss.parse(raw, { from: file });
root.walkDecls((decl) => {
if (!unsupportedColor.test(decl.value)) return;
guardedColors += 1;
let anc = decl.parent;
while (anc) {
if (anc.type === "atrule" && anc.name === "supports" && unsupportedColor.test(anc.params)) return;
anc = anc.parent;
}
let prev = decl.prev();
while (prev?.type === "comment") prev = prev.prev();
const hasFallback =
!decl.prop.startsWith("--") &&
prev?.type === "decl" &&
prev.prop === decl.prop &&
!unsupportedColor.test(prev.value);
if (!hasFallback) {
failures.push(`${file}: 未守护的现代颜色 ${decl.prop}: ${decl.value.slice(0, 60)}`);
}
});
}
if (failures.length > 0) {
console.error("旧浏览器 CSS 兼容检查失败:\n");
console.error(failures.slice(0, 50).join("\n"));
if (failures.length > 50) console.error(`... 及另外 ${failures.length - 50} 处`);
process.exit(1);
}
console.log(
`旧浏览器(麒麟 Chromium ~80)CSS 兼容检查通过(${guardedColors} 处守护的现代颜色声明)。`,
);