Skip to content

Instantly share code, notes, and snippets.

@alenaksu
Created December 14, 2024 08:50
Show Gist options
  • Save alenaksu/95aab1475508b037d91d9cb3c0d959f0 to your computer and use it in GitHub Desktop.
Save alenaksu/95aab1475508b037d91d9cb3c0d959f0 to your computer and use it in GitHub Desktop.
Vite SVG Spritesheet Plugin
const vitePluginSvgSpritesheet = ({
path,
output,
}: {
path: string | string[];
output: string;
}): Plugin => {
let spritesheet: string;
return {
name: 'vite-plugin-svg-spritesheet',
async configResolved(config) {
const files = await glob(path);
const icons: string[] = [];
const xmlOptions = {
preserveOrder: false,
alwaysCreateTextNode: false,
trimValues: true,
ignoreAttributes: false,
allowBooleanAttributes: true,
parseAttributeValue: false,
parseTagValue: false,
removeNSPrefix: true,
ignoreDeclaration: true,
};
const parser = new XMLParser(xmlOptions);
const builder = new XMLBuilder({
...xmlOptions,
format: false,
});
for (const file of files) {
const fileName = basename(file);
const svgString = await readFile(file, 'utf-8');
const icon = parser.parse(svgString);
icon.symbol = icon.svg;
icon.symbol['@_id'] = fileName.replace(extname(fileName), '');
icon.symbol['@_width'] = '100%';
icon.symbol['@_height'] = '100%';
delete icon.svg;
icons.push(builder.build(icon));
}
spritesheet = `<svg xmlns="http://www.w3.org/2000/svg"><defs>${icons.join('')}</defs></svg>`;
},
generateBundle() {
this.emitFile({
type: 'asset',
source: spritesheet,
fileName: output,
});
},
};
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment