Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Favicon support? #24

Closed
mmacaula opened this issue May 25, 2015 · 12 comments
Closed

Favicon support? #24

mmacaula opened this issue May 25, 2015 · 12 comments

Comments

@mmacaula
Copy link

I was creating a new app using this and realized my favicon was all gross. I was slightly confused at first how to do so, but figured it out. Would there be any interest in a PR to have an example to place one on the generated app?

Or alternatively, would there be interest in augmenting the html plugin to support a favicon url?

@HenrikJoreteg
Copy link
Owner

Not quite sure about how to best deal with this. Open to suggestions. I'd be tempted to not deal with favicons specifically, but instead have a way to easily include images.

@lukekarrys
Copy link
Contributor

@mmacaula I had the same experience with figuring out how to use a favicon. Curious what your solution ended up looking like? I ended up just doing this in my main app entry file:

// This just moves our favicon (without renaming it based on hash) to our build dir
require('file?name=favicon.ico!../favicon.ico');

I would vote not to change the default index.html structure to support this, since due to the number of related options (such as using a .ico, .png, supporting the other iOS webapp icons, etc) it makes more sense to have the user supply their own html.

But I do agree that we could have the example apps use a favicon (and maybe some other images) just to show how it would work.

@mmacaula
Copy link
Author

so the way i did it was to include most of the favicon html in the head section of the default template, then as my app loaded ran this module i defined:

export default function(url) {
    document.querySelector('[rel="shortcut icon"]').href=url;
}

// in another file:  
import Favicon from 'path-to-file-above'
Favicon('file!./path.to.favicon.png');

Yeah I'm not sure the best way to fit this in without seriously warping the code just for a little favicon. :) An example might be the best route here. Unless the FOU-Favicon could be considered a UX disadvantage, in that case perhaps your solution @lukekarrys is really the best one.

@lukekarrys
Copy link
Contributor

@mmacaula I think your code would be the ideal solution in some cases, but I don't think it fits in with the examples here.

I think a new example (images-and-custom-html?) would be a good addition, and it could show:

  • Using custom html with a path to favicon.png
  • Have favicon.png be compiled to that path via the file loader
  • Using other images via the file loader

Thoughts?

@mmacaula
Copy link
Author

So to me, using the main js file to run the loaders to copy the assets we want seems like something ideally to be avoided, it separates things that ideally wouldn't be separated, clutters up my main js file, looks a little magical, and is hard for newcomers to understand.

I've been diving into the plugin a bit, and I think something like this would be possible:

html : {
  'index.html' :context.defaultTemplate({
        title : 'Cesium Explorer',
                head : '<link type="image/x-icon" rel="shortcut icon" href="favicon.png">',  // or whatever
    }),
  'other.html' : '<html>', //other template
  resources : {
       'favicon.png' : '/path/to/favicon.png',
       'otherImage.png' : '/path/to/some/image.png'
  }

anything in resources, including images could be added to the compiler assets and I believe copied over. No one would be able to make a 'resources' html file, so it would effectively reserve it, but not a big deal IMO.

Thoughts?

@HenrikJoreteg
Copy link
Owner

The resources things makes sense to me. I'd say we should opt for doing it outside the html and do it as a top-level option instead. I think it should support blobs so you could do stuff like:

{ 
  in: 'app.js',
  out: 'public',
  resources: {
    images: 'images/*.png',
    'something-special.png': 'somefolder/special.png'
  }
}

@latentflip
Copy link
Contributor

Though I don't have a solution for this problem, I'm pretty hesitant about adding extra functionality beyond webpack, that webpack already does, like copying resources around (as done by url/file loader already).

The way webpack handles it is a little weird at first, but is elegant: only assets that you reference get copied, they can be hashed for cache busting, and importantly the urls in your css/html/whatever get replaced appropriately, so if you, e.g. use publicPath in your webpack config, to set an s3/cdn url for production, then your css/html will have that correctly inserted.

The challenge of course, is that that all works in the context of webpack, not within these templates currently. And I'm not totally sure how to do that yet.

I guess it kinda depends what hjs-webpack is trying to be. I like it, but I mostly like it because for the most part it just creates a preconfigured webpack config for me (that in most projects I seem to have to reach in and tweak a little after-the-fact). The html stuff is a departure from that, a little, but it does seem like a useful one, and it's at least using webpack plugins to do it. I guess I'm just hesitant about it becoming a built tool in it's own right.

@HenrikJoreteg
Copy link
Owner

Yeah, I hear ya. I contemplated just making the HTML plugin a separate thing from the start. But figured I could do that later too. Certainly don't want to bloat it either.

I do think there's benefit in answering questions like, "how do i deal with images", clearly in the docs. Perhaps simply saying, here's how this works in webpack is sufficient.

@mmacaula
Copy link
Author

I guess it all depends on how complex this html is going to be / could be. If I'm using this project, I really think webpack file loader will be everything i need, except for the one case of my favicon (at least for now). I doubt i'd really want to put other <img> tags in my html, because my app will likely handle that for me.

Don't know if you guys have seen this html-plugin, but it seems to handle the favicon and does pretty much everything else this one does. Might be worth just using that?

I'd be happy to update documentation or do another example either way. :)

@latentflip
Copy link
Contributor

After getting into the hairy depths of webpack I'm inclined to agree with you.

I can foresee a way of supporting html as entry points but it's a little hairy, and for just favicon.ico assuming it's available from the http root is probably fair enough for most things. So using that plugin under the hood if we can seems wise.

If people start doing more significant prerendering and need generic support for asset urls in there, then we can revisit later or maybe webpack/some other tool will have a plan by then?

Philip Roberts

On 28 May 2015, at 19:05, Mike Macaulay [email protected] wrote:

I guess it all depends on how complex this html is going to be / could be. If I'm using this project, I really think webpack file loader will be everything i need, except for the one case of my favicon (at least for now). I doubt i'd really want to put other tags in my html, because my app will likely handle that for me.

Don't know if you guys have seen this html-plugin, but it seems to handle the favicon and does pretty much everything else this one does. Might be worth just using that?

I'd be happy to update documentation or do another example either way. :)


Reply to this email directly or view it on GitHub.

@HenrikJoreteg
Copy link
Owner

just opened a PR with a proposed solution to this: #44 plus a few other tweaks.

Here's the relevant new section of the readme that explains how it works:


Step 5. Dealing with images and static files

option #1: requiring files

Webpack lets us do var url = require('something.png') from within your app code and url is something you can safely set as the src of an image tag, for example. When you build the project, it uses the url-loader and will base64 encode and inline it if it's smaller than the urlLoaderLimit and hash and export it otherwise.

When you do this, webpack will hash the file and use that as a name. If you basically just want to require a file so webpack knows about it, the following syntax will copy the favicon to the out directory (at the root) but leave the name unchanged: require('file?name=favicon.ico!./real/path/to/your/favicon.ico')

But, letting webpack handle images isn't always what you want to do. Sometimes you want just a simple folder of static assets and be able to reference them like you're used to. That's why there's another option:

option #2: just put 'em in your out directory

You can also just put your assests in the out directory and tell hjs-webpack to ignore them by setting a glob pattern as the clearBeforeBuild option.

Assume an out directory called public that looks like this:

public/
  some-other-generated-file.html
  index.html
  yourapp.1.1.1.css
  yourapp.1.1.1.js
  favicon.ico

  images/
    some-pic.png

Then, instead of setting clearBeforeBuild: true you can set it to a glob string like so: clearBeforeBuild: '!(images|favicon.ico)'.

Now when you build it'll clear everything that matches the glob pattern an nothing else.

In this case, it'd leave the images directory and your favicon.ico alone (more details in options section below).

note The development server will treat the out directory as the contentBase which means, that the favicon, in this case would be available at /favicon.ico despite being in public.

@HenrikJoreteg
Copy link
Owner

published 2.9.0 that includes the changes above. Considering this issue closed as now there are several documented approaches to dealing with this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants