svg-spritemap-webpack-plugin
Version:
Generates symbol-based SVG spritemap from all .svg files in a directory
66 lines (65 loc) • 2.14 kB
JavaScript
import fs from 'node:fs';
import path from 'node:path';
import { mkdirp } from 'mkdirp';
// Helpers
import styleFormatters from './style-formatters/index.js';
import { SVG_PARSER } from './svg.js';
// Types
import { StylesType } from '../types.js';
export const generateStyles = (spritemap, options, warnings, compilation) => {
var _a;
if (!spritemap) {
return;
}
const extension = path.extname(options.styles.filename).toLowerCase().slice(1);
const formatter = styleFormatters[extension];
if (formatter === undefined) {
throw new Error(`Unsupported styles extension: ${extension}`);
}
const svg = (_a = SVG_PARSER.parseFromString(spritemap, 'image/svg+xml').documentElement) !== null && _a !== void 0 ? _a : undefined;
if (!svg) {
return;
}
const symbols = [...svg.childNodes].filter((node) => {
return node.nodeName === 'symbol';
});
const output = formatter(symbols, options, compilation);
writeStylesToDisk(output, options);
return output;
};
const writeStylesToDisk = (content, options) => {
if (!content) {
return;
}
const type = getStylesType(content, options.styles.filename);
if (!type || type === StylesType.Asset) {
return;
}
const location = {
[StylesType.Directory]: options.styles.filename,
[StylesType.Module]: path.resolve(import.meta.dirname, '../../', options.styles.filename.replace('~', ''))
}[type];
const exists = fs.existsSync(location);
if (exists && fs.readFileSync(location, 'utf8') === content) {
return;
}
if (type === StylesType.Directory && !exists) {
const dirname = path.dirname(location);
if (!fs.existsSync(dirname)) {
mkdirp.sync(dirname);
}
}
fs.writeFileSync(location, content, 'utf8');
};
export const getStylesType = (content, filename) => {
if (!content || !filename) {
return;
}
if (path.parse(filename).dir) {
return StylesType.Directory;
}
if (filename.startsWith('~')) {
return StylesType.Module;
}
return StylesType.Asset;
};