theKashey / holistic-image

Wholesome image management
37 stars 1 forks source link

holistic-image

Holism is the idea that various systems should be viewed as wholes, not merely as a collection of parts.

Build-time Automatic image transformation and Holistic management

Structure

This is a convention over configuration library, and all you need is to follow our convention

Having ➑️

β”œβ”€β”€ image@2x.holistic.png

️Will produce ⬇️

β”œβ”€β”€ image@2x.holistic.png
β”œβ”€β”€ .holistic (you can hide this directory)
β”‚   └─ image@2x
β”‚      β”œβ”€ derived.image@1x.jpg
β”‚      β”œβ”€ derived.image@1x.webp
β”‚      β”œβ”€ derived.image@1x.avif
β”‚      β”œβ”€ derived.image@2x.jpg
β”‚      β”œβ”€ derived.image@2x.webp
β”‚      β”œβ”€ derived.image@2x.avif
|      β”œβ”€ derived.scss
β”‚      └─ derived.image@2x.meta.js

The same principle will be applied during the import - instead of importing image@2x.holistic.png you will get a pointer to all files below

Note: holistic-image does not produce png output (configurable) as the end user is expected to use webp or avif

Usage

Step 1 - derive files

holistic-image is looking for files named accordingly - image.holistic.png(or jpg) and derives the "missing" ones - optimized jpg, webp and avif

If the source file named as image@2x.jpg(Figma standard), then @1x version will be generated automatically

How to use

// generate-images.js
import {deriveHolisticImages} from "holistic-image/api";

deriveHolisticImages(
  /root folder*/
process.argv[2],
  /*mask*/ process.argv[3],
// /*optional*/ squoosh ecoders with options
)

And then in package.json

// package.json
 "autogen:images": "yarn generate-images.js $INIT_CWD 'src/**/*'",
// package.json
"autogen:images":"holistic-image derive  $INIT_CWD 'src/**/*'"
"validate:images":"holistic-image validate  $INIT_CWD 'src/**/*'"

Step 2 - configure webpack to process images

import { holisticImage } from 'holistic-image/webpack';

webpack.config = {
  module: {
    rules: {
      oneOf: [holisticImage, yourFileLoader],
      // .. rest of your config
    },
  },
};
import { holisticImage } from 'holistic-image/webpack';

webpack.config = {
  module: {
    rules: {
      holisticImage,
      yourFileLoader,
      // .. and rest of your config
    },
  },
};

Step 3 - use

import image from './image.holistic.jpg';
// ^ not an image, but HolisticalImageDefinition
image = {
  base: [1x, 2x],
  webp: [1x, 2x],
  avif: [1x, 2x],
  [META]: {width, height, ratio}
}

Build in React component

import { Image } from 'holistical-image/react';
import image from './image.holistic.jpg';
import imageXS from './imageXS.holistic.jpg';

<Image src={image} media={{ 'max-width: 600px': imageXS }} />;
// πŸ‘‡ 6-12 images generated, the right picked, completely transparent

TypeScript integration

While this library provides d.ts for the file extension it can be more beneficial to provide your own ones, as you did for .jpg and other static asses already

declare module '*.holistic.jpg' {
  import type { HolisticalImageDefinition } from 'holistic-image';

  const content: HolisticalImageDefinition;
  export default content;
}

Configuration

Configuration is possible in two modes:

Example configuration: > `.holistic-imagerc.yaml` (can be json or js as well) ```yml # derived from https://github.com/GoogleChromeLabs/squoosh/blob/61de471e52147ecdc8ff674f3fcd3bbf69bb214a/libsquoosh/src/codecs.ts --- jpg: use: mozjpeg # with default 75 options: - quality: 80 # for scale 1x - quality: 70 # for scale 2x webp: use: webp # with default 75 options: - quality: 85 method: 6 avif: use: avif # with default 33 options: - cqLevel: 20 effort: 5 - cqLevel: 28 effort: 5 ```

Hiding .holistic output files

folders starting from . already expected to be hidden for IDE, but keep in mind - derived files are expected to be commited.

WebStorm/IDEA

You can use idea-exclude to automaticaly configure Idea-based solutions to exclude these folders

VCS

"files.exclude": {
    "**/.holistic": true
}

See also

License

MIT