@@ -25,7 +25,7 @@ const generateIcons = async ({ withTypes = false, inputDir, outputDir, cwd, file
2525 cwd : inputDir ,
2626 } ) ;
2727 if ( files . length === 0 ) {
28- console . log ( `⚠️ No SVG files found in ${ chalk . red ( inputDirRelative ) } ` ) ;
28+ console . log ( `⚠️ No SVG files found in ${ chalk . red ( inputDirRelative ) } ` ) ;
2929 return ;
3030 }
3131
@@ -34,8 +34,8 @@ const generateIcons = async ({ withTypes = false, inputDir, outputDir, cwd, file
3434 files,
3535 inputDir,
3636 outputPath : path . join ( outputDir , fileName ) ,
37+ outputDirRelative,
3738 } ) ;
38- console . log ( `🖼️ Generated SVG spritesheet in ${ chalk . green ( outputDirRelative ) } ` ) ;
3939 if ( withTypes ) {
4040 await generateTypes ( {
4141 names : files . map ( ( file : string ) => fileNameToCamelCase ( file . replace ( / \. s v g $ / , "" ) ) ) ,
@@ -56,10 +56,12 @@ async function generateSvgSprite({
5656 files,
5757 inputDir,
5858 outputPath,
59+ outputDirRelative,
5960} : {
6061 files : string [ ] ;
6162 inputDir : string ;
6263 outputPath : string ;
64+ outputDirRelative ?: string ;
6365} ) {
6466 // Each SVG becomes a symbol and we wrap them all in a single SVG
6567 const symbols = await Promise . all (
@@ -84,17 +86,18 @@ async function generateSvgSprite({
8486 } )
8587 ) ;
8688 const output = [
87- " <?xml version=\ "1.0\ " encoding=\ "UTF-8\ "?>" ,
88- " <svg xmlns=\ "http://www.w3.org/2000/svg\ " xmlns:xlink=\ "http://www.w3.org/1999/xlink\ " width=\"0\ " height=\"0\">" ,
89+ ' <?xml version="1.0" encoding="UTF-8"?>' ,
90+ ' <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="0 " height="0">' ,
8991 "<defs>" , // for semantics: https://developer.mozilla.org/en-US/docs/Web/SVG/Element/defs
9092 ...symbols . filter ( Boolean ) ,
9193 "</defs>" ,
9294 "</svg>" ,
9395 ] . join ( "\n" ) ;
94- return fs . writeFile ( outputPath , output , "utf8" ) ;
96+
97+ return writeIfChanged ( outputPath , output , `🖼️ Generated SVG spritesheet in ${ chalk . green ( outputDirRelative ) } ` ) ;
9598}
9699
97- function generateTypes ( { names, outputPath } : { names : string [ ] ; outputPath : string } ) {
100+ async function generateTypes ( { names, outputPath } : { names : string [ ] ; outputPath : string } ) {
98101 const output = [
99102 "// This file is generated by icon spritesheet generator" ,
100103 "" ,
@@ -107,16 +110,42 @@ function generateTypes({ names, outputPath }: { names: string[]; outputPath: str
107110 "" ,
108111 ] . join ( "\n" ) ;
109112
110- const file = fs . writeFile ( outputPath , output , "utf8" ) ;
111- console . log ( `${ chalk . blueBright ( "TS" ) } Generated icon types in ${ chalk . green ( outputPath ) } ` ) ;
113+ const file = await writeIfChanged (
114+ outputPath ,
115+ output ,
116+ `${ chalk . blueBright ( "TS" ) } Generated icon types in ${ chalk . green ( outputPath ) } `
117+ ) ;
112118 return file ;
113119}
114120
121+ /**
122+ * Each write can trigger dev server reloads
123+ * so only write if the content has changed
124+ */
125+ async function writeIfChanged ( filepath : string , newContent : string , message : string ) {
126+ const currentContent = await fs . readFile ( filepath , "utf8" ) ;
127+ if ( currentContent !== newContent ) {
128+ await fs . writeFile ( filepath , newContent , "utf8" ) ;
129+ console . log ( message ) ;
130+ }
131+ }
132+
115133export const iconsSpritesheet : ( args : PluginProps ) => Plugin = ( { withTypes, inputDir, outputDir, fileName, cwd } ) => ( {
116134 name : "icon-spritesheet-generator" ,
117135 apply ( config ) {
118136 return config . mode === "development" ;
119137 } ,
138+ async watchChange ( file , type ) {
139+ const inputPath = normalizePath ( path . join ( cwd ?? process . cwd ( ) , inputDir ) ) ;
140+ if ( file . includes ( inputPath ) && file . endsWith ( ".svg" ) && [ "create" , "delete" ] . includes ( type . event ) ) {
141+ await generateIcons ( {
142+ withTypes,
143+ inputDir,
144+ outputDir,
145+ fileName,
146+ } ) ;
147+ }
148+ } ,
120149 async handleHotUpdate ( { file } ) {
121150 const inputPath = normalizePath ( path . join ( cwd ?? process . cwd ( ) , inputDir ) ) ;
122151 if ( file . includes ( inputPath ) && file . endsWith ( ".svg" ) ) {
0 commit comments