Files
tauri-meeting/vite/svgIconPathOption.ts

71 lines
2.1 KiB
TypeScript
Raw Permalink Normal View History

// vite/vite-plugin-icon-dts.ts
import fs from 'fs-extra';
import glob from 'fast-glob';
import path from 'path';
import { useThrottleFn } from '@vueuse/core';
import type { PluginOption } from 'vite';
// glob 默认只支持 / 作为路径分隔符windows 下会出现问题
const normalizePath = (_path: string) => _path.replace(/\\/g, '/');
interface IconDtsOptions {
/** svg 图标文件的路径 */
iconDirs: string;
/** 输出的dts文件的路径 */
dts: string;
/** 监听变化的延迟时间 */
delay: number;
/** 接口名称 */
interfaceName: string;
}
const defualtOptions: IconDtsOptions = {
iconDirs: 'src/icons/',
dts: 'svg-icons.d.ts',
delay: 200,
interfaceName: 'BaseSvgIconPath',
};
/**
* svg dts文件
*/
export function svgIconPathOption(options: Partial<IconDtsOptions> = {}): PluginOption {
const finalOptions: IconDtsOptions = { ...defualtOptions, ...options };
const { delay, interfaceName } = finalOptions;
let { iconDirs, dts } = finalOptions;
iconDirs = normalizePath(iconDirs);
dts = normalizePath(dts);
let watcher: fs.FSWatcher | undefined = undefined;
return {
name: 'svg-icons-dts',
buildStart: () => {
if (!fs.existsSync(iconDirs)) {
console.error(`${iconDirs}不存在,请检查`);
return;
}
const update = () => {
let assets: string[] = glob.sync(`${iconDirs}/**/*.svg`, {});
assets = assets.map((i: string) => i.replace(iconDirs, '').replace('.svg', '').replace(/\//g, '-').replace(/^-+/, ''));
let output = `interface ${interfaceName} {\n`;
assets.forEach((_item) => {
output += ` '${_item}': string;\n`;
});
output += `}\n`;
const base = path.dirname(dts);
fs.ensureDirSync(base);
fs.writeFileSync(dts, output);
};
const debounceLogic = useThrottleFn(update, delay);
// 监听到文件变化,就重新写一遍
watcher = fs.watch(iconDirs, { recursive: true }, () => {
debounceLogic();
});
update();
},
buildEnd: () => {
watcher?.close();
},
};
}