UNPKG

vite-plugin-svg-sprite

Version:
77 lines (74 loc) 3.21 kB
import p from 'node:path'; import fs from 'node:fs'; import crypto from 'node:crypto'; import micromatch from 'micromatch'; import { optimize } from 'svgo'; import { svgToSymbol } from './svg-to-symbol.js'; const { stringify } = JSON; const exportTypes = ['vanilla', 'react', 'vue']; function getHash(content) { const h = crypto.createHash('sha256'); h.update(content); return h.digest('hex'); } export default (options) => { var _a; const match = (_a = options === null || options === void 0 ? void 0 : options.include) !== null && _a !== void 0 ? _a : '**.svg'; const svgoOptions = options === null || options === void 0 ? void 0 : options.svgo; const plugin = { name: 'svg-sprite', async transform(src, filepath) { var _a, _b, _c; if (!micromatch.isMatch(filepath, match, { dot: true, })) { return undefined; } const code = await fs.promises.readFile(filepath, 'utf-8'); const hash = getHash(code).slice(0, 8); const { name } = p.parse(filepath); const optimizedSvg = optimize(code, { ...svgoOptions, plugins: [ { name: 'prefixIds', params: { prefix: hash, }, }, ...(_a = svgoOptions === null || svgoOptions === void 0 ? void 0 : svgoOptions.plugins) !== null && _a !== void 0 ? _a : [], ], }).data; const symbolId = ((_b = options === null || options === void 0 ? void 0 : options.symbolId) !== null && _b !== void 0 ? _b : 'icon-[name]').replace(/\[hash\]/g, hash).replace(/\[name\]/g, name); const symbolResults = svgToSymbol(optimizedSvg, symbolId); if (!symbolResults) { throw new Error(`invalid svg file: ${filepath}`); } const { symbolXml, attributes } = symbolResults; let exportType = options === null || options === void 0 ? void 0 : options.exportType; if (!exportType || !exportTypes.includes(exportType)) { exportType = 'vanilla'; } const codeToReturn = ` import addSymbol from 'vite-plugin-svg-sprite/runtime/inject.js'; import { adapter } from 'vite-plugin-svg-sprite/runtime/adapters/${exportType}.js'; const id = ${stringify(symbolId)}; const name = ${stringify(name)}; const symbolXml = ${stringify(symbolXml)}; const { dispose } = addSymbol(symbolXml, id); export default adapter(id, name); export const attributes = ${stringify(attributes)} if (import.meta.hot) { import.meta.hot.dispose(dispose); import.meta.hot.accept(); } `; return { code: codeToReturn, moduleSideEffects: (_c = options === null || options === void 0 ? void 0 : options.moduleSideEffects) !== null && _c !== void 0 ? _c : true, map: { mappings: '' }, }; }, }; return plugin; };