Thanks for both your replies!

In the end I went with imagemin. its very easy to use and is easily put into a 
middleware.

You may have to change this around and about, but here is how I implemented a 
caching, minifying middleware:

        CDN.use("/cdn", function(req, res, next){
            var fname = path.basename(req.url);
            var ext = path.extname(fname);
            if(ext.substr(1).match(/^(png|jpg|jpeg|gif|svg)$/i)) {
                var infile = config.base+"/cdn/"+url.parse(req.url).pathname;
                if(
                    typeof req.headers["if-none-match"] != "undefined"
                    && req.headers["if-none-match"]==md5_file(infile)
                ) {
                    log.info("Its cached.");
                    res.statusCode = 304;
                    return res.end();
                }
                var dirname = path.dirname(req.url);
                mkdirp(config.base+"/cache/cdn/"+dirname, function(err){
                    if(err) {
                        console.log("Error",err);
                        return next();
                    }
                    var cacheDir = config.base+"/cache/";
                    var outdir = 
config.base+"/cache/cdn/"+path.dirname(req.url);
                    var outname = md5_file(infile)+"-"+path.basename(infile);
                    var outfile = path.join(outdir, outname);
                    var extName = ext.substr(1);
                    fs.exists(outfile, function(exists){
                        // One way or another, we're sending something here, so 
set headers.
                        var age = 30*24*60*60;
                        var time = Date.now();
                        var d = new Date(Date.now() + age*1000);
                        res.setHeader("Etag", md5_file(infile)); // Outfile 
wont exist, but we can cheat. :)
                        res.setHeader("Cache-control", "public, max-age="+age);
                        res.setHeader("Expires", d.toUTCString());
                        if(!exists) {
                            log.info("BIRD3 CDN -> Generating: ",outfile);
                            var imagemin = new Imagemin()
                                .src(infile)
                                .use(Imagemin.jpegtran({ progressive: true }))
                                .use(Imagemin.gifsicle())
                                .use(Imagemin.optipng())
                                .use(Imagemin.pngquant())
                                .use(Imagemin.svgo());
                            imagemin.run(function(err, files, stream){
                                if(err) {
                                    log.error("Imagemin error");
                                    log.error(err);
                                    return next();
                                }
                                fs.writeFile(outfile, files[0].contents, 
function(err){
                                    if(err) {
                                        log.error("Can not write optimized 
image: "+outfile);
                                        console.error(err);
                                    }
                                    res.setHeader("Content-type", 
mime.types[extName]);
                                    res.end(files[0].contents);
                                    return;
                                });
                            });
                        } else {
                            log.info("BIRD3 CDN -> Sending generated: 
"+outfile);
                            fs.readFile(outfile, function(err, output){
                                if(err) {
                                    log.error(err);
                                    return next();
                                }
                                res.setHeader("Content-type", 
mime.types[extName]);
                                res.end(output);
                                return;
                            });
                        }
                    });
                });
            } else return next();
        });

This is straight from my code. Feel free to replace parts and reuse, or make a 
module, or whatever. But I think this is quite a neat thing to have. Because if 
your images change, then this also will regenerate the images. Otherwise, it 
tells your browser that the image should be cached as well and should save you 
some reads.

Kind regards, Ingwie

PS. If you have advice on optimizing this thing, i’d be happy to hear about it. 
:)

-- 
Job board: http://jobs.nodejs.org/
New group rules: 
https://gist.github.com/othiym23/9886289#file-moderation-policy-md
Old group rules: 
https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
--- 
You received this message because you are subscribed to the Google Groups 
"nodejs" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/nodejs/8C46C814-DB49-4CB6-956D-E3F6D312B8CA%40googlemail.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to