├── .gitignore ├── README.md ├── index.js ├── package-lock.json └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /npm-debug.log 3 | /build 4 | .DS_Store 5 | /coverage 6 | /example 7 | /.idea 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 |

4 | 5 |

lqip-loader: low quality images placeholders for webpack

6 |

7 | demo 8 |

9 | 10 |
11 |
12 |

13 | 14 |

15 | 16 | ``` 17 | npm install --save-dev lqip-loader 18 | ``` 19 | 20 |
21 |

22 | 23 |

24 | 25 | Generating Base64 & dominant colours palette for a jpeg image imported in your JS bundle: 26 | 27 | PS: The large image file will be emitted & only 400byte of Base64 (if set to true in the loader options) will be bundled. 28 | 29 | webpack.config.js: 30 | ```js 31 | { 32 | /** 33 | * OPTION A: 34 | * default file-loader fallback 35 | **/ 36 | test: /\.jpe?g$/, 37 | loaders: [ 38 | { 39 | loader: 'lqip-loader', 40 | options: { 41 | path: '/media', // your image going to be in media folder in the output dir 42 | name: '[name].[ext]', // you can use [hash].[ext] too if you wish, 43 | base64: true, // default: true, gives the base64 encoded image 44 | palette: true // default: false, gives the dominant colours palette 45 | } 46 | } 47 | ] 48 | 49 | /** 50 | * OPTION B: 51 | * Chained with your own url-loader or file-loader 52 | **/ 53 | test: /\.(png|jpe?g)$/, 54 | loaders: [ 55 | { 56 | loader: 'lqip-loader', 57 | options: { 58 | base64: true, 59 | palette: false 60 | } 61 | }, 62 | { 63 | loader: 'url-loader', 64 | options: { 65 | limit: 8000 66 | } 67 | } 68 | ] 69 | } 70 | ``` 71 | 72 | your-app-module.js: 73 | ```js 74 | import banner from './images/banner.jpg'; 75 | 76 | console.log(banner.preSrc); 77 | // outputs: "data:image/jpeg;base64,/9j/2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJChQODwwQFxQYGBcUFhY.... 78 | 79 | // the object will have palette property, array will be sorted from most dominant colour to the least 80 | console.log(banner.palette) // [ '#628792', '#bed4d5', '#5d4340', '#ba454d', '#c5dce4', '#551f24' ] 81 | 82 | console.log(banner.src) // that's the original image URL to load later! 83 | 84 | ``` 85 | 86 |
87 |

88 | 89 |

90 | 91 | To save memory and improve GPU performance, browsers (including Chrome started from 61.0.3163.38) will now render a 92 | slightly more crisp or pixelated Base64 encoded images. 93 |

94 | 95 |
96 | Older Chrome to the left, Chrome v61 to the right. 97 |

98 | 99 | If you want the blur to be smooth really bad, here's a fix! 100 | ```css 101 | img { 102 | filter: blur(25px); 103 | } 104 | ``` 105 | 106 | More history about the issue can be [found here](https://bugs.chromium.org/p/chromium/issues/detail?id=771110#c3) and [here](https://groups.google.com/a/chromium.org/forum/#!topic/blink-dev/6L_3ZZeuA0M). 107 | 108 | alternatively, you can fill the container with a really cheap colour or gradient from the amazing palette we provide. 109 | 110 |
111 |

112 | 113 |

114 | 115 | - [Medium web app](https://medium.com/cucumbertown-magazine/the-beginners-guide-to-composition-in-food-photography-how-to-transform-your-food-photos-from-good-39613ab78bf2) 116 | - [Instagram native mobile app](https://www.instagram.com/) 117 | - [Polymer shop project](https://shop.polymer-project.org/) 118 | 119 |
120 |

121 | 122 |

123 | 124 | - Essential Image Optimization, An [eBook by Addy Osmany](https://images.guide/) 125 | 126 |
127 |

128 | 129 |

130 | 131 | Related projects to this would be [lqip module for Node](https://github.com/zouhir/lqip) as well as [lqip-cli](https://github.com/zouhir/lqip-cli). 132 | 133 | Thanks to [Colin van Eenige](https://twitter.com/cvaneenige) for his reviewing and early testing. 134 | 135 | MIT - [Zouhir Chahoud](https://zouhir.org/) 136 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | var loaderUtils = require("loader-utils"); 2 | // lqip: https://github.com/zouhir/lqip 3 | var lqip = require("lqip"); 4 | 5 | module.exports = function (contentBuffer) { 6 | this.cacheable && this.cacheable(); 7 | var callback = this.async(); 8 | 9 | var content = contentBuffer.toString("utf8"); 10 | // image file path 11 | var path = this.resourcePath; 12 | 13 | // user options 14 | var config = loaderUtils.getOptions(this) || {}; 15 | 16 | config.base64 = "base64" in config ? config.base64 : true; 17 | config.palette = "palette" in config ? config.palette : false; 18 | 19 | var contentIsUrlExport = /^(module.exports =|export default) "data:(.*)base64,(.*)/.test(content); 20 | var contentIsFileExport = /^(module.exports =|export default) (.*)/.test(content); 21 | var source = ""; 22 | 23 | if (contentIsUrlExport) { 24 | var urlMatch = content.match(/^(module.exports =|export default) (.*)/); 25 | if (!(urlMatch && urlMatch[2])) { 26 | throw new Error("[lqip-loader] Unable to process file (url)."); 27 | } 28 | source = urlMatch[2]; 29 | } else { 30 | if (!contentIsFileExport) { 31 | var fileLoader = require("file-loader"); 32 | content = fileLoader.call(this, contentBuffer); 33 | } 34 | var fileMatch = content.match(/^(module.exports =|export default) (.*);/); 35 | if (!(fileMatch && fileMatch[2])) { 36 | throw new Error("[lqip-loader] Unable to process file (export)."); 37 | } 38 | source = fileMatch[2]; 39 | } 40 | 41 | // promise array in case users want both 42 | // base64 & color palettes generated 43 | // that means we have 2 promises to resolve 44 | var outputPromises = []; 45 | 46 | if (config.base64 === true) { 47 | outputPromises.push(lqip.base64(path)); 48 | } else { 49 | // push null if the user did not wish to use Base64 to preserve the order 50 | outputPromises.push(null); 51 | } 52 | 53 | // color palette generation is set to false by default 54 | // since it is little bit slower than base64 generation 55 | // if users wants it, grab it! 56 | 57 | if (config.palette === true) { 58 | outputPromises.push(lqip.palette(path)); 59 | } else { 60 | // push null if the user did not wish to use palette to preserve the order 61 | outputPromises.push(null); 62 | } 63 | 64 | // final step, resolving all the promises we got so far 65 | Promise.all(outputPromises) 66 | .then(data => { 67 | if (data) { 68 | var result = 'module.exports = { "src": ' + source; 69 | // either null or base64 70 | if (data[0]) { 71 | result += ', "preSrc": ' + JSON.stringify(data[0]); 72 | } 73 | // either null or palette 74 | if (data[1]) { 75 | result += ', "palette": ' + JSON.stringify(data[1]); 76 | } 77 | result += " };"; 78 | // the output will be sent to webpack! 79 | callback(null, result); 80 | } else { 81 | callback(new Error("[lqip-loader] No data received from base64/palette promise"), null); 82 | } 83 | }) 84 | .catch(error => { 85 | console.error(error); 86 | callback(error, null); 87 | }); 88 | }; 89 | 90 | module.exports.raw = true; 91 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "lqip-loader", 3 | "version": "2.2.1", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "@types/bluebird": { 8 | "version": "3.5.22", 9 | "resolved": "https://registry.npmjs.org/@types/bluebird/-/bluebird-3.5.22.tgz", 10 | "integrity": "sha512-wQamz3CYZCz9QVxhPOF+Odu2jZifcXkGJDff7580sx/TCR6/9Zsgv+iGe2/o4Upcs0RDFLVJuEtYSEFeAqDTSA==" 11 | }, 12 | "@types/jimp": { 13 | "version": "0.2.28", 14 | "resolved": "https://registry.npmjs.org/@types/jimp/-/jimp-0.2.28.tgz", 15 | "integrity": "sha512-nLIVbImtcaEf90y2XQsMzfgWK5EZxfDg6EVWobrkFTFJiLqmx/yU5Jh+LYUN94ztzXX1GwQLFYHaEi8tfMeZzw==", 16 | "requires": { 17 | "jimp": "*" 18 | } 19 | }, 20 | "@types/lodash": { 21 | "version": "4.14.113", 22 | "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.113.tgz", 23 | "integrity": "sha512-CINMgfKUnif7fWBqPuGUsZrkER8jGU+ufyhD7FuotPqC1rRViHOJVgPuanN2Y8Vv1TqRnHDKlMnyEQLNq9eMjA==" 24 | }, 25 | "@types/node": { 26 | "version": "8.10.21", 27 | "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.21.tgz", 28 | "integrity": "sha512-87XkD9qDXm8fIax+5y7drx84cXsu34ZZqfB7Cial3Q/2lxSoJ/+DRaWckkCbxP41wFSIrrb939VhzaNxj4eY1w==" 29 | }, 30 | "ajv": { 31 | "version": "5.5.2", 32 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", 33 | "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", 34 | "requires": { 35 | "co": "^4.6.0", 36 | "fast-deep-equal": "^1.0.0", 37 | "fast-json-stable-stringify": "^2.0.0", 38 | "json-schema-traverse": "^0.3.0" 39 | } 40 | }, 41 | "asn1": { 42 | "version": "0.2.3", 43 | "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", 44 | "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=" 45 | }, 46 | "assert-plus": { 47 | "version": "1.0.0", 48 | "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", 49 | "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" 50 | }, 51 | "asynckit": { 52 | "version": "0.4.0", 53 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", 54 | "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" 55 | }, 56 | "aws-sign2": { 57 | "version": "0.7.0", 58 | "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", 59 | "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" 60 | }, 61 | "aws4": { 62 | "version": "1.7.0", 63 | "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.7.0.tgz", 64 | "integrity": "sha512-32NDda82rhwD9/JBCCkB+MRYDp0oSvlo2IL6rQWA10PQi7tDUM3eqMSltXmY+Oyl/7N3P3qNtAlv7X0d9bI28w==" 65 | }, 66 | "bcrypt-pbkdf": { 67 | "version": "1.0.2", 68 | "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", 69 | "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", 70 | "optional": true, 71 | "requires": { 72 | "tweetnacl": "^0.14.3" 73 | } 74 | }, 75 | "big.js": { 76 | "version": "3.2.0", 77 | "resolved": "https://registry.npmjs.org/big.js/-/big.js-3.2.0.tgz", 78 | "integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==" 79 | }, 80 | "bignumber.js": { 81 | "version": "2.4.0", 82 | "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-2.4.0.tgz", 83 | "integrity": "sha1-g4qZLan51zfg9LLbC+YrsJ3Qxeg=" 84 | }, 85 | "bluebird": { 86 | "version": "3.5.1", 87 | "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", 88 | "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==" 89 | }, 90 | "bmp-js": { 91 | "version": "0.0.3", 92 | "resolved": "https://registry.npmjs.org/bmp-js/-/bmp-js-0.0.3.tgz", 93 | "integrity": "sha1-ZBE+nHzxICs3btYHvzBibr5XsYo=" 94 | }, 95 | "buffer-equal": { 96 | "version": "0.0.1", 97 | "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-0.0.1.tgz", 98 | "integrity": "sha1-kbx0sR6kBbyRa8aqkI+q+ltKrEs=" 99 | }, 100 | "caseless": { 101 | "version": "0.12.0", 102 | "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", 103 | "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" 104 | }, 105 | "co": { 106 | "version": "4.6.0", 107 | "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", 108 | "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" 109 | }, 110 | "combined-stream": { 111 | "version": "1.0.6", 112 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz", 113 | "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=", 114 | "requires": { 115 | "delayed-stream": "~1.0.0" 116 | } 117 | }, 118 | "core-util-is": { 119 | "version": "1.0.2", 120 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", 121 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" 122 | }, 123 | "dashdash": { 124 | "version": "1.14.1", 125 | "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", 126 | "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", 127 | "requires": { 128 | "assert-plus": "^1.0.0" 129 | } 130 | }, 131 | "delayed-stream": { 132 | "version": "1.0.0", 133 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", 134 | "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" 135 | }, 136 | "dom-walk": { 137 | "version": "0.1.1", 138 | "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.1.tgz", 139 | "integrity": "sha1-ZyIm3HTI95mtNTB9+TaroRrNYBg=" 140 | }, 141 | "ecc-jsbn": { 142 | "version": "0.1.1", 143 | "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", 144 | "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=", 145 | "optional": true, 146 | "requires": { 147 | "jsbn": "~0.1.0" 148 | } 149 | }, 150 | "emojis-list": { 151 | "version": "2.1.0", 152 | "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", 153 | "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=" 154 | }, 155 | "es6-promise": { 156 | "version": "3.3.1", 157 | "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.3.1.tgz", 158 | "integrity": "sha1-oIzd6EzNvzTQJ6FFG8kdS80ophM=" 159 | }, 160 | "exif-parser": { 161 | "version": "0.1.12", 162 | "resolved": "https://registry.npmjs.org/exif-parser/-/exif-parser-0.1.12.tgz", 163 | "integrity": "sha1-WKnS1ywCwfbwKg70qRZicrd2CSI=" 164 | }, 165 | "extend": { 166 | "version": "3.0.2", 167 | "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", 168 | "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" 169 | }, 170 | "extsprintf": { 171 | "version": "1.3.0", 172 | "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", 173 | "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" 174 | }, 175 | "fast-deep-equal": { 176 | "version": "1.1.0", 177 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", 178 | "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=" 179 | }, 180 | "fast-json-stable-stringify": { 181 | "version": "2.0.0", 182 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", 183 | "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" 184 | }, 185 | "file-type": { 186 | "version": "3.9.0", 187 | "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz", 188 | "integrity": "sha1-JXoHg4TR24CHvESdEH1SpSZyuek=" 189 | }, 190 | "for-each": { 191 | "version": "0.3.3", 192 | "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", 193 | "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", 194 | "requires": { 195 | "is-callable": "^1.1.3" 196 | } 197 | }, 198 | "forever-agent": { 199 | "version": "0.6.1", 200 | "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", 201 | "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" 202 | }, 203 | "form-data": { 204 | "version": "2.3.2", 205 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz", 206 | "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=", 207 | "requires": { 208 | "asynckit": "^0.4.0", 209 | "combined-stream": "1.0.6", 210 | "mime-types": "^2.1.12" 211 | } 212 | }, 213 | "getpass": { 214 | "version": "0.1.7", 215 | "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", 216 | "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", 217 | "requires": { 218 | "assert-plus": "^1.0.0" 219 | } 220 | }, 221 | "global": { 222 | "version": "4.3.2", 223 | "resolved": "https://registry.npmjs.org/global/-/global-4.3.2.tgz", 224 | "integrity": "sha1-52mJJopsdMOJCLEwWxD8DjlOnQ8=", 225 | "requires": { 226 | "min-document": "^2.19.0", 227 | "process": "~0.5.1" 228 | } 229 | }, 230 | "har-schema": { 231 | "version": "2.0.0", 232 | "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", 233 | "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" 234 | }, 235 | "har-validator": { 236 | "version": "5.0.3", 237 | "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz", 238 | "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=", 239 | "requires": { 240 | "ajv": "^5.1.0", 241 | "har-schema": "^2.0.0" 242 | } 243 | }, 244 | "http-signature": { 245 | "version": "1.2.0", 246 | "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", 247 | "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", 248 | "requires": { 249 | "assert-plus": "^1.0.0", 250 | "jsprim": "^1.2.2", 251 | "sshpk": "^1.7.0" 252 | } 253 | }, 254 | "ip-regex": { 255 | "version": "1.0.3", 256 | "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-1.0.3.tgz", 257 | "integrity": "sha1-3FiQdvZZ9BnCIgOaMzFvHHOH7/0=" 258 | }, 259 | "is-callable": { 260 | "version": "1.1.4", 261 | "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", 262 | "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==" 263 | }, 264 | "is-function": { 265 | "version": "1.0.1", 266 | "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.1.tgz", 267 | "integrity": "sha1-Es+5i2W1fdPRk6MSH19uL0N2ArU=" 268 | }, 269 | "is-typedarray": { 270 | "version": "1.0.0", 271 | "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", 272 | "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" 273 | }, 274 | "isstream": { 275 | "version": "0.1.2", 276 | "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", 277 | "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" 278 | }, 279 | "jimp": { 280 | "version": "0.2.28", 281 | "resolved": "https://registry.npmjs.org/jimp/-/jimp-0.2.28.tgz", 282 | "integrity": "sha1-3VKak3GQ9ClXp5N9Gsw6d2KZbqI=", 283 | "requires": { 284 | "bignumber.js": "^2.1.0", 285 | "bmp-js": "0.0.3", 286 | "es6-promise": "^3.0.2", 287 | "exif-parser": "^0.1.9", 288 | "file-type": "^3.1.0", 289 | "jpeg-js": "^0.2.0", 290 | "load-bmfont": "^1.2.3", 291 | "mime": "^1.3.4", 292 | "mkdirp": "0.5.1", 293 | "pixelmatch": "^4.0.0", 294 | "pngjs": "^3.0.0", 295 | "read-chunk": "^1.0.1", 296 | "request": "^2.65.0", 297 | "stream-to-buffer": "^0.1.0", 298 | "tinycolor2": "^1.1.2", 299 | "url-regex": "^3.0.0" 300 | } 301 | }, 302 | "jpeg-js": { 303 | "version": "0.2.0", 304 | "resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.2.0.tgz", 305 | "integrity": "sha1-U+RI7J0mPmgyZkZ+lELSxaLvVII=" 306 | }, 307 | "jsbn": { 308 | "version": "0.1.1", 309 | "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", 310 | "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", 311 | "optional": true 312 | }, 313 | "json-schema": { 314 | "version": "0.2.3", 315 | "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", 316 | "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" 317 | }, 318 | "json-schema-traverse": { 319 | "version": "0.3.1", 320 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", 321 | "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=" 322 | }, 323 | "json-stringify-safe": { 324 | "version": "5.0.1", 325 | "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", 326 | "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" 327 | }, 328 | "json5": { 329 | "version": "0.5.1", 330 | "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", 331 | "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=" 332 | }, 333 | "jsprim": { 334 | "version": "1.4.1", 335 | "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", 336 | "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", 337 | "requires": { 338 | "assert-plus": "1.0.0", 339 | "extsprintf": "1.3.0", 340 | "json-schema": "0.2.3", 341 | "verror": "1.10.0" 342 | } 343 | }, 344 | "load-bmfont": { 345 | "version": "1.3.0", 346 | "resolved": "https://registry.npmjs.org/load-bmfont/-/load-bmfont-1.3.0.tgz", 347 | "integrity": "sha1-u358cQ3mvK/LE8s7jIHgwBMey8k=", 348 | "requires": { 349 | "buffer-equal": "0.0.1", 350 | "mime": "^1.3.4", 351 | "parse-bmfont-ascii": "^1.0.3", 352 | "parse-bmfont-binary": "^1.0.5", 353 | "parse-bmfont-xml": "^1.1.0", 354 | "xhr": "^2.0.1", 355 | "xtend": "^4.0.0" 356 | } 357 | }, 358 | "loader-utils": { 359 | "version": "1.1.0", 360 | "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.1.0.tgz", 361 | "integrity": "sha1-yYrvSIvM7aL/teLeZG1qdUQp9c0=", 362 | "requires": { 363 | "big.js": "^3.1.3", 364 | "emojis-list": "^2.0.0", 365 | "json5": "^0.5.0" 366 | } 367 | }, 368 | "lodash": { 369 | "version": "4.17.10", 370 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", 371 | "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==" 372 | }, 373 | "lodash.sortby": { 374 | "version": "4.7.0", 375 | "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", 376 | "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=" 377 | }, 378 | "lqip": { 379 | "version": "2.1.0", 380 | "resolved": "https://registry.npmjs.org/lqip/-/lqip-2.1.0.tgz", 381 | "integrity": "sha512-cnQw+89wUk+GSyeaaUuqeJl0XwpCQDcgXZPDBNnExdnCeVdFIrIVI29tae9GmC09LYgPY0IJZjixG6sdn7IYsQ==", 382 | "requires": { 383 | "jimp": "^0.2.28", 384 | "lodash.sortby": "^4.7.0", 385 | "node-vibrant": "^3.0.0-alpha.2" 386 | } 387 | }, 388 | "mime": { 389 | "version": "1.6.0", 390 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", 391 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" 392 | }, 393 | "mime-db": { 394 | "version": "1.35.0", 395 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.35.0.tgz", 396 | "integrity": "sha512-JWT/IcCTsB0Io3AhWUMjRqucrHSPsSf2xKLaRldJVULioggvkJvggZ3VXNNSRkCddE6D+BUI4HEIZIA2OjwIvg==" 397 | }, 398 | "mime-types": { 399 | "version": "2.1.19", 400 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.19.tgz", 401 | "integrity": "sha512-P1tKYHVSZ6uFo26mtnve4HQFE3koh1UWVkp8YUC+ESBHe945xWSoXuHHiGarDqcEZ+whpCDnlNw5LON0kLo+sw==", 402 | "requires": { 403 | "mime-db": "~1.35.0" 404 | } 405 | }, 406 | "min-document": { 407 | "version": "2.19.0", 408 | "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", 409 | "integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=", 410 | "requires": { 411 | "dom-walk": "^0.1.0" 412 | } 413 | }, 414 | "minimist": { 415 | "version": "0.0.8", 416 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", 417 | "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" 418 | }, 419 | "mkdirp": { 420 | "version": "0.5.1", 421 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", 422 | "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", 423 | "requires": { 424 | "minimist": "0.0.8" 425 | } 426 | }, 427 | "node-vibrant": { 428 | "version": "3.0.0", 429 | "resolved": "https://registry.npmjs.org/node-vibrant/-/node-vibrant-3.0.0.tgz", 430 | "integrity": "sha512-3qFLV1ITyC4A7C3BCJaguhw4HjPHAqNLapqJYktMthWYIBmtfhbz9R52bciYYhNabfKMS8gB3uk7grc+la4rww==", 431 | "requires": { 432 | "@types/bluebird": "^3.0.37", 433 | "@types/jimp": "^0.2.0", 434 | "@types/lodash": "^4.14.53", 435 | "@types/node": "^8.0.53", 436 | "bluebird": "^3.4.7", 437 | "jimp": "^0.2.27", 438 | "lodash": "^4.17.4", 439 | "url": "^0.11.0" 440 | } 441 | }, 442 | "oauth-sign": { 443 | "version": "0.8.2", 444 | "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", 445 | "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=" 446 | }, 447 | "parse-bmfont-ascii": { 448 | "version": "1.0.6", 449 | "resolved": "https://registry.npmjs.org/parse-bmfont-ascii/-/parse-bmfont-ascii-1.0.6.tgz", 450 | "integrity": "sha1-Eaw8P/WPfCAgqyJ2kHkQjU36AoU=" 451 | }, 452 | "parse-bmfont-binary": { 453 | "version": "1.0.6", 454 | "resolved": "https://registry.npmjs.org/parse-bmfont-binary/-/parse-bmfont-binary-1.0.6.tgz", 455 | "integrity": "sha1-0Di0dtPp3Z2x4RoLDlOiJ5K2kAY=" 456 | }, 457 | "parse-bmfont-xml": { 458 | "version": "1.1.3", 459 | "resolved": "https://registry.npmjs.org/parse-bmfont-xml/-/parse-bmfont-xml-1.1.3.tgz", 460 | "integrity": "sha1-1rZqNxr9OcUAfZ8O6yYqTyzOe3w=", 461 | "requires": { 462 | "xml-parse-from-string": "^1.0.0", 463 | "xml2js": "^0.4.5" 464 | } 465 | }, 466 | "parse-headers": { 467 | "version": "2.0.1", 468 | "resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.1.tgz", 469 | "integrity": "sha1-aug6eqJanZtwCswoaYzR8e1+lTY=", 470 | "requires": { 471 | "for-each": "^0.3.2", 472 | "trim": "0.0.1" 473 | } 474 | }, 475 | "performance-now": { 476 | "version": "2.1.0", 477 | "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", 478 | "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" 479 | }, 480 | "pixelmatch": { 481 | "version": "4.0.2", 482 | "resolved": "https://registry.npmjs.org/pixelmatch/-/pixelmatch-4.0.2.tgz", 483 | "integrity": "sha1-j0fc7FARtHe2fbA8JDvB8wheiFQ=", 484 | "requires": { 485 | "pngjs": "^3.0.0" 486 | } 487 | }, 488 | "pngjs": { 489 | "version": "3.3.3", 490 | "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-3.3.3.tgz", 491 | "integrity": "sha512-1n3Z4p3IOxArEs1VRXnZ/RXdfEniAUS9jb68g58FIXMNkPJeZd+Qh4Uq7/e0LVxAQGos1eIUrqrt4FpjdnEd+Q==" 492 | }, 493 | "process": { 494 | "version": "0.5.2", 495 | "resolved": "https://registry.npmjs.org/process/-/process-0.5.2.tgz", 496 | "integrity": "sha1-FjjYqONML0QKkduVq5rrZ3/Bhc8=" 497 | }, 498 | "punycode": { 499 | "version": "1.4.1", 500 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", 501 | "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" 502 | }, 503 | "qs": { 504 | "version": "6.5.2", 505 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", 506 | "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" 507 | }, 508 | "querystring": { 509 | "version": "0.2.0", 510 | "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", 511 | "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=" 512 | }, 513 | "read-chunk": { 514 | "version": "1.0.1", 515 | "resolved": "https://registry.npmjs.org/read-chunk/-/read-chunk-1.0.1.tgz", 516 | "integrity": "sha1-X2jKswfmY/GZk1J9m1icrORmEZQ=" 517 | }, 518 | "request": { 519 | "version": "2.87.0", 520 | "resolved": "https://registry.npmjs.org/request/-/request-2.87.0.tgz", 521 | "integrity": "sha512-fcogkm7Az5bsS6Sl0sibkbhcKsnyon/jV1kF3ajGmF0c8HrttdKTPRT9hieOaQHA5HEq6r8OyWOo/o781C1tNw==", 522 | "requires": { 523 | "aws-sign2": "~0.7.0", 524 | "aws4": "^1.6.0", 525 | "caseless": "~0.12.0", 526 | "combined-stream": "~1.0.5", 527 | "extend": "~3.0.1", 528 | "forever-agent": "~0.6.1", 529 | "form-data": "~2.3.1", 530 | "har-validator": "~5.0.3", 531 | "http-signature": "~1.2.0", 532 | "is-typedarray": "~1.0.0", 533 | "isstream": "~0.1.2", 534 | "json-stringify-safe": "~5.0.1", 535 | "mime-types": "~2.1.17", 536 | "oauth-sign": "~0.8.2", 537 | "performance-now": "^2.1.0", 538 | "qs": "~6.5.1", 539 | "safe-buffer": "^5.1.1", 540 | "tough-cookie": "~2.3.3", 541 | "tunnel-agent": "^0.6.0", 542 | "uuid": "^3.1.0" 543 | } 544 | }, 545 | "safe-buffer": { 546 | "version": "5.1.2", 547 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 548 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" 549 | }, 550 | "safer-buffer": { 551 | "version": "2.1.2", 552 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 553 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 554 | }, 555 | "sax": { 556 | "version": "1.2.4", 557 | "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", 558 | "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" 559 | }, 560 | "sshpk": { 561 | "version": "1.14.2", 562 | "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.14.2.tgz", 563 | "integrity": "sha1-xvxhZIo9nE52T9P8306hBeSSupg=", 564 | "requires": { 565 | "asn1": "~0.2.3", 566 | "assert-plus": "^1.0.0", 567 | "bcrypt-pbkdf": "^1.0.0", 568 | "dashdash": "^1.12.0", 569 | "ecc-jsbn": "~0.1.1", 570 | "getpass": "^0.1.1", 571 | "jsbn": "~0.1.0", 572 | "safer-buffer": "^2.0.2", 573 | "tweetnacl": "~0.14.0" 574 | } 575 | }, 576 | "stream-to": { 577 | "version": "0.2.2", 578 | "resolved": "https://registry.npmjs.org/stream-to/-/stream-to-0.2.2.tgz", 579 | "integrity": "sha1-hDBgmNhf25kLn6MAsbPM9V6O8B0=" 580 | }, 581 | "stream-to-buffer": { 582 | "version": "0.1.0", 583 | "resolved": "https://registry.npmjs.org/stream-to-buffer/-/stream-to-buffer-0.1.0.tgz", 584 | "integrity": "sha1-JnmdkDqyAlyb1VCsRxcbAPjdgKk=", 585 | "requires": { 586 | "stream-to": "~0.2.0" 587 | } 588 | }, 589 | "tinycolor2": { 590 | "version": "1.4.1", 591 | "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.4.1.tgz", 592 | "integrity": "sha1-9PrTM0R7wLB9TcjpIJ2POaisd+g=" 593 | }, 594 | "tough-cookie": { 595 | "version": "2.3.4", 596 | "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz", 597 | "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==", 598 | "requires": { 599 | "punycode": "^1.4.1" 600 | } 601 | }, 602 | "trim": { 603 | "version": "0.0.1", 604 | "resolved": "https://registry.npmjs.org/trim/-/trim-0.0.1.tgz", 605 | "integrity": "sha1-WFhUf2spB1fulczMZm+1AITEYN0=" 606 | }, 607 | "tunnel-agent": { 608 | "version": "0.6.0", 609 | "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", 610 | "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", 611 | "requires": { 612 | "safe-buffer": "^5.0.1" 613 | } 614 | }, 615 | "tweetnacl": { 616 | "version": "0.14.5", 617 | "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", 618 | "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", 619 | "optional": true 620 | }, 621 | "url": { 622 | "version": "0.11.0", 623 | "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", 624 | "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", 625 | "requires": { 626 | "punycode": "1.3.2", 627 | "querystring": "0.2.0" 628 | }, 629 | "dependencies": { 630 | "punycode": { 631 | "version": "1.3.2", 632 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", 633 | "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=" 634 | } 635 | } 636 | }, 637 | "url-regex": { 638 | "version": "3.2.0", 639 | "resolved": "https://registry.npmjs.org/url-regex/-/url-regex-3.2.0.tgz", 640 | "integrity": "sha1-260eDJ4p4QXdCx8J9oYvf9tIJyQ=", 641 | "requires": { 642 | "ip-regex": "^1.0.1" 643 | } 644 | }, 645 | "uuid": { 646 | "version": "3.3.2", 647 | "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", 648 | "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" 649 | }, 650 | "verror": { 651 | "version": "1.10.0", 652 | "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", 653 | "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", 654 | "requires": { 655 | "assert-plus": "^1.0.0", 656 | "core-util-is": "1.0.2", 657 | "extsprintf": "^1.2.0" 658 | } 659 | }, 660 | "xhr": { 661 | "version": "2.5.0", 662 | "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.5.0.tgz", 663 | "integrity": "sha512-4nlO/14t3BNUZRXIXfXe+3N6w3s1KoxcJUUURctd64BLRe67E4gRwp4PjywtDY72fXpZ1y6Ch0VZQRY/gMPzzQ==", 664 | "requires": { 665 | "global": "~4.3.0", 666 | "is-function": "^1.0.1", 667 | "parse-headers": "^2.0.0", 668 | "xtend": "^4.0.0" 669 | } 670 | }, 671 | "xml-parse-from-string": { 672 | "version": "1.0.1", 673 | "resolved": "https://registry.npmjs.org/xml-parse-from-string/-/xml-parse-from-string-1.0.1.tgz", 674 | "integrity": "sha1-qQKekp09vN7RafPG4oI42VpdWig=" 675 | }, 676 | "xml2js": { 677 | "version": "0.4.19", 678 | "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz", 679 | "integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==", 680 | "requires": { 681 | "sax": ">=0.6.0", 682 | "xmlbuilder": "~9.0.1" 683 | } 684 | }, 685 | "xmlbuilder": { 686 | "version": "9.0.7", 687 | "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", 688 | "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=" 689 | }, 690 | "xtend": { 691 | "version": "4.0.1", 692 | "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", 693 | "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" 694 | } 695 | } 696 | } 697 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "lqip-loader", 3 | "version": "2.2.1", 4 | "description": "Low Quality Image Placeholders (LQIP) loader for webpack", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/zouhir/lqip-loader.git" 12 | }, 13 | "keywords": [ 14 | "Webpack", 15 | "blurry", 16 | "images", 17 | "base64", 18 | "image", 19 | "loader", 20 | "medium", 21 | "lazy", 22 | "load" 23 | ], 24 | "author": "Zouhir Chahoud", 25 | "license": "MIT", 26 | "bugs": { 27 | "url": "https://github.com/zouhir/lqip-loader/issues" 28 | }, 29 | "homepage": "https://github.com/zouhir/lqip-loader#readme", 30 | "dependencies": { 31 | "loader-utils": "^1.1.0", 32 | "lqip": "^2.1.0" 33 | }, 34 | "peerDependencies": { 35 | "file-loader": "*" 36 | } 37 | } 38 | --------------------------------------------------------------------------------