From a6fd30767a294964a90dcdc42eb96f46701caa74 Mon Sep 17 00:00:00 2001 From: Alem Tuzlak Date: Sun, 12 May 2024 12:52:13 +0200 Subject: [PATCH] v1.1.0 Improvements --- package-lock.json | 12 +++--- package.json | 4 +- src/index.ts | 45 ++++++++++++++++---- test-apps/remix-vite-cjs/package.json | 2 +- test-apps/remix-vite/icons/a.svg | 1 + test-apps/remix-vite/icons/b.svg | 1 + test-apps/remix-vite/icons/c.svg | 1 + test-apps/remix-vite/icons/d.svg | 1 + test-apps/remix-vite/icons/de.svg | 0 test-apps/remix-vite/icons/test.svg | 3 +- test-apps/remix-vite/package.json | 2 +- test-apps/remix-vite/public/icons/sprite.svg | 5 +++ test-apps/remix-vite/public/icons/types.ts | 10 +++++ 13 files changed, 68 insertions(+), 19 deletions(-) create mode 100644 test-apps/remix-vite/icons/a.svg create mode 100644 test-apps/remix-vite/icons/b.svg create mode 100644 test-apps/remix-vite/icons/c.svg create mode 100644 test-apps/remix-vite/icons/d.svg create mode 100644 test-apps/remix-vite/icons/de.svg diff --git a/package-lock.json b/package-lock.json index 1e9d2a0..84671df 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,7 +16,7 @@ "chalk": "^4.1.2", "glob": "^10.3.12", "node-html-parser": "^6.1.13", - "vite": "^5.2.10" + "vite": "5.2.11" }, "devDependencies": { "@types/node": "^20.12.7", @@ -11621,9 +11621,9 @@ } }, "node_modules/vite": { - "version": "5.2.10", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.2.10.tgz", - "integrity": "sha512-PAzgUZbP7msvQvqdSD+ErD5qGnSFiGOoWmV5yAKUEI0kdhjbH6nMWVyZQC/hSc4aXwc0oJ9aEdIiF9Oje0JFCw==", + "version": "5.2.11", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.2.11.tgz", + "integrity": "sha512-HndV31LWW05i1BLPMUCE1B9E9GFbOu1MbenhS58FuK6owSO5qHm7GiCotrNY1YE5rMeQSFBGmT5ZaLEjFizgiQ==", "dependencies": { "esbuild": "^0.20.1", "postcss": "^8.4.38", @@ -12666,7 +12666,7 @@ "eslint-plugin-react": "^7.33.2", "eslint-plugin-react-hooks": "^4.6.0", "typescript": "^5.1.6", - "vite": "^5.1.0", + "vite": "^5.2.11", "vite-tsconfig-paths": "^4.2.1" }, "engines": { @@ -12696,7 +12696,7 @@ "eslint-plugin-react": "^7.33.2", "eslint-plugin-react-hooks": "^4.6.0", "typescript": "^5.1.6", - "vite": "^5.1.0", + "vite": "^5.2.11", "vite-tsconfig-paths": "^4.2.1" }, "engines": { diff --git a/package.json b/package.json index 0dd2fe4..0a7bcf2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "vite-plugin-icons-spritesheet", - "version": "1.0.0", + "version": "1.1.0", "description": "Vite plugin that generates a spritesheet out of your icons.", "main": "./dist/index.js", "module": "./dist/index.mjs", @@ -58,7 +58,7 @@ "dependencies": { "chalk": "^4.1.2", "glob": "^10.3.12", - "vite": "^5.2.10", + "vite": "5.2.11", "node-html-parser": "^6.1.13" }, "devDependencies": { diff --git a/src/index.ts b/src/index.ts index 2541aca..ffbb588 100644 --- a/src/index.ts +++ b/src/index.ts @@ -25,7 +25,7 @@ const generateIcons = async ({ withTypes = false, inputDir, outputDir, cwd, file cwd: inputDir, }); if (files.length === 0) { - console.log(`⚠️ No SVG files found in ${chalk.red(inputDirRelative)}`); + console.log(`⚠️ No SVG files found in ${chalk.red(inputDirRelative)}`); return; } @@ -34,8 +34,8 @@ const generateIcons = async ({ withTypes = false, inputDir, outputDir, cwd, file files, inputDir, outputPath: path.join(outputDir, fileName), + outputDirRelative, }); - console.log(`🖼️ Generated SVG spritesheet in ${chalk.green(outputDirRelative)}`); if (withTypes) { await generateTypes({ names: files.map((file: string) => fileNameToCamelCase(file.replace(/\.svg$/, ""))), @@ -56,10 +56,12 @@ async function generateSvgSprite({ files, inputDir, outputPath, + outputDirRelative, }: { files: string[]; inputDir: string; outputPath: string; + outputDirRelative?: string; }) { // Each SVG becomes a symbol and we wrap them all in a single SVG const symbols = await Promise.all( @@ -84,17 +86,18 @@ async function generateSvgSprite({ }) ); const output = [ - "", - "", + '', + '', "", // for semantics: https://developer.mozilla.org/en-US/docs/Web/SVG/Element/defs ...symbols.filter(Boolean), "", "", ].join("\n"); - return fs.writeFile(outputPath, output, "utf8"); + + return writeIfChanged(outputPath, output, `🖼️ Generated SVG spritesheet in ${chalk.green(outputDirRelative)}`); } -function generateTypes({ names, outputPath }: { names: string[]; outputPath: string }) { +async function generateTypes({ names, outputPath }: { names: string[]; outputPath: string }) { const output = [ "// This file is generated by icon spritesheet generator", "", @@ -107,16 +110,42 @@ function generateTypes({ names, outputPath }: { names: string[]; outputPath: str "", ].join("\n"); - const file = fs.writeFile(outputPath, output, "utf8"); - console.log(`${chalk.blueBright("TS")} Generated icon types in ${chalk.green(outputPath)}`); + const file = await writeIfChanged( + outputPath, + output, + `${chalk.blueBright("TS")} Generated icon types in ${chalk.green(outputPath)}` + ); return file; } +/** + * Each write can trigger dev server reloads + * so only write if the content has changed + */ +async function writeIfChanged(filepath: string, newContent: string, message: string) { + const currentContent = await fs.readFile(filepath, "utf8"); + if (currentContent !== newContent) { + await fs.writeFile(filepath, newContent, "utf8"); + console.log(message); + } +} + export const iconsSpritesheet: (args: PluginProps) => Plugin = ({ withTypes, inputDir, outputDir, fileName, cwd }) => ({ name: "icon-spritesheet-generator", apply(config) { return config.mode === "development"; }, + async watchChange(file, type) { + const inputPath = normalizePath(path.join(cwd ?? process.cwd(), inputDir)); + if (file.includes(inputPath) && file.endsWith(".svg") && ["create", "delete"].includes(type.event)) { + await generateIcons({ + withTypes, + inputDir, + outputDir, + fileName, + }); + } + }, async handleHotUpdate({ file }) { const inputPath = normalizePath(path.join(cwd ?? process.cwd(), inputDir)); if (file.includes(inputPath) && file.endsWith(".svg")) { diff --git a/test-apps/remix-vite-cjs/package.json b/test-apps/remix-vite-cjs/package.json index bc07d13..9ead437 100644 --- a/test-apps/remix-vite-cjs/package.json +++ b/test-apps/remix-vite-cjs/package.json @@ -32,7 +32,7 @@ "eslint-plugin-react": "^7.33.2", "eslint-plugin-react-hooks": "^4.6.0", "typescript": "^5.1.6", - "vite": "^5.1.0", + "vite": "^5.2.11", "vite-tsconfig-paths": "^4.2.1" }, "engines": { diff --git a/test-apps/remix-vite/icons/a.svg b/test-apps/remix-vite/icons/a.svg new file mode 100644 index 0000000..7086e85 --- /dev/null +++ b/test-apps/remix-vite/icons/a.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/test-apps/remix-vite/icons/b.svg b/test-apps/remix-vite/icons/b.svg new file mode 100644 index 0000000..7086e85 --- /dev/null +++ b/test-apps/remix-vite/icons/b.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/test-apps/remix-vite/icons/c.svg b/test-apps/remix-vite/icons/c.svg new file mode 100644 index 0000000..dc1ced5 --- /dev/null +++ b/test-apps/remix-vite/icons/c.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/test-apps/remix-vite/icons/d.svg b/test-apps/remix-vite/icons/d.svg new file mode 100644 index 0000000..7086e85 --- /dev/null +++ b/test-apps/remix-vite/icons/d.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/test-apps/remix-vite/icons/de.svg b/test-apps/remix-vite/icons/de.svg new file mode 100644 index 0000000..e69de29 diff --git a/test-apps/remix-vite/icons/test.svg b/test-apps/remix-vite/icons/test.svg index 58f1bcf..7bbc380 100644 --- a/test-apps/remix-vite/icons/test.svg +++ b/test-apps/remix-vite/icons/test.svg @@ -1,2 +1,3 @@ - \ No newline at end of file + + \ No newline at end of file diff --git a/test-apps/remix-vite/package.json b/test-apps/remix-vite/package.json index d2966bb..c2beb91 100644 --- a/test-apps/remix-vite/package.json +++ b/test-apps/remix-vite/package.json @@ -32,7 +32,7 @@ "eslint-plugin-react": "^7.33.2", "eslint-plugin-react-hooks": "^4.6.0", "typescript": "^5.1.6", - "vite": "^5.1.0", + "vite": "^5.2.11", "vite-tsconfig-paths": "^4.2.1" }, "engines": { diff --git a/test-apps/remix-vite/public/icons/sprite.svg b/test-apps/remix-vite/public/icons/sprite.svg index 39f63ce..7573540 100644 --- a/test-apps/remix-vite/public/icons/sprite.svg +++ b/test-apps/remix-vite/public/icons/sprite.svg @@ -2,6 +2,11 @@ + + + + + \ No newline at end of file diff --git a/test-apps/remix-vite/public/icons/types.ts b/test-apps/remix-vite/public/icons/types.ts index 0c5f28e..bc810a9 100644 --- a/test-apps/remix-vite/public/icons/types.ts +++ b/test-apps/remix-vite/public/icons/types.ts @@ -2,7 +2,17 @@ export type IconName = | "Test" + | "De" + | "D" + | "C" + | "B" + | "A" export const iconNames = [ "Test", + "De", + "D", + "C", + "B", + "A", ] as const