@vuetter/vite-plugin-vue-svg
Version:
Vite plugin to use svg files as Vue components.
67 lines (63 loc) • 2.29 kB
JavaScript
;
var path = require('path');
var fs = require('fs');
var compilerSfc = require('@vue/compiler-sfc');
var svgo = require('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$1) {
let { code } = compilerSfc.compileTemplate({
id: path$1,
filename: path.basename(path$1),
transformAssetUrls: false,
source: wrapper(source),
});
code = code.replace('export function render', 'function render');
code += '\nconst VueComponent = { render };';
code += `
VueComponent.name = "icon-${path.basename(path$1.replace('.svg', ''))}";
export default VueComponent;
`;
if (!viteConfig.isProduction) {
code += `
VueComponent.data = () => ({
path: "${path$1}",
});
`;
}
return code;
}
async function compileFileToJS(src) {
let contents = fs.readFileSync(src).toString();
if (options.svgo !== false) {
contents = svgo.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', ''));
}
},
};
}
module.exports = index;