RealFaviconGenerator / gulp-real-favicon

Gulp plugin to generate a multiplatform favicon with RealFaviconGenerator
76 stars 6 forks source link

Error: path must be a string #7

Open bjarnef opened 8 years ago

bjarnef commented 8 years ago

I am using the gulp plugin to generate favicons, however it doesn't seems to work correct with special characters in manifest name, e.g. with Danish æ, ø and å. If I manually enter æ, ø or å into manifest name it works fine, but the task seems to convert it to ø

Furthermore the task returns an error like this:

[15:17:57] Finished 'favicon' after 2.82 ms
fs.js:438
  return binding.open(pathModule._makeLong(path), stringToFlags(flags), mode);
                 ^
TypeError: path must be a string
    at Object.fs.openSync (fs.js:438:18)
    at Object.fs.writeFileSync (fs.js:977:15)
    at C:\Visual Studio Projects\STG\STG\STG.Site\node_modules\gulp-real-favicon\index.js:30:10
    at ProxyWriter.<anonymous> (C:\Visual Studio Projects\STG\STG\STG.Site\node_modules\gulp-real-favicon\node_modules\rfg-api\index.js:64:11)
    at ProxyWriter.emit (events.js:117:20)
    at DirWriter.emit (events.js:92:17)
    at end (C:\Visual Studio Projects\STG\STG\STG.Site\node_modules\gulp-real-favicon\node_modules\rfg-api\node_modules\fstream\lib\writer.js:324:14)
    at C:\Visual Studio Projects\STG\STG\STG.Site\node_modules\gulp-real-favicon\node_modules\rfg-api\node_modules\fstream\lib\writer.js:314:34
    at endUtimes (C:\Visual Studio Projects\STG\STG\STG.Site\node_modules\gulp-real-favicon\node_modules\rfg-api\node_modules\fstream\lib\writer.js:215:58)
Process terminated with code 8.
    at setProps (C:\Visual Studio Projects\STG\STG\STG.Site\node_modules\gulp-real-favicon\node_modules\rfg-api\node_modules\fstream\lib\writer.js:297:5)

In this case I have also wrapped it inside a loop to execute for 4 sites, but it sometimes not generate icons for all sites. The error mentioned before get I even it's not wrapped inside a loop and just running for single favicon.

gulp.task("favicon", function () {

    var sites = [
        { name: "Højmark", alias: "hojmark", bgColor: "#ffffff" },
        { name: "Lion Alpin", alias: "lionalpin", bgColor: "#10528c" },
        { name: "Team Benns Ski", alias: "tbski", bgColor: "#9e1231" },
        { name: "Clickski", alias: "clickski", bgColor: "#e5582b" }
    ];

    for (i = 0; i < sites.length; i++) {
        //sites[i].name
        //sites[i].alias
        console.log("generating favicon for " + sites[i].name);

        realFavicon.generateFavicon({
            masterPicture: config.sourcePath + "img/favicon/" + sites[i].alias + ".png",
            dest: "./dist/img/favicons/" + sites[i].alias + "/",
            iconsPath: "./",
            design: {
                ios: {
                    pictureAspect: 'backgroundAndMargin', //noChange
                    backgroundColor: sites[i].bgColor,
                    margin: '14%'
                },
                desktopBrowser: {},
                windows: {
                    pictureAspect: 'noChange',
                    backgroundColor: sites[i].bgColor, //#ffffff
                    onConflict: 'override'
                },
                androidChrome: {
                    pictureAspect: 'backgroundAndMargin', //noChange
                    margin: '17%',
                    backgroundColor: '#ffffff',
                    themeColor: '#ffffff',
                    manifest: {
                        name: sites[i].name,
                        display: 'browser',
                        orientation: 'notSet',
                        onConflict: 'override',
                        declared: true
                    }
                },
                safariPinnedTab: {
                    pictureAspect: 'blackAndWhite', //silhouette
                    threshold: 53.125,
                    themeColor: "#5bbad5"
                }
            },
            settings: {
                scalingAlgorithm: 'Mitchell',
                errorOnImageTooSmall: false
            }//,
            //markupFile: FAVICON_DATA_FILE
        }, function () {
            done();
        });

    }

});

Finally according to docs https://developer.chrome.com/extensions/manifest the properties _manifestversion, name and version are required - how do I add _manifestversion and version*?

phbernard commented 8 years ago

I don't have much time right here right now, but at least I can answer your last question regarding the version and name. You can use the existing_manifest attribute. Basically, it allows you to write your own manifest (with name and version) and let RFG patch it with the icons. For an example of this, I suggest you to generate a favicon for Google Web Starter Kit and look for existingManifest in the generated code.

bjarnef commented 8 years ago

Okay, I will take a futher look on some of the other options. Are there a full documentation of the docs for the gulp task? Most of the properties fit the docs here, but just camelCase for gulp task. https://realfavicongenerator.net/api/non_interactive_api

However e.g. favicon_design is just design in gulp task and the gulp task also has properties like dest, iconsPath and markupFile which are not documented on that page - I just know it from the generated gulp task(s).

Futheremore the error I got before was related to L30 in gulp-real-favicon/index.js:

fs.writeFileSync(params.markupFile, JSON.stringify(data));

I uncommeted markupFile: FAVICON_DATA_FILE in gulp task, because I got this error first time I ran the task, where the json file wasn't generated.. but if I uncomment that line now I don' get the error (because the json file now exists) and it also reach the callback/success function.

Btw. the generation of the the gulp task add a done() function, but it isn't defined or do anything. Maybe add a simple function to demonstrate its use.

e.g.

gulp.task("generate-favicon", function () {
        realFavicon.generateFavicon({
        ...
            markupFile: FAVICON_DATA_FILE
        }, function () {
            done();
        });

    function done() {
        console.log("done");
    }
});
phbernard commented 8 years ago

Yeah sorry, there is no documentation for Gulp. You guess well: it's all in https://realfavicongenerator.net/api/non_interactive_api, with CamelCase and some tricks. Not really dev friendly.

Although a solid documentation should be a good thing, the spirit of the Gulp feature in RFG is to use the web site to generate the code for you and give you the instructions to make it work. This is what you did but as soon as the plugin failed you were suddenly on your own :(

Two things puzzle me:

bjarnef commented 8 years ago

Yes, I also like how the website generate examples tasks for Gulp, Grunt etc.. it just don't include all options, but the interactive api docs helped me to see which options are available.

So my complete task looks like this:

// File where the favicon markups are stored
var FAVICON_DATA_FILE = config.projectPath + 'faviconData.json';

// Generate the icons. This task takes a few seconds to complete.
// You should run it at least once to create the icons. Then,
// you should run it whenever RealFaviconGenerator updates its
// package (see the check-for-favicon-update task below).
gulp.task("favicon", function () {

    var sites = [
        { name: "Højmark", alias: "hojmark", bgColor: "#ffffff", themeColor: "#004268" },
        { name: "Lion Alpin", alias: "lionalpin", bgColor: "#10528c", themeColor: "#10528c" },
        { name: "Team Benns Ski", alias: "tbski", bgColor: "#9e1231", themeColor: "#9e1231" },
        { name: "Clickski", alias: "clickski", bgColor: "#e5582b", themeColor: "#e5582b" }
    ];

    sites.forEach(function(entry) {

        var siteName = entry.name,
            siteAlias = entry.alias,
            siteBgColor = entry.bgColor,
            siteThemeColor = entry.themeColor;

        // for Windows/IE it is also generating a browserconfig.xml - https://msdn.microsoft.com/library/dn455106.aspx

        console.log("Generating favicon for " + siteName + " (" + siteAlias + ")");

            realFavicon.generateFavicon({
                masterPicture: config.sourcePath + "img/favicons/" + siteAlias + ".png",
                dest: config.faviconsDist + "/" + siteAlias + "/",
                iconsPath: config.faviconsDist + "/" + siteAlias + "/",
                design: {
                    ios: {
                        pictureAspect: 'backgroundAndMargin', //noChange
                        backgroundColor: siteBgColor,
                        margin: '14%'
                    },
                    desktopBrowser: {},
                    windows: {
                        pictureAspect: 'noChange',
                        backgroundColor: siteBgColor, //#ffffff
                        onConflict: 'override'
                    },
                    firefoxApp: {
                        pictureAspect: "circle",
                        keepPictureInCircle: true,
                        circleInnerMargin: 3,
                        backgroundColor: siteBgColor,
                        manifest: {
                            appName: siteName
                        }
                    },
                    androidChrome: {
                        pictureAspect: 'backgroundAndMargin', //noChange
                        margin: '17%',
                        backgroundColor: siteBgColor,
                        themeColor: siteThemeColor,
                        manifest: {
                            name: siteName,
                            display: 'browser', //standalone
                            orientation: 'notSet',
                            onConflict: 'override',
                            declared: true
                        }
                    },
                    safariPinnedTab: {
                        pictureAspect: 'blackAndWhite', //silhouette
                        threshold: 53.125,
                        themeColor: "#5bbad5"
                    }
                },
                settings: {
                    compression: 0, // 0 (no compression) to 5 (highest compression level)
                    scalingAlgorithm: 'Mitchell', // Mitchell, NearestNeighbor, Cubic, Bilinear, Lanczos, Spline
                    errorOnImageTooSmall: false
                },
                //versioning: { // true (auto-versioning), false (the favicon files are not versioned)
                //    paramName: "ver",
                //    paramValue: "1"
                //},
                markupFile: FAVICON_DATA_FILE
            },
            function() {
                done(siteName);
            });

        function done(name) {
            console.log("Done generating favicons for " + name);
        };

    });

});
phbernard commented 8 years ago

Encoding. As a French, I don't have those fancy characters of yours, yet my é, ô and friends give me mini-headaches from time to time.

That's right, markupFile is mandatory. Else, you don't store the markups to inject later in the HTML and the whole favicon thing doesn't make any sense.

The plugin should throw an explicit error message when this happen, so the user knows what he should do to fix.

bjarnef commented 8 years ago

Yes, ANSI is just a much smaller set of characters than UTF-8 http://www.w3schools.com/charsets/ref_html_ansi.asp which seems to contain è, é, ê and ë, but not æ, ø and å .. I think it is only Nordic contries where we use these characters http://www.nndata.no/home/jborgos/alfabet.htm

Well, in my case I only use the task to generate the favicons - not to inject them. The examples demonstrate it with *.html files, but I am not sure how well it works for MVC/Razor views *.cshtml files.

For now I reference to them like this:

<!-- Favicons -->
    <link rel="apple-touch-icon" sizes="57x57" href="/dist/img/favicons/@(siteNameNoEnding)/apple-touch-icon-57x57.png">
    <link rel="apple-touch-icon" sizes="60x60" href="/dist/img/favicons/@(siteNameNoEnding)/apple-touch-icon-60x60.png">
    <link rel="apple-touch-icon" sizes="72x72" href="/dist/img/favicons/@(siteNameNoEnding)/apple-touch-icon-72x72.png">
    <link rel="apple-touch-icon" sizes="76x76" href="/dist/img/favicons/@(siteNameNoEnding)/apple-touch-icon-76x76.png">
    <link rel="apple-touch-icon" sizes="114x114" href="/dist/img/favicons/@(siteNameNoEnding)/apple-touch-icon-114x114.png">
    <link rel="apple-touch-icon" sizes="120x120" href="/dist/img/favicons/@(siteNameNoEnding)/apple-touch-icon-120x120.png">
    <link rel="apple-touch-icon" sizes="144x144" href="/dist/img/favicons/@(siteNameNoEnding)/apple-touch-icon-144x144.png">
    <link rel="apple-touch-icon" sizes="152x152" href="/dist/img/favicons/@(siteNameNoEnding)/apple-touch-icon-152x152.png">
    <link rel="apple-touch-icon" sizes="180x180" href="/dist/img/favicons/@(siteNameNoEnding)/apple-touch-icon-180x180.png">
    <link rel="icon" type="image/png" href="/dist/img/favicons/@(siteNameNoEnding)/favicon-32x32.png" sizes="32x32">
    <link rel="icon" type="image/png" href="/dist/img/favicons/@(siteNameNoEnding)/android-chrome-192x192.png" sizes="192x192">
    <link rel="icon" type="image/png" href="/dist/img/favicons/@(siteNameNoEnding)/favicon-96x96.png" sizes="96x96">
    <link rel="icon" type="image/png" href="/dist/img/favicons/@(siteNameNoEnding)/favicon-16x16.png" sizes="16x16">
    <link rel="manifest" href="/dist/img/favicons/@(siteNameNoEnding)/manifest.json">
    <link rel="mask-icon" href="/dist/img/favicons/@(siteNameNoEnding)/safari-pinned-tab.svg" color="#5bbad5">
    <link rel="shortcut icon" href="/dist/img/favicons/@(siteNameNoEnding)/favicon.ico">

    <!-- Win8 tile -->
    <meta name="msapplication-TileColor" content="@faviTileColor">
    <meta name="msapplication-TileImage" content="/dist/img/favicons/@(siteNameNoEnding)/mstile-144x144.png">
    <meta name="msapplication-config" content="/dist/img/favicons/@(siteNameNoEnding)/browserconfig.xml">

    <meta name="theme-color" content="@faviThemeColor">
    <meta name="application-name" content="@appName">
    @*<meta name="mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-capable" content="yes">*@
    <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">