Skip to content

Commit f0a2639

Browse files
committedApr 26, 2018
move imagemin to peer, plugin loading to client, and test with webpack 4
1 parent 412f0ce commit f0a2639

10 files changed

+6082
-487
lines changed
 

‎.travis.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
language: node_js
22
node_js:
3-
- '4.8'
3+
- 'lts/*'
44
- stable

‎CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changelog
22

3+
## 3.0.0
4+
5+
**Breaking Change** By default no image optimizing is done. The options for the loader are passed directly to `imagemin.buffer`, so `options.plugins` should be passed as an array of configured imagemin plugins. If `plugins` is a function it will be called with the webpack loader context, and the plugin array should be returned.
6+
37
## 2.0.1
48

59
Updated dependencies

‎README.md

+59-33
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,11 @@
77
[![JS Standard Style][style-image]][style]
88
[![MIT License][license-image]][LICENSE]
99

10-
Image minimizing loader for webpack 2, meant to be used with [url-loader](https://github.com/webpack/url-loader), [file-loader](https://github.com/webpack/file-loader), or [raw-loader](https://github.com/webpack/raw-loader)
10+
Image minimizing loader for webpack 4, meant to be used with [url-loader](https://github.com/webpack/url-loader), [file-loader](https://github.com/webpack/file-loader), or [raw-loader](https://github.com/webpack/raw-loader)
1111

12-
> Minify PNG, JPEG, GIF and SVG images with [imagemin](https://github.com/imagemin/imagemin)
12+
> Minify PNG, JPEG, GIF and SVG images with [imagemin](https://github.com/imagemin/imagemin) [plugins](https://www.npmjs.com/search?q=keywords:imageminplugin)
1313
14-
*Issues with the minimized output should be reported [to imagemin](https://github.com/imagemin/imagemin/issues).*
15-
16-
Comes with the following optimizers:
17-
18-
- [gifsicle](https://github.com/imagemin/imagemin-gifsicle)*Compress GIF images*
19-
- [mozjpeg](https://github.com/imagemin/imagemin-mozjpeg)*Compress JPEG images*
20-
- [optipng](https://github.com/imagemin/imagemin-optipng)*Compress PNG images*
21-
- [pngquant](https://github.com/imagemin/imagemin-pngquant)*Compress PNG images*
22-
- [svgo](https://github.com/imagemin/imagemin-svgo)*Compress SVG images*
14+
img-loader has a peer dependency on `imagemin`, so you will need to make sure to include that, along with any imagemin plugins you will use.
2315

2416

2517
## Install
@@ -47,18 +39,56 @@ module: {
4739
}
4840
```
4941

50-
The default minification includes: `gifsicle`, `mozjpeg`, `optipng`, & `svgo`. Each with their default settings.
51-
52-
`pngquant` can be enabled by configuring it in the options.
42+
By default the loader simply passes along the image unmodified.
5343

5444

5545
### Options
5646

57-
Options can also be passed by specifying properties matching each optimizer in your rule options. `false` or `null` can be used to disable one of the default optimizers.
47+
Options are forwarded to `imagemin.buffer(image, options)`, so any plugins you would like to use for optimizing the images are passed as the `plugins` property.
5848

5949
For more details on each plugin's options, see their documentation on [Github](https://github.com/imagemin).
6050

61-
``` javascript
51+
```js
52+
{
53+
module: {
54+
rules: [
55+
{
56+
test: /\.(jpe?g|png|gif|svg)$/i,
57+
use: [
58+
'url-loader?limit=10000',
59+
{
60+
loader: 'img-loader',
61+
options: {
62+
plugins: [
63+
require('imagemin-gifsicle')({
64+
interlaced: false
65+
}),
66+
require('imagemin-mozjpeg')({
67+
progressive: true,
68+
arithmetic: false
69+
}),
70+
require('imagemin-pngquant')({
71+
floyd: 0.5,
72+
speed: 2
73+
}),
74+
require('imagemin-svgo')({
75+
plugins: [
76+
{ removeTitle: true },
77+
{ convertPathData: false }
78+
]
79+
})
80+
]
81+
}
82+
}
83+
]
84+
}
85+
]
86+
}
87+
}
88+
```
89+
90+
`plugins` can also be a function, which will receive the [webpack loader context](https://webpack.js.org/api/loaders/#the-loader-context) and should return the plugins array.
91+
```js
6292
{
6393
module: {
6494
rules: [
@@ -69,23 +99,19 @@ For more details on each plugin's options, see their documentation on [Github](h
6999
{
70100
loader: 'img-loader',
71101
options: {
72-
enabled: process.env.NODE_ENV === 'production',
73-
gifsicle: {
74-
interlaced: false
75-
},
76-
mozjpeg: {
77-
progressive: true,
78-
arithmetic: false
79-
},
80-
optipng: false, // disabled
81-
pngquant: {
82-
floyd: 0.5,
83-
speed: 2
84-
},
85-
svgo: {
86-
plugins: [
87-
{ removeTitle: true },
88-
{ convertPathData: false }
102+
plugins (context) {
103+
if (process.env.NODE_ENV === 'production') return []
104+
return [
105+
require('imagemin-svgo')({
106+
plugins: [
107+
{ cleanupIDs: false },
108+
{
109+
prefixIds: {
110+
prefix: path.basename(context.resourcePath, 'svg')
111+
}
112+
}
113+
]
114+
})
89115
]
90116
}
91117
}

‎__tests__/fixture.gif

1.09 KB
Loading

‎__tests__/fixture.svg

+1
Loading

‎__tests__/index.spec.js

+38-40
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,51 @@
11
/* eslint-env mocha */
22
'use strict'
3-
43
var assert = require('assert')
5-
var Buffer = require('safe-buffer').Buffer
6-
var loader = require('..')
4+
var fs = require('fs')
5+
var path = require('path')
6+
var gifsicle = require('imagemin-gifsicle')
7+
var svgo = require('imagemin-svgo')
8+
var run = require('./run-webpack')
9+
10+
var fixtureGif = fs.readFileSync(path.resolve(__dirname, './fixture.gif'))
11+
var fixtureSvg = fs.readFileSync(path.resolve(__dirname, './fixture.svg'))
712

813
describe('img-loader', () => {
9-
describe('svgo', () => {
10-
it('optimizes svg images by default', (done) => {
11-
var img = Buffer.from('<svg><g><path d="M0 0" /></g></svg>')
12-
var context = {
13-
loader,
14-
async () {
15-
return (error, buffer) => {
16-
if (error) return done(error)
17-
assert.equal(buffer.toString(), '<svg/>')
18-
done()
19-
}
20-
}
21-
}
22-
context.loader(img)
14+
it('passes the img though unchanged by default', function () {
15+
return run('./fixture.gif').then(function (image) {
16+
assert(image.equals(fixtureGif), 'gif should be unchanged')
2317
})
18+
})
2419

25-
it('passes content through when whole loader disabled', () => {
26-
var img = Buffer.from('<svg></svg>')
27-
var context = {
28-
loader,
29-
query: { enabled: false },
30-
async () {
31-
assert.fail('should not call async')
32-
}
33-
}
34-
assert.equal(context.loader(img), img)
20+
it('can apply optimizations for gif', function () {
21+
return run('./fixture.gif', {
22+
plugins: [ gifsicle({}) ]
23+
}).then(function (image) {
24+
assert(!image.equals(fixtureGif), 'gif should be changed')
25+
assert(image.length < fixtureGif.length, 'optimized gif should be smaller')
3526
})
27+
})
28+
29+
it('can apply optimizations for svg', function () {
30+
return run('./fixture.svg', {
31+
plugins: [ svgo({}) ]
32+
}).then(function (image) {
33+
assert(!image.equals(fixtureSvg), 'svg should be changed')
34+
assert(image.length < fixtureSvg.length, 'optimized svg should be smaller')
35+
assert.equal(image.toString('utf8'), '<svg/>')
36+
})
37+
})
3638

37-
it('does not optimize when plugin disabled', (done) => {
38-
var img = Buffer.from('<svg></svg>')
39-
var context = {
40-
loader,
41-
query: { svgo: false },
42-
async () {
43-
return (error, buffer) => {
44-
if (error) return done(error)
45-
assert.equal(buffer.toString(), '<svg></svg>')
46-
done()
47-
}
48-
}
39+
it('can use a function for plugins', function () {
40+
var context
41+
return run('./fixture.svg', {
42+
plugins: function (ctx) {
43+
context = ctx
44+
return [ svgo({}) ]
4945
}
50-
context.loader(img)
46+
}).then(function (image) {
47+
assert.equal(path.basename(context.resourcePath), 'fixture.svg')
48+
assert(image.length < fixtureSvg.length, 'optimized svg should be smaller')
5149
})
5250
})
5351
})

‎__tests__/run-webpack.js

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
'use strict'
2+
var path = require('path')
3+
var webpack = require('webpack')
4+
var MemoryFS = require('memory-fs')
5+
6+
module.exports = function (entry, options) {
7+
var compiler = webpack({
8+
context: __dirname,
9+
entry: entry,
10+
output: {
11+
path: path.resolve(__dirname),
12+
filename: 'bundle.js'
13+
},
14+
mode: 'none',
15+
module: {
16+
rules: [{
17+
test: /./,
18+
use: [
19+
{
20+
loader: 'file-loader',
21+
options: {
22+
name: 'image'
23+
}
24+
},
25+
{
26+
loader: path.resolve(__dirname, '../index.js'),
27+
options: options
28+
}
29+
]
30+
}]
31+
}
32+
})
33+
compiler.outputFileSystem = new MemoryFS()
34+
return new Promise(function (resolve, reject) {
35+
compiler.run(function (error, stats) {
36+
return error ? reject(error) : resolve(stats.compilation.assets.image.source())
37+
})
38+
})
39+
}

‎index.js

+6-33
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,19 @@
11
'use strict'
2-
32
var imagemin = require('imagemin')
4-
var imageminGifsicle = require('imagemin-gifsicle')
5-
var imageminMozjpeg = require('imagemin-mozjpeg')
6-
var imageminOptipng = require('imagemin-optipng')
7-
var imageminPngquant = require('imagemin-pngquant')
8-
var imageminSvgo = require('imagemin-svgo')
93
var loaderUtils = require('loader-utils')
104

11-
var defaults = {
12-
enabled: true,
13-
gifsicle: {},
14-
mozjpeg: {},
15-
optipng: {},
16-
svgo: {}
17-
}
18-
19-
module.exports = function (content) {
20-
this.cacheable && this.cacheable()
21-
22-
var options = Object.assign(
23-
Object.create(defaults),
24-
loaderUtils.getOptions(this)
25-
)
26-
if (!options.enabled) {
27-
return content
5+
module.exports = function (content, map, meta) {
6+
var options = Object.assign({}, loaderUtils.getOptions(this))
7+
if (typeof options.plugins === 'function') {
8+
options.plugins = options.plugins(this)
289
}
29-
30-
var use = [
31-
options.gifsicle && imageminGifsicle(options.gifsicle),
32-
options.mozjpeg && imageminMozjpeg(options.mozjpeg),
33-
options.optipng && imageminOptipng(options.optipng),
34-
options.svgo && imageminSvgo(options.svgo),
35-
options.pngquant && imageminPngquant(options.pngquant)
36-
].filter(Boolean)
37-
if (use.length === 0) {
10+
if (!Array.isArray(options.plugins) || options.plugins.length === 0) {
3811
return content
3912
}
4013

4114
var callback = this.async()
4215
imagemin
43-
.buffer(content, { use: use })
16+
.buffer(content, options)
4417
.then(function (buffer) { callback(null, buffer) })
4518
.catch(function (error) { callback(error) })
4619
}

‎package-lock.json

+5,921-369
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎package.json

+13-11
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "img-loader",
3-
"version": "2.0.1",
4-
"description": "Image minimizing loader for webpack",
3+
"version": "3.0.0",
4+
"description": "Image minimizing loader for webpack 4",
55
"keywords": [
66
"image",
77
"imagemin",
@@ -17,26 +17,28 @@
1717
},
1818
"author": {
1919
"name": "Andy VanWagoner",
20-
"email": "thetalecrafter@gmail.com"
20+
"email": "andy@thetalecrafter.com"
2121
},
2222
"license": "MIT",
2323
"bugs": {
2424
"url": "https://github.com/thetalecrafter/img-loader/issues"
2525
},
2626
"homepage": "https://github.com/thetalecrafter/img-loader",
2727
"dependencies": {
28-
"imagemin": "^5.3.1",
29-
"imagemin-gifsicle": "^5.2.0",
30-
"imagemin-mozjpeg": "^7.0.0",
31-
"imagemin-optipng": "^5.2.0",
32-
"imagemin-pngquant": "^5.0.1",
33-
"imagemin-svgo": "^6.0.0",
3428
"loader-utils": "^1.1.0"
3529
},
30+
"peerDependencies": {
31+
"imagemin": "^5.0.0"
32+
},
3633
"devDependencies": {
34+
"file-loader": "^1.1.11",
35+
"imagemin": "^5.3.1",
36+
"imagemin-gifsicle": "^5.2.0",
37+
"imagemin-svgo": "^6.0.0",
38+
"memory-fs": "^0.4.1",
3739
"mocha": "^5.0.0",
38-
"safe-buffer": "^5.1.1",
39-
"standard": "^11.0.0"
40+
"standard": "^11.0.0",
41+
"webpack": "^4.6.0"
4042
},
4143
"scripts": {
4244
"pretest": "standard",

0 commit comments

Comments
 (0)
Please sign in to comment.