From 97c3a977d3b44fee9c2e081ebf52e940eba4a94a Mon Sep 17 00:00:00 2001 From: Daniel Zuloaga Date: Sat, 26 Dec 2020 11:26:46 -0500 Subject: [PATCH] validate error --- .yalc/responsive-loader/CHANGELOG.md | 134 ++++++++++++ .yalc/responsive-loader/LICENSE | 28 +++ .yalc/responsive-loader/README.md | 291 +++++++++++++++++++++++++++ .yalc/responsive-loader/jimp.js | 1 + .yalc/responsive-loader/package.json | 58 ++++++ .yalc/responsive-loader/sharp.js | 1 + .yalc/responsive-loader/yalc.sig | 1 + package.json | 1 + src/declarations.d.ts | 4 + src/index.ts | 5 +- src/schema.json | 1 + tsconfig.json | 2 +- yalc.lock | 9 + 13 files changed, 532 insertions(+), 4 deletions(-) create mode 100644 .yalc/responsive-loader/CHANGELOG.md create mode 100644 .yalc/responsive-loader/LICENSE create mode 100644 .yalc/responsive-loader/README.md create mode 100644 .yalc/responsive-loader/jimp.js create mode 100644 .yalc/responsive-loader/package.json create mode 100644 .yalc/responsive-loader/sharp.js create mode 100644 .yalc/responsive-loader/yalc.sig create mode 100644 src/declarations.d.ts create mode 100644 yalc.lock diff --git a/.yalc/responsive-loader/CHANGELOG.md b/.yalc/responsive-loader/CHANGELOG.md new file mode 100644 index 0000000..0dfb362 --- /dev/null +++ b/.yalc/responsive-loader/CHANGELOG.md @@ -0,0 +1,134 @@ +# Change Log + +## v1.1.0 + + - Added `min` and `max` options to automatically generate a number of images, and `steps` option to say how many images ([#31](https://github.com/herrstucki/responsive-loader/pull/31)). + +## v1.0.0 + +### New + +- 🚀 Added support for [sharp](https://github.com/lovell/sharp) ([#19](https://github.com/herrstucki/responsive-loader/pull/29)) + +### Breaking + +#### Webpack 2 support + +Removed support for webpack 1! Please upgrade to webpack >= 2. + +The syntax to import images has changed. The query part now comes _after_ the resource (the image) instead of the loader. + +```diff +- require('responsive-loader?size=100!some-image.jpg') ++ require('responsive-loader!some-image.jpg?size=100') +``` + +That means if `responsive-loader` is configured in your webpack-config, it's possible to specify image-specific options without having to add the loader part to the import path. For example: + +```js +// webpack.config.js +module.exports = { + // ... + module: { + rules: [ + { + test: /\.jpg$/, + loader: 'responsive-loader', + options: { + size: 1000 + //... + } + } + ] + }, +} + +// some-file.js +const image1000 = require('some-image.jpg') // will have size 1000 from the config +const image500 = require('some-image.jpg?size=500') +``` + +#### Other breaking changes + +- The `ext` option was removed, in favor of `format=jpg|png`. `[ext]` is now part of the `name` option like in other loaders (fixes [#13](https://github.com/herrstucki/responsive-loader/issues/13)) +- Changed default JPEG `quality` to `85` +- The `pass` option is now called `disable` + +## v0.7.0 + +- Add `placeholder` option ([#16](https://github.com/herrstucki/responsive-loader/pull/16)) +- Add `width` and `height` attributes to output ([#19](https://github.com/herrstucki/responsive-loader/pull/19)) + +## v0.6.1 + +- Declare default `name`, `context`, `quality`, and `background` through webpack options when they're not specified in the loader query ([#12](https://github.com/herrstucki/responsive-loader/pull/12)). + +## v0.6.0 + +- Add linting ([#7](https://github.com/herrstucki/responsive-loader/pull/7)) +- Breaking (maybe): Require node >= v4 + +## v0.5.3 + +- Fix wrong callback being called on file load error ([#6](https://github.com/herrstucki/responsive-loader/pull/6)) + +## v0.5.2 + +- Added tests! +- Update `queue-async` to `d3-queue` + +## v0.5.1 + +- Optimization: skip resizing images of the same size ([#5](https://github.com/herrstucki/responsive-loader/pull/5)) + +## v0.5.0 + +Using the `size` option for getting only one resized image no longer just returns a string but the same object structure as when using `sizes`. The difference is, that when `toString()` is called on that object, it will return the path of the first resized image. + +Also, for pure convenience, the returned object also contains a `src` property, so it can be spread onto a React component (e.g. ``). + +### Before + +This worked: + +```js +import resized from 'responsive?sizes[]=100,sizes[]=200'; + + +``` + +```css +.foo { background-image: url('responsive?size=100'); } +``` + +But this didn't :sob:: + +```js +import resized from 'responsive?size=100'; + +// Whoops, error because `resized` ist just a string + +``` + +```css +/* Whoops, `url('[object Object]')` */ +.foo { background-image: url('responsive?sizes[]=100'); } +``` + +### After + +All these work :v: + +```js +import resized from 'responsive?sizes[]=100,sizes[]=200'; + + + + +``` + +```css +.foo { background-image: url('responsive?sizes[]=100,sizes[]=200'); } +.foo { background-image: url('responsive?sizes[]=100'); } +.foo { background-image: url('responsive?size=100'); } +``` diff --git a/.yalc/responsive-loader/LICENSE b/.yalc/responsive-loader/LICENSE new file mode 100644 index 0000000..a1923df --- /dev/null +++ b/.yalc/responsive-loader/LICENSE @@ -0,0 +1,28 @@ +Copyright (c) 2016, Jeremy Stucki +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of responsive-loader nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + diff --git a/.yalc/responsive-loader/README.md b/.yalc/responsive-loader/README.md new file mode 100644 index 0000000..4513794 --- /dev/null +++ b/.yalc/responsive-loader/README.md @@ -0,0 +1,291 @@ +# responsive-loader + +[![build][travis]][travis-url] +[![npm][npm]][npm-url] +[![node][node]][node-url] + +A webpack loader for responsive images. Creates multiple images from one source image, and returns a `srcset`. For more information on how to use `srcset`, read [Responsive Images](https://developer.mozilla.org/en-US/docs/Learn/HTML/Multimedia_and_embedding/Responsive_images). Browser support is [pretty good](http://caniuse.com/#search=srcset). + +## Install + +### With jimp + +``` +npm install responsive-loader jimp --save-dev +``` + +Per default, responsive-loader uses [jimp](https://github.com/oliver-moran/jimp) to transform images. which needs to be installed alongside responsive-loader. Because jimp is written entirely in JavaScript and doesn't have any native dependencies it will work anywhere. The main drawback is that it's pretty slow. + +### With sharp + +``` +npm install responsive-loader sharp --save-dev +``` + +For [super-charged performance](http://sharp.dimens.io/en/stable/performance/), responsive-loader also works with [sharp](https://github.com/lovell/sharp). It's recommended to use sharp if you have lots of images to transform, and/or need to generate webp/avif images. + +If you want to use sharp, you need to configure responsive-loader to use its adapter: + +```diff +module.exports = { + // ... + module: { + rules: [ + { + test: /\.(jpe?g|png|webp)$/i, + use: [ + loader: 'responsive-loader', + options: { ++ adapter: require('responsive-loader/sharp') + } + ] + } + ] + }, +} +``` + +## Usage + +Add a rule for loading responsive images to your webpack config: + +```js +module.exports = { + // ... + module: { + rules: [ + { + test: /\.(jpe?g|png|webp)$/i, + use: { + loader: "responsive-loader", + options: { + // If you want to enable sharp support: + adapter: require("responsive-loader/sharp"), + }, + }, + }, + ], + }, +} +``` + +Then import images in your JavaScript files: + +```js +import responsiveImage from 'img/myImage.jpg?sizes[]=300,sizes[]=600,sizes[]=1024,sizes[]=2048'; +import responsiveImageWebp from 'img/myImage.jpg?sizes[]=300,sizes[]=600,sizes[]=1024,sizes[]=2048&format=webp'; + +// Outputs +// responsiveImage.srcSet => '2fefae46cb857bc750fa5e5eed4a0cde-300.jpg 300w,2fefae46cb857bc750fa5e5eed4a0cde-600.jpg 600w,2fefae46cb857bc750fa5e5eed4a0cde-600.jpg 600w ...' +// responsiveImage.images => [{height: 150, path: '2fefae46cb857bc750fa5e5eed4a0cde-300.jpg', width: 300}, {height: 300, path: '2fefae46cb857bc750fa5e5eed4a0cde-600.jpg', width: 600} ...] +// responsiveImage.src => '2fefae46cb857bc750fa5e5eed4a0cde-300.jpg' +// responsiveImage.toString() => '2fefae46cb857bc750fa5e5eed4a0cde-300.jpg' +... + + + + +... +``` + +Notes: + +- `width` and `height` are intrinsic and are used to avoid layout shift, other techniques involve the use of aspect ratio and padding. +- `sizes`, without sizes, the browser assumes the image is always 100vw for any viewport. + - A helpful tool to determine proper sizes https://ausi.github.io/respimagelint/ +- `loading` do not add loading lazy if the image is part of the initial rendering of the page or close to it. +- `srcset` Modern browsers will choose the closest best image depending on the pixel density of your screen. + - in the example above is your pixel density is `>1x` for a screen `>1024px` it will display the 2048 image. + +Or use it in CSS (only the first resized image will be used, if you use multiple `sizes`): + +```css +.myImage { + background: url("myImage.jpg?size=1140"); +} + +@media (max-width: 480px) { + .myImage { + background: url("myImage.jpg?size=480"); + } +} +``` + +```js +// Outputs placeholder image as a data URI, and three images with 100, 200, and 300px widths +const responsiveImage = require("myImage.jpg?placeholder=true&sizes[]=100,sizes[]=200,sizes[]=300") + +// responsiveImage.placeholder => 'data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAIBAQE…' +ReactDOM.render( +
+ +
, + el +) +``` + +You can also use the following notation: + +``` + +``` + +More here https://github.com/webpack/loader-utils#parsequery + +### Options + +| Option | Type | Default | Description | +| --------------------------- | -------------------- | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `name` | `string` | `[hash]-[width].[ext]` | Filename template for output files. | +| `outputPath` | `string \| Function` | `undefined` | Configure a custom output path for your file | +| `publicPath` | `string \| Function` | `undefined` | Configure a custom public path for your file. | +| `context` | `string` | `this.options.context` | Custom file context, defaults to webpack.config.js [context](https://webpack.js.org/configuration/entry-context/#context) | +| `sizes` | `array` | _original size_ | 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 the loader options in your `webpack.config.js`. | +| `size` | `integer` | _original size_ | 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) | +| `min` | `integer` | | As an alternative to manually specifying `sizes`, you can specify `min`, `max` and `steps`, and the sizes will be generated for you. | +| `max` | `integer` | | See `min` above | +| `steps` | `integer` | `4` | Configure the number of images generated between `min` and `max` (inclusive) | +| `quality` | `integer` | `85` | JPEG and WEBP compression quality | +| `format` | `string` | _original format_ | Either `png` or `jpg`; use to convert to another format. `webp` and `avif` is also supported, but only by the sharp adapter | +| `placeholder` | `boolean` | `false` | A true or false value to specify wether to output a placeholder image as a data URI | +| `placeholderSize` | `integer` | `40` | A number value specifying the width of the placeholder image, if enabled with the option above | +| `adapter` | `Adapter` | JIMP | Specify which adapter to use. Can only be specified in the loader options. | +| `disable` | `boolean` | `false` | Disable processing of images by this loader (useful in development). `srcSet` and other attributes will still be generated but only for the original size. Note that the `width` and `height` attributes will both be set to `100` but the image will retain its original dimensions. | +| **[`esModule`](#esmodule)** | `boolean` | `false` | Use ES modules syntax. | +| `emitFile` | `boolean` | `true` | If `true`, emits a file (writes a file to the filesystem). If `false`, the loader will still return a object with the public URI but will not emit the file. It is often useful to disable this option for server-side packages. | + +#### Adapter-specific options + +##### jimp + +- `background: number` — Background fill when converting transparent to opaque images. Make sure this is a valid hex number, e.g. `0xFFFFFFFF`) + +##### sharp + +- `background: string` — Background fill when converting transparent to opaque images. E.g. `#FFFFFF` or `%23FFFFFF` for webpack > 5 + +- `format: webp` — Conversion to the `image/webp` format. Recognizes the `quality` option. +- `format: avif` — Conversion to the `image/avif` format. Recognizes the `quality` option. + +- `progressive: boolean` - Use progressive (interlace) scan for `image/jpeg` format. +- `rotate: number` - Rotates image [more here](https://sharp.pixelplumbing.com/api-operation#rotate) + +### Examples + +Set a default `sizes` array, so you don't have to declare them with each `require`. + +```js +module.exports = { + entry: {...}, + output: {...}, + module: { + rules: [ + { + test: /\.(jpe?g|png|webp)$/i, + use: [ + { + loader: "responsive-loader", + options: { + adapter: require('responsive-loader/sharp'), + sizes: [320, 640, 960, 1200, 1800, 2400], + placeholder: true, + placeholderSize: 20 + }, + }, + ], + } + ] + }, +} +``` + +### `esModule` + +Type: `Boolean` +Default: `false` + +By default, `responsive-loader` generates JS modules that use the CommonJS syntax. +There are some cases in which using ES modules is beneficial, like in the case of [module concatenation](https://webpack.js.org/plugins/module-concatenation-plugin/) and [tree shaking](https://webpack.js.org/guides/tree-shaking/). + +You can enable a ES module syntax using: + +**webpack.config.js** + +```js +module.exports = { + module: { + rules: [ + { + test: /\.(jpe?g|png)$/i, + use: [ + { + loader: "responsive-loader", + options: { + esModule: true, + }, + }, + ], + }, + ], + }, +} +``` + +### Writing Your Own Adapter + +Maybe you want to use another image processing library or you want to change an existing one's behavior. You can write your own adapter with the following signature: + +```js +type Adapter = (imagePath: string) => { + metadata: () => Promise<{width: number, height: number}> + resize: (config: {width: number, mime: string, options: Object}) => Promise<{data: Buffer, width: number, height: number}> +} +``` + +The `resize` method takes a single argument which has a `width`, `mime` and `options` property (which receives all loader options) + +In your webpack config, require your adapter + +```js +{ + test: /\.(jpe?g|png)$/i, + loader: 'responsive-loader', + options: { + adapter: require('./my-adapter') + foo: 'bar' // will get passed to adapter.resize({width, mime, options: {foo: 'bar}}) + } +} +``` + +## Notes + +- Doesn't support `1x`, `2x` sizes, but you probably don't need it. + +## See also + +- Inspired by [resize-image-loader](https://github.com/Levelmoney/resize-image-loader), but simpler and without dependency on ImageMagick + +[npm]: https://img.shields.io/npm/v/responsive-loader.svg +[npm-url]: https://npmjs.com/package/responsive-loader +[node]: https://img.shields.io/node/v/responsive-loader.svg +[node-url]: https://nodejs.org +[deps]: https://david-dm.org/dazuaz/responsive-loader.svg +[deps-url]: https://david-dm.org/dazuaz/responsive-loader +[travis]: https://travis-ci.com/dazuaz/responsive-loader.svg?branch=master +[travis-url]: https://travis-ci.com/dazuaz/responsive-loader +[size]: https://packagephobia.now.sh/badge?p=responsive-loader +[size-url]: https://packagephobia.now.sh/result?p=responsive-loader diff --git a/.yalc/responsive-loader/jimp.js b/.yalc/responsive-loader/jimp.js new file mode 100644 index 0000000..ed26566 --- /dev/null +++ b/.yalc/responsive-loader/jimp.js @@ -0,0 +1 @@ +module.exports = require('./lib/adapters/jimp'); diff --git a/.yalc/responsive-loader/package.json b/.yalc/responsive-loader/package.json new file mode 100644 index 0000000..d3cf957 --- /dev/null +++ b/.yalc/responsive-loader/package.json @@ -0,0 +1,58 @@ +{ + "name": "responsive-loader", + "version": "2.3.0+3df241e4", + "description": "A webpack loader for responsive images", + "main": "lib/cjs.js", + "engines": { + "node": ">= 10.13.0" + }, + "scripts": { + "build": "tsc && cp ./src/cjs.js ./lib", + "lint": "eslint", + "test:clean": "find -E test/**/build/ -regex '.*/*.(avif|jpg|webp|png|js)' -delete", + "test": "npm run build && npm run test:clean && webpack --config=./test/jimp/webpack.config.js && webpack --config=./test/sharp/webpack.config.js && jest" + }, + "files": [ + "lib", + "jimp.js", + "sharp.js" + ], + "repository": { + "type": "git", + "url": "git+https://github.com/dazuaz/responsive-loader.git" + }, + "keywords": [ + "webpack", + "responsive", + "loader", + "srcset" + ], + "author": "Jeremy Stucki ", + "contributors": [ + "Daniel Zuloaga (https://staticprops.com/)" + ], + "license": "BSD-3-Clause", + "bugs": { + "url": "https://github.com/dazuaz/responsive-loader/issues" + }, + "homepage": "https://github.com/dazuaz/responsive-loader", + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + }, + "peerDependenciesMeta": { + "jimp": { + "optional": true + }, + "sharp": { + "optional": true + } + }, + "dependencies": { + "loader-utils": "^2.0.0", + "schema-utils": "^3.0.0" + }, + "jest": { + "testEnvironment": "node" + }, + "yalcSig": "3df241e424afebecff77b309d1447b8e" +} diff --git a/.yalc/responsive-loader/sharp.js b/.yalc/responsive-loader/sharp.js new file mode 100644 index 0000000..d9a71d3 --- /dev/null +++ b/.yalc/responsive-loader/sharp.js @@ -0,0 +1 @@ +module.exports = require('./lib/adapters/sharp'); diff --git a/.yalc/responsive-loader/yalc.sig b/.yalc/responsive-loader/yalc.sig new file mode 100644 index 0000000..814d6c2 --- /dev/null +++ b/.yalc/responsive-loader/yalc.sig @@ -0,0 +1 @@ +3df241e424afebecff77b309d1447b8e \ No newline at end of file diff --git a/package.json b/package.json index 7386d09..5c6c82d 100644 --- a/package.json +++ b/package.json @@ -49,6 +49,7 @@ }, "dependencies": { "loader-utils": "^2.0.0", + "responsive-loader": "file:.yalc/responsive-loader", "schema-utils": "^3.0.0" }, "devDependencies": { diff --git a/src/declarations.d.ts b/src/declarations.d.ts new file mode 100644 index 0000000..261d51e --- /dev/null +++ b/src/declarations.d.ts @@ -0,0 +1,4 @@ +declare module "*.json" { + const value: any + export default value +} diff --git a/src/index.ts b/src/index.ts index 2c05a51..930e1af 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,7 @@ import { parseQuery, getOptions, interpolateName } from "loader-utils" + import { validate } from "schema-utils" +import * as schema from "./schema.json" import { parseOptions, getOutputAndPublicPath, createPlaceholder } from "./utils" @@ -13,8 +15,6 @@ import type { AdapterResizeResponse, } from "./types" -import schema from "./schema.json" - const DEFAULTS = { quality: 85, placeholder: false, @@ -43,7 +43,6 @@ export default function loader(this: LoaderContext, content: Buffer): void { // combine webpack options with query options, later sources' properties overwrite earlier ones. const options: Options = Object.assign({}, DEFAULTS, getOptions(this), parsedResourceQuery) - // @ts-ignore validate(schema, options, { name: "Responsive Loader" }) /** diff --git a/src/schema.json b/src/schema.json index 2e3ec35..a931349 100644 --- a/src/schema.json +++ b/src/schema.json @@ -31,6 +31,7 @@ "name": { "type": "string" }, + "outputPath": { "anyOf": [{ "type": "string" }, { "instanceof": "Function" }] }, diff --git a/tsconfig.json b/tsconfig.json index 30ed7e0..25068ab 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -12,7 +12,7 @@ // "sourceMap": true, /* Additional Checks */ "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */, - "resolveJsonModule": true, + "resolveJsonModule": false, /* Advanced Options */ "skipLibCheck": true /* Skip type checking of declaration files. */, "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */ diff --git a/yalc.lock b/yalc.lock new file mode 100644 index 0000000..0df920a --- /dev/null +++ b/yalc.lock @@ -0,0 +1,9 @@ +{ + "version": "v1", + "packages": { + "responsive-loader": { + "signature": "3df241e424afebecff77b309d1447b8e", + "file": true + } + } +} \ No newline at end of file