Skip to content

Commit

Permalink
Feature/avif (#349)
Browse files Browse the repository at this point in the history
* heic and avif wip [ci skip]

* rebase fixes

* types fix

* spec fix

* size limit fix

* increase timeout
  • Loading branch information
dangreen authored Jan 31, 2021
1 parent eef69b7 commit 559c806
Show file tree
Hide file tree
Showing 9 changed files with 115 additions and 79 deletions.
2 changes: 1 addition & 1 deletion .size-limit
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[
{
"path": "lib/index.js",
"limit": "3.2 KB",
"limit": "3.3 KB",
"webpack": false
},
{
Expand Down
16 changes: 8 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
"omit-empty": "^1.0.0",
"rcfile": "^1.0.3",
"regenerator-runtime": "^0.13.7",
"sharp": "^0.26.0",
"sharp": "^0.27.1",
"through2-concurrent": "^2.0.0",
"vinyl": "^2.2.0",
"vinyl-fs": "^3.0.3"
Expand All @@ -69,14 +69,14 @@
"@babel/core": "^7.12.10",
"@rollup/plugin-eslint": "^8.0.1",
"@size-limit/preset-small-lib": "^4.9.2",
"@trigen/scripts": "^7.2.0",
"@trigen/scripts-plugin-babel": "^7.2.0",
"@trigen/scripts-plugin-eslint": "^7.2.0",
"@trigen/scripts-plugin-jest": "^7.2.0",
"@trigen/scripts": "^7.3.1",
"@trigen/scripts-plugin-babel": "^7.3.1",
"@trigen/scripts-plugin-eslint": "^7.3.1",
"@trigen/scripts-plugin-jest": "^7.3.1",
"@trigen/scripts-plugin-rollup": "^7.1.0",
"@trigen/scripts-plugin-size-limit": "^7.2.0",
"@trigen/scripts-plugin-typescript": "^7.2.0",
"@trigen/scripts-preset-lib": "^7.3.0",
"@trigen/scripts-plugin-size-limit": "^7.3.1",
"@trigen/scripts-plugin-typescript": "^7.3.1",
"@trigen/scripts-preset-lib": "^7.3.1",
"eslint": "^7.18.0",
"rollup": "^2.38.1",
"rollup-plugin-add-shebang": "^0.3.1",
Expand Down
3 changes: 3 additions & 0 deletions src/defaults.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ import gifLossyPlugin from 'imagemin-giflossy';
import svgoPlugin from 'imagemin-svgo';

export const processing = {
avif: {
quality: 100
},
webp: {
quality: 100
},
Expand Down
3 changes: 2 additions & 1 deletion src/extensions.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@

export type SupportedExtension = 'webp'|'jpg'|'png'|'gif'|'svg';
export type SupportedExtension = 'avif' | 'webp' | 'jpg' | 'png' | 'gif' | 'svg';

export const extensions = {
avif: /^avif$/i,
webp: /^webp$/i,
jpg: /^jpe?g$/i,
png: /^png$/i,
Expand Down
5 changes: 5 additions & 0 deletions src/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
ISrcSetVinyl
} from './types';
import {
SupportedExtension,
isSupportedType
} from './extensions';

Expand Down Expand Up @@ -127,3 +128,7 @@ export async function matchImage(source: ISrcSetVinyl, matcherOrMatchers: Matche
return false;
});
}

export function getFormat(file: Vinyl) {
return file.extname.replace(/^\./, '').toLowerCase() as SupportedExtension;
}
45 changes: 29 additions & 16 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ import {
} from './extensions';
import {
isVinylBuffer,
attachMetadata
attachMetadata,
getFormat
} from './helpers';
import {
ISrcSetVinyl,
Expand Down Expand Up @@ -85,15 +86,17 @@ export default class SrcSetGenerator {
scalingUp: this.scalingUp,
...generateConfig
};
const sourceType = source.extname.replace(/^\./, '') as SupportedExtension;
const sourceType = getFormat(source);

if (!isSupportedType(sourceType)) {
throw new Error(`"${sourceType}" is not supported.`);
}

const outputTypes = Array.isArray(config.format)
? config.format
: [config.format];
const outputTypes = (
Array.isArray(config.format)
? config.format
: [config.format]
).map(_ => _.toLowerCase() as SupportedExtension);
const widths = Array.isArray(config.width)
? config.width
: [config.width];
Expand Down Expand Up @@ -212,19 +215,29 @@ export default class SrcSetGenerator {
this.addPostfix(target, originWidth, originWidth, config.postfix);
}

if (!willResize && source.extname === target.extname) {
if (!willResize && source.extname.toLowerCase() === target.extname) {
target.contents = source.contents;
return target;
}

if (extensions.webp.test(outputType)) {
processor.webp(processing.webp);
} else
if (extensions.jpg.test(outputType)) {
processor.jpeg(processing.jpg);
} else
if (extensions.png.test(outputType)) {
processor.png(processing.png);
switch (true) {
case extensions.webp.test(outputType):
processor.webp(processing.webp);
break;

case extensions.jpg.test(outputType):
processor.jpeg(processing.jpg);
break;

case extensions.png.test(outputType):
processor.png(processing.png);
break;

case extensions.avif.test(outputType):
processor.avif(processing.avif);
break;

default:
}

target.contents = await processor.toBuffer();
Expand All @@ -246,7 +259,7 @@ export default class SrcSetGenerator {
...this.optimization,
...config.optimization
};
const plugins = optimization[source.extname.replace(/^\./, '') as SupportedExtension];
const plugins = optimization[getFormat(source)];

target.contents = await Imagemin.buffer(source.contents as Buffer, {
plugins: Array.isArray(plugins)
Expand All @@ -270,7 +283,7 @@ export default class SrcSetGenerator {
width: number,
customPostfix: Postfix = null
) {
const format = target.extname.replace('.', '');
const format = getFormat(target);
const {
postfix
} = this;
Expand Down
22 changes: 12 additions & 10 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,10 @@ export interface ISrcSetVinyl extends Vinyl {
* ```
*/
export interface IProcessingConfig {
webp: Record<string, unknown>;
jpg: Record<string, unknown>;
png: Record<string, unknown>;
avif?: Record<string, unknown>;
webp?: Record<string, unknown>;
jpg?: Record<string, unknown>;
png?: Record<string, unknown>;
}

/**
Expand All @@ -57,11 +58,12 @@ export interface IProcessingConfig {
* ```
*/
export interface IOptimizationConfig {
webp: Plugin | Plugin[];
jpg: Plugin | Plugin[];
png: Plugin | Plugin[];
gif: Plugin | Plugin[];
svg: Plugin | Plugin[];
avif?: Plugin | Plugin[];
webp?: Plugin | Plugin[];
jpg?: Plugin | Plugin[];
png?: Plugin | Plugin[];
gif?: Plugin | Plugin[];
svg?: Plugin | Plugin[];
}

export type IPostfixFormatter = (width: number, mul?: number, format?: string) => string;
Expand All @@ -75,11 +77,11 @@ export interface IConfig {
/**
* Object with Sharp configs for each supported format.
*/
processing?: Partial<IProcessingConfig>;
processing?: IProcessingConfig;
/**
* Object with imagemin plugins for each format.
*/
optimization?: Partial<IOptimizationConfig>;
optimization?: IOptimizationConfig;
/**
* Do not optimize output images.
*/
Expand Down
14 changes: 13 additions & 1 deletion test/SrcsetGenerator.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ async function vinylsFromAsyncIterator(iterator: AsyncIterableIterator<Vinyl>) {
}

describe('SrcSetGenerator', () => {
jest.setTimeout(30000);
jest.setTimeout(60000);

it('should create correct instance', () => {
const srcSet = new SrcSetGenerator();
Expand Down Expand Up @@ -97,6 +97,18 @@ describe('SrcSetGenerator', () => {
expect(imageWithPostfix.postfix).toBe('@postfix');
});

it('should support avif', async () => {
const srcSet = new SrcSetGenerator({
skipOptimization: true
});
const [avifImage] = await vinylsFromAsyncIterator(srcSet.generate(image, {
format: 'avif'
}));

expect(avifImage.metadata.format).toBe('heif');
expect(avifImage.extname).toBe('.avif');
});

describe('#generate', () => {
const srcSet = new SrcSetGenerator({
skipOptimization: true
Expand Down
84 changes: 42 additions & 42 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1437,38 +1437,38 @@
eslint-plugin-react "^7.17.0"
eslint-plugin-react-hooks "^4.0.4"

"@trigen/scripts-plugin-babel@^7.2.0":
version "7.2.0"
resolved "https://registry.yarnpkg.com/@trigen/scripts-plugin-babel/-/scripts-plugin-babel-7.2.0.tgz#dd4e5c084abd2c20650cfe3d54fe5333c7d860f2"
integrity sha512-gULAA5BiCIwjx5040wk28Vt+6GumsE2VeDuOHXUEAFJmhXyNTS0lUVh4GpsEKSNZKL7duX2S7MALi1j13zmM7g==
"@trigen/scripts-plugin-babel@^7.3.1":
version "7.3.1"
resolved "https://registry.yarnpkg.com/@trigen/scripts-plugin-babel/-/scripts-plugin-babel-7.3.1.tgz#a20e0f8f64093b52a7379b6bf35ff79a53f07930"
integrity sha512-nNqQw1d/J9ycLbiBAkTsKIV+8GvzEBQHjKsFV0JrMJ8xJ67OEeSQ2AE2Uum7ub8lytmVh+rKKPAjxDiDGabzZQ==
dependencies:
"@babel/cli" "^7.2.3"
"@babel/core" "^7.4.0"
"@babel/node" "^7.0.0"
"@babel/runtime" "^7.12.5"
"@trigen/babel-preset" "^7.1.0"
"@trigen/scripts" "^7.2.0"
"@trigen/scripts" "^7.3.1"
core-js "^3.8.2"

"@trigen/scripts-plugin-eslint@^7.2.0":
version "7.2.0"
resolved "https://registry.yarnpkg.com/@trigen/scripts-plugin-eslint/-/scripts-plugin-eslint-7.2.0.tgz#1fbda9c34b184944dbc69168eba6a88146cb08ae"
integrity sha512-jcKYE8Lof8V66d6ZRIqN4sh58xDQbfvbL8T8Yo0RSzugExLPjmB/XeByNT/X1BS/C/5gpE+ECmnvPQU5pJZ7WQ==
"@trigen/scripts-plugin-eslint@^7.3.1":
version "7.3.1"
resolved "https://registry.yarnpkg.com/@trigen/scripts-plugin-eslint/-/scripts-plugin-eslint-7.3.1.tgz#cdbd90c526f1a427638fbd8f2f9a05684cb3df89"
integrity sha512-gLvilWAYUAZrdu7GJd05SD/mmDLmy6KWNG/6B0LSik3oNTqjS3xq58J74c0nfjELPDW9ZIf3HCyF5IN0GqNyrw==
dependencies:
"@babel/runtime" "^7.12.5"
"@trigen/eslint-config" "^7.1.0"
"@trigen/scripts" "^7.2.0"
"@trigen/scripts" "^7.3.1"
core-js "^3.8.2"
eslint "^7.0.0"

"@trigen/scripts-plugin-jest@^7.2.0":
version "7.2.0"
resolved "https://registry.yarnpkg.com/@trigen/scripts-plugin-jest/-/scripts-plugin-jest-7.2.0.tgz#39547c95b657864d1446e99f2201eccf0c71de09"
integrity sha512-TXFuAAzhnr6hDEp5XrZ3m06y3kynAItNFHf9P1BeTJBJwbxFvjxhuN4t2b4MuOnPMBU/7LCrzpf7bHhWq4rp5A==
"@trigen/scripts-plugin-jest@^7.3.1":
version "7.3.1"
resolved "https://registry.yarnpkg.com/@trigen/scripts-plugin-jest/-/scripts-plugin-jest-7.3.1.tgz#2a5a554305a988cea2d0eb29e23d091f69578b51"
integrity sha512-6On1p+M1w81Q0o6X6FkaGGN2SEKSrvxAFqAXJi7yLS+KKGQI5eUdLmXi57yVrQ6hjldJkR6BrkzrdvJRlZL0QQ==
dependencies:
"@babel/runtime" "^7.12.5"
"@trigen/babel-preset" "^7.1.0"
"@trigen/scripts" "^7.2.0"
"@trigen/scripts" "^7.3.1"
"@types/jest" "^26.0.0"
archiver "^5.2.0"
babel-jest "^26.0.1"
Expand All @@ -1489,48 +1489,48 @@
core-js "^3.8.2"
rollup "^2.6.1"

"@trigen/scripts-plugin-size-limit@^7.2.0":
version "7.2.0"
resolved "https://registry.yarnpkg.com/@trigen/scripts-plugin-size-limit/-/scripts-plugin-size-limit-7.2.0.tgz#e7fce2bec29581b113bb59b9489d6bd6ff7eb385"
integrity sha512-co9TU3N2OCDSoHU3B7Xk1mRBbtlI6DBFkt3NG1PNouJzos3Ze7Owm7MOnDvfiB3sa0Lsfdx8HWzXQ4F22gHbHA==
"@trigen/scripts-plugin-size-limit@^7.3.1":
version "7.3.1"
resolved "https://registry.yarnpkg.com/@trigen/scripts-plugin-size-limit/-/scripts-plugin-size-limit-7.3.1.tgz#4cd4a833d79a74d0c2f45a796d57289b1898b424"
integrity sha512-x7Azhqff6hEepydngslx5S+Ypk9xcxHwLrkhWW2ct5pm7k5D2MW5guiuE/sUml1wPAWORtRaZ+wS+oA4ofuCrg==
dependencies:
"@babel/runtime" "^7.12.5"
"@trigen/scripts" "^7.2.0"
"@trigen/scripts" "^7.3.1"
core-js "^3.8.2"
size-limit "^4.1.1"

"@trigen/scripts-plugin-typescript@^7.2.0":
version "7.2.0"
resolved "https://registry.yarnpkg.com/@trigen/scripts-plugin-typescript/-/scripts-plugin-typescript-7.2.0.tgz#8ad831cbadea6a095408c55ab4f1f87f1f34182b"
integrity sha512-5OXL7rvZskU6lYti6gfotwNfXPNX/KNLGLPy64VlCVNXZHQ1WdBPv/7OBvclv36lAh2T2Xj6dmWk0BG0DuljMg==
"@trigen/scripts-plugin-typescript@^7.3.1":
version "7.3.1"
resolved "https://registry.yarnpkg.com/@trigen/scripts-plugin-typescript/-/scripts-plugin-typescript-7.3.1.tgz#30d2e59ffe2110885616165e7ee72bd576218f6a"
integrity sha512-9FbdExTkChR6JvOYbRaSJYrLL44IiuGPmZQpTG0eRz3Am/vHJHPZ+5dmv6QtG1PvjD31t3hLQFTVz81QTW5g0Q==
dependencies:
"@babel/runtime" "^7.12.5"
"@trigen/scripts" "^7.2.0"
"@trigen/scripts" "^7.3.1"
core-js "^3.8.2"
ts-node-dev "^1.0.0-pre.39"
tsconfig-paths "^3.8.0"
typedoc "^0.20.16"
typescript "4.1.3"

"@trigen/scripts-preset-lib@^7.3.0":
version "7.3.0"
resolved "https://registry.yarnpkg.com/@trigen/scripts-preset-lib/-/scripts-preset-lib-7.3.0.tgz#8ec42f5f428c7e39dfe282c21b4bb192f9f8dd37"
integrity sha512-aAv1/taJ493zONQ1hmX69SyxSxxuUUzDiyNjH/Xo3hIIx9ziYRTwz+RiAe/BZhoLxc7TSX9jnMlFeTd33/Pq5g==
"@trigen/scripts-preset-lib@^7.3.1":
version "7.3.1"
resolved "https://registry.yarnpkg.com/@trigen/scripts-preset-lib/-/scripts-preset-lib-7.3.1.tgz#b4c5ce0eb89cc396fc2438817bee26f2b2149594"
integrity sha512-u5pbmE15VOU/ZUS1TM2XME6uDwRjEZvrtsvvtY+jcKr3XadE/hO/c+1nGVeA2k37Wy22dJVDjrAu+WPogO/6kg==
dependencies:
"@babel/runtime" "^7.12.5"
"@trigen/browserslist-config" "^7.1.0"
"@trigen/scripts" "^7.2.0"
"@trigen/scripts-plugin-eslint" "^7.2.0"
"@trigen/scripts" "^7.3.1"
"@trigen/scripts-plugin-eslint" "^7.3.1"
clean-publish "^1.1.0"
core-js "^3.8.2"
coveralls "^3.0.0"
husky "^4.0.9"
lint-staged "^10.0.0"

"@trigen/scripts@^7.2.0":
version "7.2.0"
resolved "https://registry.yarnpkg.com/@trigen/scripts/-/scripts-7.2.0.tgz#0d9604692504a73b79db6cbab6dfb2c462bd4bf7"
integrity sha512-bbjz/tcYdjLe2cFIsfyhtdbrx1DN+ByPM4AWFsTicH/djPc0RxYUlb3+n7A5AMmSyX0GPJ7GWDDkxemv99SK3g==
"@trigen/scripts@^7.3.1":
version "7.3.1"
resolved "https://registry.yarnpkg.com/@trigen/scripts/-/scripts-7.3.1.tgz#a3dd22194d11cbbf54d1652a48ba89bd5049a8e0"
integrity sha512-GYK20Lx6LG8qhTEIueGXWCvi6RF6CMPJ18A0vp0oSA55UDgK0vQJPQ4P7pUXGV4x07phoOoIUV0h9RmzTEPGCw==
dependencies:
"@babel/runtime" "^7.12.5"
chalk "^4.0.0"
Expand Down Expand Up @@ -8164,7 +8164,7 @@ node-abi@^2.7.0:
dependencies:
semver "^5.4.1"

node-addon-api@^3.0.2:
node-addon-api@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-3.1.0.tgz#98b21931557466c6729e51cb77cd39c965f42239"
integrity sha512-flmrDNB06LIl5lywUz7YlNGZH/5p0M7W28k8hzd9Lshtdh1wshD2Y+U4h9LD6KObOy1f+fEVdgprPrEymjM5uw==
Expand Down Expand Up @@ -10275,18 +10275,18 @@ sha.js@^2.4.0, sha.js@^2.4.8:
inherits "^2.0.1"
safe-buffer "^5.0.1"

sharp@^0.26.0:
version "0.26.3"
resolved "https://registry.yarnpkg.com/sharp/-/sharp-0.26.3.tgz#9de8577a986b22538e6e12ced1f7e8a53f9728de"
integrity sha512-NdEJ9S6AMr8Px0zgtFo1TJjMK/ROMU92MkDtYn2BBrDjIx3YfH9TUyGdzPC+I/L619GeYQc690Vbaxc5FPCCWg==
sharp@^0.27.1:
version "0.27.1"
resolved "https://registry.yarnpkg.com/sharp/-/sharp-0.27.1.tgz#cd04926406a697b58dfc5fb62e3c7a3a2d68389a"
integrity sha512-IQNXWdspb4nZcJemXa6cfgz+JvKONsuqP8Mwi1Oti23Uo7+J+UF2jihJDf6I1BQbrmhcZ0lagH/1WYG+ReAzyQ==
dependencies:
array-flatten "^3.0.0"
color "^3.1.3"
detect-libc "^1.0.3"
node-addon-api "^3.0.2"
node-addon-api "^3.1.0"
npmlog "^4.1.2"
prebuild-install "^6.0.0"
semver "^7.3.2"
semver "^7.3.4"
simple-get "^4.0.0"
tar-fs "^2.1.1"
tunnel-agent "^0.6.0"
Expand Down

0 comments on commit 559c806

Please sign in to comment.