Skip to content

Instantly share code, notes, and snippets.

@mortezasabihi
Last active April 21, 2023 11:00
Show Gist options
  • Save mortezasabihi/515d080d6ad268ff6c6a01fb2d973346 to your computer and use it in GitHub Desktop.
Save mortezasabihi/515d080d6ad268ff6c6a01fb2d973346 to your computer and use it in GitHub Desktop.
A Node.js script that converts SVG files in a directory to Vue components, using the filename as the component name and replacing spaces with hyphens.
const fs = require("fs");
const path = require("path");
const prettier = require("prettier");
const { DOMParser, XMLSerializer } = require("xmldom");
const ICONS_DIRECTORY = path.join(__dirname, "icons");
const EXPORT_DIRECTORY = path.join(__dirname, "components");
fs.readdir(ICONS_DIRECTORY, function (err, files) {
if (err) {
console.error(err);
return;
}
const svgFiles = files.filter((file) => path.extname(file) === ".svg");
svgFiles.forEach((file) => {
const componentName = path.parse(file).name.replace(/\s/g, "-");
const componentPath = path.join(EXPORT_DIRECTORY, componentName + ".vue");
const svgData = fs.readFileSync(path.join(ICONS_DIRECTORY, file), "utf8");
const parser = new DOMParser();
const doc = parser.parseFromString(svgData, "image/svg+xml");
// Replace width and height attributes values with 1em
const widthAttr = doc.documentElement.getAttribute("width");
if (widthAttr) {
doc.documentElement.setAttribute("width", "1em");
}
const heightAttr = doc.documentElement.getAttribute("height");
if (heightAttr) {
doc.documentElement.setAttribute("height", "1em");
}
// Replace stroke attribute value with currentColor in root element
const strokeAttr = doc.documentElement.getAttribute("stroke");
if (strokeAttr) {
doc.documentElement.setAttribute("stroke", "currentColor");
}
// Replace fill attribute value with currentColor if it's not "none"
const fillAttr = doc.documentElement.getAttribute("fill");
if (fillAttr && fillAttr !== "none") {
doc.documentElement.setAttribute("fill", "currentColor");
}
// Replace stroke attribute value with currentColor in child elements
const elements = doc.documentElement.getElementsByTagName("*");
for (let i = 0; i < elements.length; i++) {
const element = elements[i];
const strokeAttr = element.getAttribute("stroke");
if (strokeAttr) {
element.setAttribute("stroke", "currentColor");
}
}
const serializer = new XMLSerializer();
const svgString = serializer.serializeToString(doc.documentElement);
const vueComponent = `
<template>
${svgString}
</template>
<script>
export default {
name: '${componentName}'
}
</script>
`;
const formattedVueComponent = prettier.format(vueComponent, {
parser: "vue",
});
if (!fs.existsSync(EXPORT_DIRECTORY)) {
fs.mkdirSync(EXPORT_DIRECTORY);
}
fs.writeFile(componentPath, formattedVueComponent, function (err) {
if (err) {
console.error(err);
return;
}
console.log(`Converted ${file} to ${componentName}.vue`);
});
});
});
@mortezasabihi
Copy link
Author

mortezasabihi commented Apr 21, 2023

SVG to Vue Component Converter

This script converts all SVG files in the icons directory into Vue single-file components and outputs them to the components directory. The converted Vue components will have the same name as the original SVG file, with spaces replaced by hyphens.

Prerequisites

Node.js 10 or later

Installation

download the files.
Navigate to the project directory in your terminal.
Run npm install to install the required dependencies.

Usage

To use this script, place all SVG files that you want to convert in the icons directory. Then, run the following command in your terminal:
node convert-svg-to-vue-components.js

The script will convert all SVG files in the icons directory and output the resulting Vue components to the components directory.

Customization

You can customize the output by modifying the following constants in the convert.js file:

ICONS_DIRECTORY: The directory where the input SVG files are stored.
EXPORT_DIRECTORY: The directory where the output Vue components will be saved.

You can also modify the script to adjust the attributes of the generated Vue components.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment