Fingerprinting of arbitrary resources

16 views
Skip to first unread message

Dmitry Schetnikovich

unread,
Jan 2, 2015, 3:24:56 PM1/2/15
to rapt...@googlegroups.com
It is a first time in my entire developer's career when I really enjoy writing frontend part of the sites. And this is because of RaptorJS Optimizer + Marko. Thank you for these really cool tools!

Sometimes I just need to copy fingerprinted static resource to outputDir (default to "static" folder), that is defined in HTML template and not in CSS files. For instance, below I specified URL of favicon:

<html>
  <head>
    ...
    <link rel="shortcut icon" href="/common/favicon.ico">
    ...
  </head>
  <body>
    ...
  </body>
</html>

Is it possible to "optimize" href attribute and produce something like favicon-b8fcec0d.ico in "static" folder? So that I can safely turn off HTTP expiration for favicon.

For <img /> tags we have <optimizer-img /> Marko tag. Maybe we have the similar functionality for arbitrary resources? 

For instance, something like that:

<optimizer-tag tag-name="link" rel="shortcut icon" resource-href="./favicon.ico">

Attributes that starts with "resource-name"  are paths to resources which should be fingerprinted. Such attributes should be rendered as "name".

Or maybe even today we can require some Optimizer module and write something like the following?

<require module="optimizer/resource-optimizer" var="optimizer" />
...
<link rel="shortcut icon" href="${optimizer.url('./favicon.ico')}">

Is there is a way to do something similar?

Thank you!

Patrick Steele-Idem

unread,
Jan 7, 2015, 2:31:20 AM1/7/15
to rapt...@googlegroups.com
Thank you for the feedback, Dmitry! I'm glad you are enjoying these tools. Unfortunately this message was sitting in the moderation queue and I did not get an email notification from Google Groups so sorry for the delayed response.

The optimizer module provides an API for optimizing any resource, but you are right that we only provide a <optimizer-img> tag for optimizing image resources conveniently inside a template. I think that is a gap that we should try to fill and I think your proposals are a great starting point. FYI, you can always use the JavaScript API directly and pass the resulting URL to the template:

require('optimizer').optimizeResource('/path/to/common/favicon.ico', function(err, optimizedResource) {
    console.log('optimized URL: ', optimizedResource.url);
});

I propose we move this discussion over to a Github issue because I think it should be tracked as a feature request. I went ahead and created a new Github issue:

I'm going to give this some more thought, but I would like to see a solve for this in the very near future. Please feel free to add comments to the Github issue.

Thanks again,

--Patrick

Phil Gates-Idem

unread,
Jan 7, 2015, 10:09:54 AM1/7/15
to rapt...@googlegroups.com
As Patrick said, we definitely need a better solution for this since it is so common.

Here's an alternate solution:

IN THE RENDERER:
var optimizerImage = require('optimizer-image');
var template = require('marko').load(require.resolve('./template.marko'));

module.exports = function(input, out) {
 input
.dataProviders = {
     favicon: function(callback) {
         optimizerImage
.getImageInfo(require.resolve('src/assets/favicon.png'), callback);
     }
 };
 
 
template.render(input, out);
};

IN THE TEMPLATE:
<async-fragment data-provider="data.dataProviders.favicon" var="imageInfo">
 
<link rel="shortcut icon" href="$!imageInfo.url" />
</async-fragment>


It's not as concise as I would have liked but it will get the job done.

Thanks,
Phil

Patrick Steele-Idem

unread,
Jan 8, 2015, 2:06:45 AM1/8/15
to rapt...@googlegroups.com
A new version of the optimizer module has been published with support for this feature. Please see the following Github issue: https://github.com/raptorjs/optimizer/issues/34

Thanks again for the very helpful feedback. Let us know if you run into any issues with this feature.

--Patrick

Dmitry Schetnikovich

unread,
Jan 8, 2015, 11:31:32 AM1/8/15
to rapt...@googlegroups.com
Simply amazing! Patrick, my hat's off to you for so quick and nice solution! I've already pushed this feature to production and love Optimizer even more :) 

I'm using this not only for *.ico files, but also for *.svg files that are loaded by JS. I'm introducing global variable that will be used by JS lately:

    <optimizer-resource path="src/common/svgs/icons.svg" var="svg"/>
   
<script>var svg_url = "${svg.url}";</script>

So definitely Option 2, as mention in GitHub ticket for this feature, is more flexible than Option 1. Although Option 1 can be seen as additional usability improvement for more simple situations, like with *.ico files. Marko's ability to introduce attributes for existing tags is really powerful feature and should be utilized :)

Phil, thank you for your alternate solution, I was really close to select it! But Patrick managed to implement new feature faster than I copied your solution :)

Thank you all!
Reply all
Reply to author
Forward
0 new messages