2025-10-17 22:11:10 +08:00

203 lines
4.8 KiB
TypeScript
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 type { Plugin } from "vite";
import { SAFE_CHAR_MAP_LOCALE } from "./config";
import { createCtx } from "../ctx";
import { readFile, rootDir } from "../utils";
// 获取 tailwind.config.ts 中的颜色
function getTailwindColor() {
const config = readFile(rootDir("tailwind.config.ts"));
if (!config) {
return null;
}
try {
// 从配置文件中动态提取主色和表面色
const colorResult: Record<string, string> = {};
// 提取 getPrimary 调用中的颜色名称
const primaryMatch = config.match(/getPrimary\(["']([^"']+)["']\)/);
const primaryColorName = primaryMatch?.[1];
// 提取 getSurface 调用中的颜色名称
const surfaceMatch = config.match(/getSurface\(["']([^"']+)["']\)/);
const surfaceColorName = surfaceMatch?.[1];
if (primaryColorName) {
// 提取 PRIMARY_COLOR_PALETTES 中对应的调色板
const primaryPaletteMatch = config.match(
new RegExp(
`{\\s*name:\\s*["']${primaryColorName}["'],\\s*palette:\\s*({[^}]+})`,
"s",
),
);
if (primaryPaletteMatch) {
// 解析调色板对象
const paletteStr = primaryPaletteMatch[1];
const paletteEntries = paletteStr.match(/(\d+):\s*["']([^"']+)["']/g);
if (paletteEntries) {
paletteEntries.forEach((entry: string) => {
const match = entry.match(/(\d+):\s*["']([^"']+)["']/);
if (match) {
const [, key, value] = match;
colorResult[`primary-${key}`] = value;
}
});
}
}
}
if (surfaceColorName) {
// 提取 SURFACE_PALETTES 中对应的调色板
const surfacePaletteMatch = config.match(
new RegExp(
`{\\s*name:\\s*["']${surfaceColorName}["'],\\s*palette:\\s*({[^}]+})`,
"s",
),
);
if (surfacePaletteMatch) {
// 解析调色板对象
const paletteStr = surfacePaletteMatch[1];
const paletteEntries = paletteStr.match(/(\d+):\s*["']([^"']+)["']/g);
if (paletteEntries) {
paletteEntries.forEach((entry: string) => {
const match = entry.match(/(\d+):\s*["']([^"']+)["']/);
if (match) {
const [, key, value] = match;
// 0 对应 surface其他对应 surface-*
const colorKey = key === "0" ? "surface" : `surface-${key}`;
colorResult[colorKey] = value;
}
});
}
}
}
return colorResult;
} catch (error) {
return null;
}
}
// 获取版本号
function getVersion() {
const pkg = readFile(rootDir("package.json"), true);
return pkg?.version || "0.0.0";
}
export function codePlugin(): Plugin[] {
return [
{
name: "vite-cool-uniappx-code-pre",
enforce: "pre",
async transform(code, id) {
if (id.includes("/cool/ctx/index.ts")) {
const ctx = await createCtx();
// 主题配置
const theme = readFile(rootDir("theme.json"), true);
// 主题配置
ctx["theme"] = theme || {};
// 颜色值
ctx["color"] = getTailwindColor();
if (!ctx.subPackages) {
ctx.subPackages = [];
}
if (!ctx.tabBar) {
ctx.tabBar = {};
}
// 安全字符映射
ctx["SAFE_CHAR_MAP_LOCALE"] = [];
for (const i in SAFE_CHAR_MAP_LOCALE) {
ctx["SAFE_CHAR_MAP_LOCALE"].push([i, SAFE_CHAR_MAP_LOCALE[i]]);
}
let ctxCode = JSON.stringify(ctx, null, 4);
ctxCode = ctxCode.replace(`"tabBar": {}`, `"tabBar": {} as TabBar`);
ctxCode = ctxCode.replace(
`"subPackages": []`,
`"subPackages": [] as SubPackage[]`,
);
code = code.replace("const ctx = {}", `const ctx = ${ctxCode}`);
code = code.replace(
"const ctx = parse<Ctx>({})!",
`const ctx = parse<Ctx>(${ctxCode})!`,
);
}
// if (id.includes("/cool/service/index.ts")) {
// const eps = await createEps();
// if (eps.serviceCode) {
// const { content, types } = eps.serviceCode;
// const typeCode = `import type { ${uniq(types).join(", ")} } from '../types';`;
// code =
// typeCode +
// "\n\n" +
// code.replace("const service = {}", `const service = ${content}`);
// }
// }
if (id.endsWith(".json")) {
const d = JSON.parse(code);
for (let i in d) {
let k = i;
for (let j in SAFE_CHAR_MAP_LOCALE) {
k = k.replaceAll(j, SAFE_CHAR_MAP_LOCALE[j]);
}
if (k != i) {
d[k] = d[i];
delete d[i];
}
}
// 转字符串不然会报错Method too large
if (id.includes("/locale/")) {
let t: string[] = [];
(d as string[][]).forEach(([a, b]) => {
t.push(`${a}<__=__>${b}`);
});
code = JSON.stringify([[t.join("<__&__>")]]);
} else {
code = JSON.stringify(d);
}
}
return {
code,
map: { mappings: "" },
};
},
},
{
name: "vite-cool-uniappx-code",
transform(code, id) {
if (id.endsWith(".json")) {
return {
code: code.replace("new UTSJSONObject", ""),
map: { mappings: "" },
};
}
},
},
];
}