Giter Site home page Giter Site logo

elmassimo / vite-plugin-image-presets Goto Github PK

View Code? Open in Web Editor NEW
244.0 3.0 5.0 363 KB

๐Ÿ–ผ Image Presets for Vite.js apps

Home Page: https://image-presets.netlify.app/

License: MIT License

Vue 9.14% HTML 4.24% TypeScript 74.96% JavaScript 11.66%
image-processing images ssg vitejs vite-plugin sharp

vite-plugin-image-presets's Introduction


vite-plugin-image-presets

Image Presets for Vite.js apps


This Vite plugin allows you to define presets for image processing using Sharp, allowing you to optimize, resize, and process images consistently and with ease.

Demo ๐Ÿ–ผ

Installation ๐Ÿ’ฟ

npm install -D vite-plugin-image-presets # pnpm, yarn

Configuration โš™๏ธ

Add it to your plugins in vite.config.ts

import { defineConfig } from 'vite'
import imagePresets, { widthPreset } from 'vite-plugin-image-presets'

export default defineConfig({
  plugins: [
    imagePresets({
      thumbnail: widthPreset({
        class: 'img thumb',
        loading: 'lazy',
        widths: [48, 96],
        formats: {
          webp: { quality: 50 },
          jpg: { quality: 70 },
        },
      }),
    }),
  ],
})

Usage ๐Ÿš€

Use the preset query parameter to obtain an array of source and img attrs:

import thumbnails from '~/images/logo.jpg?preset=thumbnail'

expect(thumbnails).toEqual([
  {
    type: 'image/webp',
    srcset: '/assets/logo.ffc730c4.webp 48w, /assets/logo.1f874174.webp 96w',
  },
  {
    type: 'image/jpeg',
    srcset: '/assets/logo.063759b1.jpeg 48w, /assets/logo.81d93491.jpeg 96w',
    src: '/assets/logo.81d93491.jpeg',
    class: 'img thumb',
    loading: 'lazy',
  },
])

You can also use the src and srcset query parameters for direct usage:

import srcset from '~/images/logo.jpg?preset=thumbnail&srcset'
import src from '~/images/logo.jpg?preset=thumbnail&src'

expect(srcset).toEqual('/assets/logo.063759b1.jpeg 48w, /assets/logo.81d93491.jpeg 96w')
expect(src).toEqual('/assets/logo.81d93491.jpeg')

Check the example for additional usage information and different preset examples, or see it live.

Documentation ๐Ÿ“–

Additional usage documentation coming soon.

In the meantime, check the @islands/images module for รฎles.

Acknowledgements

  • sharp: High performance Node.js image processing
  • vite-imagetools: The middleware used in development is based on this nice library.

The hdPreset is based on the following article by Jake Archibald:

License

This library is available as open source under the terms of the MIT License.

vite-plugin-image-presets's People

Contributors

elmassimo avatar ngalaiko avatar ouuan avatar rajaniraiyn avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

vite-plugin-image-presets's Issues

enhancement: string as the default export if the preset only defines srcset

Description ๐Ÿ“–

Currently the default export for preset imports is ImageSource[]. This allows presets to define additional source tags, with different formats, conditional widths and densities, etc.

For presets that define a single ImageSource that only contains srcsets, it would be convenient for the default export to be a string.

That would make it work out of the box in img and source tags in HTML and Vue SFCs, where src and srcset are already extracted as imports.

Dynamic imports

Hello :)
Does this plugin supports vite's dynamic imports?
For example:
new URL(/src/assets/img/category/${slug}.png, import.meta.url).href

Usage in raw HTML/Twig

Hi,

It looks like a great plugin ! Sorry if I misunderstand something, but I can't find how to use this in a raw HTML or a Twig template. Is this something possible ?

Best.

Possible vulnerability in sharp at 'npm install' time if an attacker has control over build environment

There's a possible vulnerability in logic that is run only at npm install time when installing versions of sharp prior to the latest v0.30.5.

This is not part of any runtime code, does not affect Windows users at all, and is unlikely to affect anyone that already cares about the security of their build environment. However, out of an abundance of caution, I've created this advisory.

If an attacker has the ability to set the value of the PKG_CONFIG_PATH environment variable in a build environment then they might be able to use this to inject an arbitrary command at npm install time.

I've used the Common Vulnerability Scoring System (CVSS) calculator to determine the maximum possible impact, which suggests a "medium" score of 5.9, but for most people the real impact will be dealing with the noise from automated security tooling that this advisory will bring.

AV:L/AC:L/PR:H/UI:R/S:U/C:H/I:H/A:H/E:P/RL:O/RC:C/CR:X/IR:X/AR:X/MAV:X/MAC:X/MPR:X/MUI:R/MS:X/MC:X/MI:X/MA:X

This problem was fixed in commit a6aeef6 and published as part of sharp v0.30.5.

[Feature Request] Include generated image dimensions

Taking the example from the readme...

widthPreset({
  class: 'img thumb',
  loading: 'lazy',
  widths: [48, 96],
  formats: {
    webp: { quality: 50 },
    jpg: { quality: 70 }
  }
})

it would be great to have a width and height attributes to spread onto the <img> in order to give it the correct intrinsic dimensions and reserve the correct amount of space when loading to avoid layout shifts, e.g. assuming a 100x150 source image

expect(thumbnails).toEqual([
  {
    type: 'image/webp',
    srcset: '/assets/logo.ffc730c4.webp 48w, /assets/logo.1f874174.webp 96w',
  },
  {
    type: 'image/jpeg',
    srcset: '/assets/logo.063759b1.jpeg 48w, /assets/logo.81d93491.jpeg 96w',
    src: '/assets/logo.81d93491.jpeg',
    class: 'img thumb',
    loading: 'lazy',
    
    // width and height of the generated image used for `src`
    width: 96,
    height: 144,
  },
])

Animated images Support

Sharp supports animated option to read all frames of an animated png, gif, avif, webp image formats. But, there is no way to use that option in presets. Now by default all animated images are converted to non-animated upon any conversion.

https://github.com/Rajaniraiyn/modern-web-boilerplate , this project uses apng but upon using this plugin it is converted into non-animated form.

Not only this. It would be nicer to enable an option to parse custom options to sharp

Update NPM package

A security issue #14 is fixed in the pull #15 and it is also merged but this package is not yet updated in NPM registry. Please publish the the updated repo in NPM so all the dependent projects can benefited

`&src` argument gives bad `/@imagepresets/[id].[ext]` path (vite 5)

the import for the file in question:
import rebrandedImage from "../../../images/example.jpeg?preset=800&src"

Screenshot 2024-01-22 at 12 33 37

the preset:

imagePresets({
     800: widthPreset({
          widths: [800],
          loading: "lazy",
          formats: {
            png: { quality: 70 },
            jpeg: { quality: 70 },
          },
      })
})

what am i missing?

vite: 5.0.8
sharp: 0.33.2

Use `rollupOptions.options.assetFileNames` when specified in the Vite config

Typically in vite we use build.rollupOptions.output.assetFileNames to tweak output directory and file names, like:

            rollupOptions: {
                output: {
                    assetFileNames: (asset) => {
                        if (
                            ['.jpg', '.png', '.svg', '.avif', '.webp'].some((ext) =>
                                asset.name?.endsWith(ext),
                            )
                        ) {
                            return 'images/[name]-[hash][extname]';
                        }
                        return 'assets/[name]-[hash][extname]';  // for other assets like fonts and audios etc.
                    },
                },

While this plugin provides an assetsDir option, it should still conform to the idiom above when assetsDir is not specified. But unfortunately that's not the current behavior.

I can submit a PR for this if feasible.

Add support for dynamic images

Is there any possibility to load dynamic images? I have the following use case:
I load a list of events from my headless cms. All events have an attribute title image that is named like an image i have in my assets folder. Now i want to use vite-plugin-image-presets with the picture vue sfc and the image described in the event attribute.
Is there any pattern i can use to do this?

My workaround is a sfc called DynamicPicture that looks like this:

<template>
  <Picture :src="src" />
</template>

<script setup lang="ts">
import { computed } from 'vue'

import event_img_1 from '@/assets/events/event_img_1.jpg?preset=full'
import event_img_2 from '@/assets/events/event_img_2.jpg?preset=full'
import event_img_3 from '@/assets/events/event_img_3.jpg?preset=full'

let assets = new Map<string, any>([
  ['event_img_1.jpg', event_img_1],
  ['event_img_2.jpg', event_img_2],
  ['event_img_3.jpg', event_img_3],
])

const props = defineProps({
  name: {
    type: String,
    required: true,
  },
})

const src = computed(() => assets.get(props.name))
</script>

It works. But i need to add a line of code every time i add a new event image into the assets directory (what happens sometimes).

Example Image.vue with <style scoped>

Is it possible to set a class on <Image> and have it be defined in a <style scoped> in the component that instantiates the Image? Basically if I'm replacing an existing <img> that had a class on it, I currently have to move that class to a plain <style> since it doesn't seem to trigger the scoped logic when it's passed into the <Image>.

This is more of a Vue question but you seem to know your way around so I figured I'd ask here first.

[Feature Request] Default preset

It would be nice if there were a way to specify a default preset so every import didn't need the query string.

Maybe something like this...

    imagePresets({
      'default': widthPreset({
        widths: [425, 1024, 1200],
        formats: {
          webp: { quality: 100 },
          png: { quality: 100 }
        }
      })
    }),

Or this...

    imagePresets({
      'foobar': widthPreset({
        default: true,
        widths: [425, 1024, 1200],
        formats: {
          webp: { quality: 100 },
          png: { quality: 100 }
        }
      })
    }),

Great plugin btw ๐Ÿ‘ It's saved me a lot of time already.

Can this work with import.meta.glob?

I have a "gallery" of images which gets loaded like so:

import.meta.glob<string>("@/assets/images/**", {
    eager: true,
    as: "url",
})

Is it possible to have the plugin process the images that get imported in this way? Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.