Skip to content

Commit

Permalink
feat: make image metadata available in defaultDirectives (#619)
Browse files Browse the repository at this point in the history
  • Loading branch information
benmccann authored Oct 12, 2023
1 parent 4476285 commit 49a89a6
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 9 deletions.
5 changes: 5 additions & 0 deletions .changeset/kind-dogs-walk.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'vite-imagetools': minor
---

feat: make image metadata available in defaultDirectives
29 changes: 22 additions & 7 deletions packages/vite/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,14 @@ import {
builtinOutputFormats,
urlFormat,
extractEntries,
ImageConfig,
Logger,
OutputFormat
type ImageConfig,
type Logger,
type OutputFormat
} from 'imagetools-core'
import { createFilter, dataToEsm } from '@rollup/pluginutils'
import { VitePluginOptions } from './types.js'
import type { Metadata, Sharp } from 'sharp'
import { createBasePath } from './utils.js'
import type { VitePluginOptions } from './types.js'

const defaultOptions: VitePluginOptions = {
include: /^[^?]+\.(heic|heif|avif|jpeg|jpg|png|tiff|webp|gif)(\?.*)?$/,
Expand Down Expand Up @@ -56,9 +57,23 @@ export function imagetools(userOptions: Partial<VitePluginOptions> = {}): Plugin

const srcURL = parseURL(id)

// lazy loaders so that we can load the metadata in defaultDirectives if needed
// but if there are no directives then we can just skip loading
let lazyImg: Sharp
const lazyLoadImage = () => {
if (lazyImg) return lazyImg
return (lazyImg = loadImage(decodeURIComponent(srcURL.pathname)))
}

let lazyMetadata: Metadata
const lazyLoadMetadata = async () => {
if (lazyMetadata) return lazyMetadata
return (lazyMetadata = await lazyLoadImage().metadata())
}

const defaultDirectives =
typeof pluginOptions.defaultDirectives === 'function'
? pluginOptions.defaultDirectives(srcURL)
? await pluginOptions.defaultDirectives(srcURL, lazyLoadMetadata)
: pluginOptions.defaultDirectives || new URLSearchParams()
const directives = new URLSearchParams({
...Object.fromEntries(defaultDirectives),
Expand All @@ -67,9 +82,9 @@ export function imagetools(userOptions: Partial<VitePluginOptions> = {}): Plugin

if (!directives.toString()) return null

const img = loadImage(decodeURIComponent(srcURL.pathname))
const img = lazyLoadImage()
if (directives.get('allowUpscale') !== 'true') {
const metadata = await img.metadata()
const metadata = await lazyLoadMetadata()
const intrinsicWidth = metadata.width || 0
const intrinsicHeight = metadata.height || 0

Expand Down
9 changes: 7 additions & 2 deletions packages/vite/src/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import { TransformFactory, OutputFormat, resolveConfigs } from 'imagetools-core'
import type { TransformFactory, OutputFormat, resolveConfigs } from 'imagetools-core'
import type { Metadata } from 'sharp'

type MaybePromise<T> = T | Promise<T>

export interface VitePluginOptions {
/**
Expand Down Expand Up @@ -39,7 +42,9 @@ export interface VitePluginOptions {
* })
* ```
*/
defaultDirectives?: URLSearchParams | ((url: URL) => URLSearchParams)
defaultDirectives?:
| URLSearchParams
| ((url: URL, metadata: () => MaybePromise<Metadata>) => MaybePromise<URLSearchParams>)

/**
* You can use this option to extend the builtin list of import transforms.
Expand Down

0 comments on commit 49a89a6

Please sign in to comment.