Skip to content

Instantly share code, notes, and snippets.

@pugson
Created June 4, 2024 09:38
Show Gist options
  • Save pugson/55dcbc0fafd2da6aa3dccafddc328563 to your computer and use it in GitHub Desktop.
Save pugson/55dcbc0fafd2da6aa3dccafddc328563 to your computer and use it in GitHub Desktop.
fix svg in jsx with a script
import fs from "fs/promises";
import path from "path";
import { fileURLToPath } from "url";
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const APPS_DIRECTORY = path.resolve(__dirname, "../../apps");
// Common SVG attributes that need renaming to camelCase for JSX
const attributeReplacements = {
"fill-opacity=": "fillOpacity=",
"fill-rule=": "fillRule=",
"stroke-opacity=": "strokeOpacity=",
"stroke-width=": "strokeWidth=",
"stroke-linecap=": "strokeLinecap=",
"stroke-linejoin=": "strokeLinejoin=",
"stroke-dasharray=": "strokeDasharray=",
"stroke-dashoffset=": "strokeDashoffset=",
"xlink:href=": "xlinkHref=",
"clip-path=": "clipPath=",
"clip-rule=": "clipRule=",
"stop-color=": "stopColor=",
"view-box=": "viewBox=",
"text-anchor=": "textAnchor=",
"gradient-transform=": "gradientTransform=",
"gradient-units=": "gradientUnits=",
"pattern-content-units=": "patternContentUnits=",
"pattern-units=": "patternUnits=",
"pattern-transform=": "patternTransform=",
"mask-content-units=": "maskContentUnits=",
"mask-units=": "maskUnits=",
"alignment-baseline=": "alignmentBaseline=",
"baseline-shift=": "baselineShift=",
"enable-background=": "enableBackground=",
"image-rendering=": "imageRendering=",
};
// This function transforms SVG JSX code. Extend this with additional transformations as needed.
function transformSvgJsx(content) {
let transformedContent = content.replace(/class=/g, "className=");
for (const [original, jsxCompatible] of Object.entries(
attributeReplacements
)) {
const regExp = new RegExp(original, "g");
transformedContent = transformedContent.replace(regExp, jsxCompatible);
}
return transformedContent;
}
async function processFile(filePath) {
const filePathOnlyAfterAppsDirectory = filePath.replace(APPS_DIRECTORY, "");
try {
const data = await fs.readFile(filePath, "utf8");
const transformedData = await transformSvgJsx(data);
await fs.writeFile(filePath, transformedData, "utf8");
if (data !== transformedData) {
console.log(`✅ Fixed SVG in: ${filePathOnlyAfterAppsDirectory}`);
}
} catch (err) {
console.error(
`Error processing file: ${filePathOnlyAfterAppsDirectory}`,
err
);
}
}
async function findAndProcessFiles() {
console.log(`🔍 Searching in: ${APPS_DIRECTORY}`);
try {
// Directly use the dynamic import for 'glob' that supports promises
const glob = (await import("glob")).glob;
const files = await glob(`${APPS_DIRECTORY}/**/*.tsx`, { nodir: true });
if (!files || files.length === 0) {
console.log("[fix-svg-jsx] No .tsx files found.");
return;
}
files.forEach(async (file) => {
await processFile(file);
});
} catch (err) {
console.error("[fix-svg-jsx] Error:", err);
} finally {
console.log("🎉 [fix-svg-jsx] Done.");
}
}
console.log("📦 [fix-svg-jsx] Processing .tsx files...");
findAndProcessFiles().catch(console.error);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment