Cowboy-coder/bundle-up — Issue #8: image processing
Author: panosru
Created: 2012-01-26 00:23:00+00:00
State: open

I would love to have image support for bundle-up.

For me, bundle-up is a way to reduce http request process on my web-page and the goal of the module is to 1) have faster web page 2) organize my files outside of public folder. bundle-up doing a good work so far with css and js files but what about images? Should we ignore images? Last time I checked most of my http requests where on images and not css/js files... so if we need to blame someone on abuse http requests that someone are images. Of course we can't bundle images into one huge image and use css to get our image... this would be more than insane and useless to do (there is already [stylus sprite module](https://github.com/andris9/stylus-sprite) to do that thing for us...) what we can do is reduce our images size (like html5 boiler plate do with build script).

based on our latest conversation about api and hooks we could have something like this:

```js
BundleUp(app, 'assets.js', {
staticRoot: __dirname + '/public'
staticUrlRoot: '/'
development:true
bundles: {
minifyCss:true,
minifyJs:true,
processImages : {
extensions : ['png','jpg'],
caseSensitive : false, //In order png extension to match foo.png and foo.PNG
ignoreFileNames : [ //Adds patterns for file names (excluding .extension) to be ignored by the image processor
'foo',
'^foo[0-9]',
'foo$'
]
}
},
hooks: {
preMinify: {
js: [...]
css: [...]
},
afterMinify: {
js: [...]
css: [...]
},
images : {
all : [
{ pattern : '_watter$', hooks : [wattermark], replace : [ '_watter', ''] }
],
jpg : [
{ pattern : '*', hooks : [dropQuality(80)] }
]
}
}
});
```

So, to explain the above settings... the module should check if the `processImages` property is set, is so then proceed...

`extensions` (Array) property is defining which extensions should be processed, those who are not there will be ignored by the processor.

`caseSensitive` (Boolean) property defines is extensions should be case sensitive or not. In other words if it is set to true jpg will match with JPG too.

`ignoreFileNames` (Array) property defines patterns which will be used by the processor in order to check for the name of all the files that will be processed by the image processor and for the files that will match those patterns will be ignored by the processor.

`hooks.images` (Object) property have one standard property which is the `all` property, `all` property covers all the files that will be processed by the image processor. Besides `all` property it gets as property the file extensions that we passed to the `extensions` property, so if our `extensions` property is set to ['png','jpg'] then we can use inside `hooks.images` the `all`, `png` and `jpg` property, if our `extensions` property would be `['png'] then if we would pass `hooks.images.jpg` it would be ignored by the processor completely.

`hooks.images.*` (Array) property, as explained previously in the place of __*__ we can set `all` and our extensions. This property should be an array or objects, each object inside it can take 3 properties which are:

`pattern` (String) a pattern to match the names of the files that will be processed by hooks

`hooks` (Array) an array of hooks that will be used, the order should matter also, first hook in array should be executed and once is ready it should return the image in order for the next hook to continue working on that image, the last hook that would return the image would be the image that would be used by the processor to be copied in public.

`replace` (Array) an array of two string values where the first string value would be used as the **search** pattern and the second value would be used as the **replace** pattern, this simply identifies how the target file name should be.

The reason `hooks.images.*` are arrays is because we can apply different hooks based on different file name pattern, why? because I could have `foo_80.jpg`, `bar_80.jpg`, `foo_20.jpg`, `bar_20.jpg` and I could simply do:

```js
...
jpg : [
{ pattern : '_80$', hooks : [dropQuality(80)], replace: ['_80', ''] }, //Removes the _80 from the target file name
{ pattern : '_20$', hooks : [dropQuality(20)], replace: ['_20', ''] }
]
...
```

Similar API could be applied on css/js but I don't see any reason to do so, so I believe it could be useful only on images.