-
-
Save hirasso/bc2563ed7a107a77c21ddf09b90432b5 to your computer and use it in GitHub Desktop.
Vite favicons plugin
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Vite Favicons | |
APP_ICON="./resources/images/favicon.svg" | |
APP_NAME="My Application" | |
APP_NAME_SHORT="MyApp" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { defineConfig, loadEnv } from "vite"; | |
import { favicons } from "./vite.favicons.ts"; | |
export default defineConfig(async ({ mode }) => { | |
const env = loadEnv(mode, process.cwd(), ""); | |
return { | |
plugins: [ | |
favicons({ | |
source: env.APP_ICON, | |
outputDir: `path/to/generated/favicons`, | |
publicDir: "public", | |
favilibOptions: { | |
name: env.APP_NAME, | |
short_name: env.APP_NAME_SHORT, | |
}, | |
}), | |
], | |
}; | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Plugin, ResolvedConfig } from "vite"; | |
import favilib, { FaviconOptions } from "favilib"; | |
import fs from "fs/promises"; | |
import path from "path"; | |
import colors from "picocolors"; | |
type Options = { | |
source: string; | |
outputDir: string; | |
publicDir: string; | |
favilibOptions: FaviconOptions; | |
verbose?: boolean; | |
}; | |
/** | |
* Generate favicons when building | |
* | |
* All paths will be resolved to your current cwd | |
* | |
* @param source The path to the source file | |
* @param outputDir The directory where the favicons should be saved | |
* @param publicDir Your public root directory. favicon.ico will be copied there | |
* @param favilibOptions Options for favilib. @see https://github.com/withpwa/favilib/blob/main/test/createExamples.mjs | |
* @param verbose Activate verbose logging | |
*/ | |
export function favicons({ | |
source, | |
outputDir, | |
publicDir, | |
favilibOptions, | |
verbose = false, | |
}: Options): Plugin { | |
let resolvedConfig: ResolvedConfig; | |
/** | |
* @see https://github.com/withpwa/favilib/ | |
*/ | |
async function generate() { | |
const { envDir } = resolvedConfig; | |
const rootDir = envDir ?? process.cwd(); | |
const dirs = { | |
output: path.resolve(rootDir, outputDir), | |
public: path.resolve(rootDir, publicDir), | |
}; | |
/** log if verbose is true */ | |
const debug = (...args: any[]) => { | |
verbose && console.log(...args); | |
}; | |
/** log an info */ | |
const info = (message: string) => { | |
resolvedConfig.logger.info(message); | |
}; | |
const relative = (dir: string) => path.relative(envDir, dir); | |
const response = await favilib(source, { | |
name_localized: undefined, | |
short_name_localized: undefined, | |
manifestRelativePaths: true, | |
...favilibOptions, | |
}); | |
await fs.mkdir(dirs.output, { recursive: true }); | |
/** Save images */ | |
for (const item of response.images) { | |
await fs.writeFile( | |
`${dirs.output}/${item.name}`, | |
item.contents, | |
"binary", | |
); | |
/** Copy favicon.ico to the public dir */ | |
if (item.name === "favicon.ico") { | |
await fs.copyFile( | |
`${dirs.output}/${item.name}`, | |
`${dirs.public}/${item.name}`, | |
); | |
info( | |
`${colors.green("✓ generated")} ${colors.gray(`${relative(`${dirs.public}/${item.name}`)}`)}`, | |
); | |
} | |
debug(`${item.name} saved.`); | |
} | |
// Save files | |
for (const item of response.files) { | |
await fs.writeFile( | |
`${dirs.output}/${item.name}`, | |
item.contents, | |
"binary", | |
); | |
debug(`${item.name} saved.`); | |
} | |
// Save HTML files | |
await fs.writeFile(`${dirs.output}/index.html`, response.html, "binary"); | |
debug("index.html saved."); | |
info( | |
`${colors.green("✓ generated")} ${colors.gray(`${relative(dirs.output)}`)}`, | |
); | |
} | |
return { | |
name: "favicons", | |
apply: "build", | |
configResolved(config) { | |
resolvedConfig = config; | |
}, | |
async closeBundle() { | |
await generate(); | |
}, | |
}; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment