203 lines
4.8 KiB
TypeScript
203 lines
4.8 KiB
TypeScript
|
|
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: "" },
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
];
|
|||
|
|
}
|