UNPKG

laravel-mix-favicon-generator

Version:

Laravel Mix extension to generate favicons and include them into the HTML from single PNG/JPG/SVG image.

201 lines (174 loc) 5.55 kB
const mix = require('laravel-mix'); const chokidar = require('chokidar'); const fs = require('fs'); const realFavicon = require('gulp-real-favicon'); const shell = require('shelljs'); class Favicon { name() { return 'favicon'; } dependencies() { return ['chokidar', 'gulp-real-favicon', 'shelljs']; } register(options) { this.options = Object.assign({ inputPath: 'resources/assets/favicon/generate', inputFile: '*.{jpg,png,svg}', publicPath: 'public', output: '/assets/favicon', usePathAsIs: true, dataFile: 'faviconData.json', blade: 'resources/views/blocks/favicon.blade.php', reload: false, debug: false, compression: 0, scalingAlgorithm: 'Mitchell', bgColor: '#ffffff', appName: 'Web App', chromeManifest: { name: 'Web App', display: 'standalone', orientation: 'portrait', on_conflict: 'override', declared: true } }, options || {}); } boot() { let self = this; let sourcePath = this.options.inputPath + '/' + this.options.inputFile; this.mkdir(this.options.inputPath); chokidar.watch(sourcePath, { ignoreInitial: false }).on('add', (_path) => { self.generateFavicon(_path); }); } webpackConfig(webpackConfig) { this.webpackOriginalAfterCallback = webpackConfig.devServer.after; let self = this; this.log('webpack config updated'); webpackConfig.devServer.after = (app, server) => { self.after(app, server); }; } after(app, server) { if (typeof this.webpackOriginalAfterCallback === 'function') { this.webpackOriginalAfterCallback(app, server); } this.serverHandler = server; this.log('webpack server handler attached'); } reload() { if (this.options.reload === true && typeof mix.bladeReload !== 'function' && typeof this.serverHandler !== 'undefined') { this.serverHandler.sockWrite(this.serverHandler.sockets, 'content-changed'); } return void (8); } generateFavicon(_path) { let self = this; let dataFilePath = this.options.inputPath + '/' + this.options.dataFile; let destinationPath = this.options.publicPath + '/' + this.options.output; this.mkdir(path.dirname(dataFilePath)); this.clearDir(destinationPath); self.log('Favicon is generating, wait a moment, please...'); realFavicon.generateFavicon({ masterPicture: _path, dest: destinationPath, iconsPath: this.options.output, design: { desktop_browser: {}, ios: { app_name: this.options.appName, picture_aspect: 'no_change', assets: { ios6_and_prior_icons: false, ios7_and_later_icons: true, precomposed_icons: false, declare_only_default_icon: false } }, windows: { app_name: this.options.appName, picture_aspect: 'no_change', background_color: this.options.bgColor, onConflict: 'override', assets: { windows_80_ie_10_tile: true, windows_10_ie_11_edge_tiles: { small: false, medium: true, big: true, rectangle: false } } }, android_chrome: { picture_aspect: 'no_change', themeColor: this.options.bgColor, manifest: this.options.chromeManifest, assets: { legacyIcon: false, lowResolutionIcons: false } } }, settings: { compression: this.options.compression, scaling_algorithm: this.options.scalingAlgorithm, error_on_image_too_small: false, readme_file: false, html_code_file: false, use_path_as_is: this.options.usePathAsIs }, markupFile: dataFilePath }, () => { if (self.options.blade !== false && self.options.blade !== null) { self.mkdir(path.dirname(self.options.blade)); let html = JSON.parse( fs.readFileSync(dataFilePath) ).favicon.html_code; fs.writeFile(path.normalize(self.options.blade), html, (err) => { if (err) { self.error(err); } else { fs.unlinkSync(_path); fs.unlinkSync(dataFilePath); self.log('Favicon was generated! [HTML in: ' + self.options.blade + ']'); self.reload(); } }); } else { fs.unlinkSync(_path); fs.unlinkSync(dataFilePath); self.log('Favicon was generated! [without injecting HTML]'); } }); } log(message) { if (this.options.debug === true) { console.log('laravel-mix-' + this.name() + ': ' + message); } } error(message) { console.error('laravel-mix-' + this.name() + ': ' + message); } mkdir(directory) { if (!fs.existsSync(directory)) { shell.mkdir('-p', directory); } } clearDir(directory) { if (fs.existsSync(directory)) { fs.readdir(directory, (err, files) => { if (err) throw err; for (let file of files) { fs.unlink(path.join(directory, file), err => { if (err) throw err; }); } }); } } } mix.extend('favicon', new Favicon());