Skip to content

Instantly share code, notes, and snippets.

@kevinleedrum
Created June 7, 2024 14:54
Show Gist options
  • Save kevinleedrum/5dc78d3b24e5b9ff85c5ebf07cf8b056 to your computer and use it in GitHub Desktop.
Save kevinleedrum/5dc78d3b24e5b9ff85c5ebf07cf8b056 to your computer and use it in GitHub Desktop.
vite-plugin-icon-sprite
import { promises as fs } from 'fs';
import path from 'path';
export default function IconSpritePlugin() {
async function generateIconSprite() {
const iconsDir = path.join(process.cwd(), 'static', 'icons');
const files = await fs.readdir(iconsDir);
let symbols = '';
let iconNameType = 'export type IconName =\n';
for (const file of files) {
if (!file.endsWith('.svg')) continue;
let svgContent = await fs.readFile(path.join(iconsDir, file), 'utf8');
const id = file.replace('.svg', '');
svgContent = svgContent
.replace(/id="[^"]+"/, '')
.replace('<svg', `<symbol id="${id}"`)
.replace('</svg>', '</symbol>');
symbols += svgContent + '\n';
iconNameType += ` | '${id}'\n`;
}
const sprite = `<svg width="0" height="0" style="display: none">\n\n${symbols}</svg>`;
await fs.writeFile(path.join(process.cwd(), 'static', 'icon-sprite.svg'), sprite);
await writeChangesToType(iconNameType);
}
async function writeChangesToType(iconNameType) {
const iconNameTypePath = path.join(process.cwd(), 'src', 'types', 'IconName.ts');
const currentContent = await fs.readFile(iconNameTypePath, 'utf8');
if (currentContent === iconNameType) return;
await fs.writeFile(iconNameTypePath, iconNameType);
}
return {
name: 'icon-sprite-plugin',
buildStart() {
return generateIconSprite();
},
configureServer(server) {
server.watcher.add(path.join(process.cwd(), 'static', 'icons', '*.svg'));
server.watcher.on('change', async (changedPath) => {
if (changedPath.endsWith('.svg')) return generateIconSprite();
});
},
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment