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

Add option for default sizes & setting output context #12

Merged
merged 3 commits into from
Aug 20, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 22 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,33 @@ Or use it in CSS (only the first resized image will be used, if you use multiple

### Options

- `sizes: array`: specify all widths you want to use; if a specified size exceeds the original image's width, the latter will be used (i.e. images won't be scaled up)
- `sizes: array`: specify all widths you want to use; if a specified size exceeds the original image's width, the latter will be used (i.e. images won't be scaled up). You may also declare a default `sizes` array in `responsiveLoader` in your `webpack.config.js`.
- `size: integer`: specify one width you want to use; if the specified size exceeds the original image's width, the latter will be used (i.e. images won't be scaled up)
- `quality: integer`: JPEG compression quality; defaults to `95`
- `ext: string`: either `png`, `jpg`, or `gif`; use to convert to another format; defaults to original file's extension
- `background: hex`: Background fill when converting transparent to opaque images; defaults to `0xFFFFFFFF` (note: make sure this is a valid hex number)


### Examples

Set a default `sizes` array, so you don't have to declare them with each `require`.

```js
module.exports = {
entry: {...},
output: {...},
module: {
loaders: [{
test: /\.(jpe?g|png)$/i,
loader: 'responsive'
]}
},
responsiveLoader: {
sizes: [300, 600, 1200, 2000]
}
}
```

## Notes

- Doesn't support `1x`, `2x` sizes.
Expand Down
16 changes: 10 additions & 6 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,13 @@ module.exports = function loader(content) {
const loaderCallback = this.async();
const query = loaderUtils.parseQuery(this.query);
const options = this.options.responsiveLoader || {};
const sizes = query.sizes || query.size || [Number.MAX_SAFE_INTEGER];
const name = query.name || '[hash]-[width].';
const sizes = query.sizes || query.size || options.sizes || [Number.MAX_SAFE_INTEGER];
const name = query.name || options.name || '[hash]-[width].';
const outputContext = query.context || options.context || '';
// JPEG compression
const quality = parseInt(query.quality, 10) || 95;
const quality = parseInt(query.quality, 10) || options.quality || 95;
// Useful when converting from PNG to JPG
const background = parseInt(query.background, 16) || 0xFFFFFFFF;
const background = parseInt(query.background, 16) || options.background || 0xFFFFFFFF;
// Specify ext to convert to another format
const ext = query.ext || path.extname(this.resourcePath).replace(/\./, '');
const mime = MIMES[ext];
Expand All @@ -35,7 +36,7 @@ module.exports = function loader(content) {

if (options.pass) {
// emit original content only
const f = loaderUtils.interpolateName(loaderContext, '[hash].[ext]', {content: content});
const f = loaderUtils.interpolateName(loaderContext, '[hash].[ext]', {context: outputContext, content: content});
loaderContext.emitFile(f, content);
const p = '__webpack_public_path__ + ' + JSON.stringify(f);
return loaderCallback(null, 'module.exports = {srcSet:' + p + ',images:[{path:' + p + ',width:1}],src: ' + p + ',toString:function(){return ' + p + '}};');
Expand All @@ -57,7 +58,10 @@ module.exports = function loader(content) {
return queueCallback(queueErr);
}

const fileName = loaderUtils.interpolateName(loaderContext, name + ext, {content: buf}).replace(/\[width\]/ig, width);
const fileName = loaderUtils.interpolateName(loaderContext, name + ext, {
context: outputContext,
content: buf
}).replace(/\[width\]/ig, width);

loaderContext.emitFile(fileName, buf);

Expand Down
16 changes: 16 additions & 0 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,19 @@ test('single size', t => {
t.equal('foobar/ac8fbe83765514062b5da3b8966cd475-500.jpg', single.toString());
t.end();
});

test('with size defined in webpack.config.js', t => {
const multi = require('../index!./cat-1000.jpg');
t.equal('foobar/ac8fbe83765514062b5da3b8966cd475-500.jpg 500w,foobar/16c2a62d860f67276d750a7777ec932e-750.jpg 750w,foobar/6582e69db43187e14b01fa76c021cf71-1000.jpg 1000w', multi.srcSet);
t.equal('foobar/ac8fbe83765514062b5da3b8966cd475-500.jpg', multi.src);
t.equal('foobar/ac8fbe83765514062b5da3b8966cd475-500.jpg', multi.toString());
t.end();
});

test('output should be relative to context', t => {
const multi = require('../index?name=[path][hash]-[width].&context=./!./cat-1000.jpg');
t.equal('foobar/test/ac8fbe83765514062b5da3b8966cd475-500.jpg 500w,foobar/test/16c2a62d860f67276d750a7777ec932e-750.jpg 750w,foobar/test/6582e69db43187e14b01fa76c021cf71-1000.jpg 1000w', multi.srcSet);
t.equal('foobar/test/ac8fbe83765514062b5da3b8966cd475-500.jpg', multi.src);
t.equal('foobar/test/ac8fbe83765514062b5da3b8966cd475-500.jpg', multi.toString());
t.end();
});
3 changes: 3 additions & 0 deletions test/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ const path = require('path');

module.exports = {
entry: path.resolve(__dirname, 'index'),
responsiveLoader: {
sizes: [500, 750, 1000]
},
output: {
path: path.resolve(__dirname, 'build'),
publicPath: 'foobar/',
Expand Down