import type { Plugin } from "vite"; import { SAFE_CHAR_MAP_LOCALE } from "./config"; import { createCtx } from "../ctx"; import { compareVersion, readFile, rootDir } from "../utils"; import { createEps } from "../eps"; import { uniq } from "lodash"; // 获取 tailwind.config.ts 中的颜色 function getTailwindColor() { const config = readFile(rootDir("tailwind.config.ts")); if (!config) { return null; } try { // 从配置文件中动态提取主色和表面色 const colorResult: Record = {}; // 提取 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 version = getVersion(); // 主题配置 const theme = readFile(rootDir("theme.json"), true); // 主题配置 ctx["theme"] = theme; if (compareVersion(version, "8.0.2") >= 0) { // 颜色值 ctx["color"] = getTailwindColor(); } // 安全字符映射 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]]); } code = code.replace( "const ctx = {}", `const ctx = ${JSON.stringify(ctx, null, 4)}`, ); } 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]; } } 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: "" }, }; } }, }, ]; }