UNPKG

@vuetter/vite-plugin-vue-svg

Version:

Vite plugin to use svg files as Vue components.

65 lines (62 loc) 2.27 kB
import { basename } from 'path'; import { readFileSync } from 'fs'; import { compileTemplate } from '@vue/compiler-sfc'; import { optimize } from 'svgo'; const fileRegex = /\.(svg\?inline)$/; function index (options = {}) { var _a; let viteConfig; const createWrapper = (tagName) => { var _a, _b; const attrs = (_b = (_a = options === null || options === void 0 ? void 0 : options.htmlWrapper) === null || _a === void 0 ? void 0 : _a.attrs) !== null && _b !== void 0 ? _b : {}; let stringifiedAttrs = ''; for (const key in attrs) { stringifiedAttrs += ` ${key}=${attrs[key]}`; } return (code) => `<${tagName} ${stringifiedAttrs}>${code}</${tagName}>`; }; const wrapper = ((_a = options === null || options === void 0 ? void 0 : options.htmlWrapper) === null || _a === void 0 ? void 0 : _a.tagName) ? createWrapper(options.htmlWrapper.tagName) : (code) => code; async function compileSvg(source, path) { let { code } = compileTemplate({ id: path, filename: basename(path), transformAssetUrls: false, source: wrapper(source), }); code = code.replace('export function render', 'function render'); code += '\nconst VueComponent = { render };'; code += ` VueComponent.name = "icon-${basename(path.replace('.svg', ''))}"; export default VueComponent; `; if (!viteConfig.isProduction) { code += ` VueComponent.data = () => ({ path: "${path}", }); `; } return code; } async function compileFileToJS(src) { let contents = readFileSync(src).toString(); if (options.svgo !== false) { contents = optimize(contents).data; } return await compileSvg(contents, src); } return { name: 'svg-transform', async configResolved(config) { viteConfig = config; }, async transform(src, id) { if (fileRegex.test(id)) { return await compileFileToJS(id.replace('?inline', '')); } }, }; } export { index as default };