Плагин Vite
Обрабатывайте изображения на этапе сборки — так же, как CLI, но интегрировано в жизненный цикл Vite. Запускается на buildStart и перезапускается в dev-режиме при изменении исходных изображений.
Рецепты интеграции показывают готовые конфигурации на все случаи — с пояснением, для чего каждая и когда её применять.
// vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { vueImageKit } from '@macrulez/vue-image-kit/vite'
export default defineConfig({
plugins: [
vue(),
vueImageKit({
input: './src/images',
output: './public/images',
widths: [400, 800, 1200],
manifest: './src/assets/images.ts',
}),
],
})Поддерживаются все опции CLI. sharp должен быть установлен как dev-зависимость.
buildStart/handleHotUpdate вызывают ту же generate(), что и CLI, поэтому инкрементальная генерация применима и здесь — и автоматически включается именно во время vite dev (не vite build), если не задать incremental явно. Изменение одного исходного файла в dev переобрабатывает только этот файл, а не весь пакет.
Горячее обновление запускает генерацию только для изображения внутри input и никогда для файла внутри output, поэтому файлы, которые плагин пишет сам, не могут запустить новый проход. Проходы никогда не накладываются друг на друга: изменения, пришедшие во время работы, объединяются в один повторный запуск. output может даже лежать внутри input — при сканировании папки он пропускается.
SVG-изображения
У векторного изображения нет hazehash, blurhash и thumbhash — только доминирующий цвет и размер:
import icon from './logo.svg?placeholder'
// → { placeholderColor: '#ee3333', width: 64, height: 64 }Размер берётся из собственных width/height (или viewBox) файла без растеризации, а большой SVG для определения цвета рендерится в уменьшенном виде, поэтому вектор 30000×30000 не упирается в лимит пикселей sharp. ?hazehash, ?blurhash и ?thumbhash для SVG возвращают пустую строку и печатают предупреждение со ссылкой на ?placeholder. Битый SVG не роняет сборку: плагин предупреждает и возвращает объявленный размер (или пустой объект). Битое растровое изображение по-прежнему падает с ошибкой.
Импорты на этапе сборки
Плагин также разрешает импорты с суффиксом запроса, так что вам никогда не нужно вручную настраивать пропы — метаданные попадают прямо в ваш JS на этапе сборки:
import meta from './photo.jpg?vik'
// → { src, srcset, webp, avif, width, height, placeholder, blurhash, thumbhash, name, src400, ... }
import hash from './photo.jpg?thumbhash'
// → 'base64string'Передавайте метаданные прямо в проп image компонента <VImage> — без ручной настройки полей:
<script setup lang="ts">
import meta from './hero.jpg?vik'
</script>
<template>
<VImage :image="meta" alt="Hero" />
</template>?vikизменяет размер/кодирует изображение вoutputи возвращает полную запись манифеста (URL используютpublicPath, точно как в сгенерированном манифесте). ThumbHash включается всегда.?placeholder(со списком полей),?hazehash,?blurhash,?thumbhash,?color,?size,?aspectи?previewвычисляют только данные плейсхолдера и не пишут файлы — см. Только плейсхолдеры и Выбор того, что считать.
Все они перезапускаются при изменении исходного изображения в dev. Требуется sharp; thumbhash требуется для вывода ThumbHash.
TypeScript — включите типизированные импорты ?vik / ?placeholder / ?hazehash / ?blurhash / ?thumbhash, один раз сославшись на встроенные декларации (например, в env.d.ts):
/// <reference types="@macrulez/vue-image-kit/vite/client" />Только плейсхолдеры, без изменения размеров
Если адаптивные варианты не нужны, а нужен только блюр на время загрузки, отключите пакетную обработку через generate: false. Плагин ничего не делает сам и только отвечает на импорты плейсхолдеров и на манифест плейсхолдеров, поэтому папка input может не существовать:
// vite.config.ts
vueImageKit({ generate: false })<script setup lang="ts">
import placeholder from './photo.jpg?placeholder'
</script>
<template>
<VImage src="/photo.jpg" v-bind="placeholder" alt="Photo" />
</template>?placeholder возвращает готовые для v-bind пропсы <VImage> — { hazehash, placeholderColor, width, height } (вместо hazehash — blurhash, если пакет не установлен), посчитанные при сборке по настоящему файлу. Какой хеш в них попадёт, задаёт значение:
?placeholder— HazeHash (BlurHash, если пакетhazehashне установлен илиmodeравенblurhash), доминирующий цвет и исходный размер.?placeholder=hazehash— явно HazeHash.?placeholder=blurhash— явно BlurHash.?placeholder=thumbhash— ThumbHash вместо BlurHash.?placeholder=color— только доминирующий цвет и размер.?hazehash/?blurhash/?thumbhash— только строка хеша,export default 'LJ9+E%}}…'.
Значения совпадают с теми, что для того же файла считает команда placeholders. При generate: false импорт ?vik по-прежнему работает и, если вы его используете, пишет свои варианты в output.
Выбор того, что считать
?placeholder принимает список полей, так что один импорт возвращает ровно то, что нужно:
import ph from './photo.jpg?placeholder=color,blurhash'
// → { blurhash: 'L6T9R{,YfQ,Y|cjtfQjtfQfQfQfQ', placeholderColor: '#fe0000' }
import all from './photo.jpg?placeholder=all&shape=raw'
// → { hazehash, blurhash, thumbhash, color, preview, size: { width, height }, aspect }Поля разделяются запятыми (пробелы тоже подходят), порядок любой, а поле, названное дважды, считается один раз:
hazehash— строка HazeHash (нужен пакетhazehash).blurhash— строка BlurHash.thumbhash— ThumbHash в base64.color— доминирующий цвет как#rrggbb(у изображения без единого непрозрачного пикселя цвета нет, и поле опускается).size— реальныеwidthиheight.preview— крошечный PNG в виде URIdata:image/png;base64,…, восстановленный из ThumbHash. Его можно сразу подставить вsrcили в CSSbackground, ничего не декодируя на странице.aspect—width / heightчислом, например2для изображения 200×100.all— все поля выше.
Возвращаются только перечисленные поля. Если <VImage> нужны width и height, добавьте и size. Старые одиночные значения сохраняют свою форму: ?placeholder, ?placeholder=hazehash, ?placeholder=blurhash, ?placeholder=thumbhash и ?placeholder=color по-прежнему возвращают хеш вместе с цветом и размером.
Форма результата
&shape=props (по умолчанию) использует имена пропсов <VImage>, поэтому работает <VImage v-bind="ph" />: color становится placeholderColor, preview — placeholder, size — width и height. aspect — не проп <VImage>, поэтому он пропускается с предупреждением. &shape=raw оставляет имена как в списке и возвращает size объектом, а aspect включает:
import raw from './photo.jpg?placeholder=color,size,aspect&shape=raw'
// → { color: '#fe0000', size: { width: 200, height: 100 }, aspect: 2 }По одному значению
У каждого поля есть и свой импорт, который возвращает голое значение:
import color from './photo.jpg?color' // '#fe0000'
import size from './photo.jpg?size' // { width: 200, height: 100 }
import aspect from './photo.jpg?aspect' // 2
import preview from './photo.jpg?preview' // 'data:image/png;base64,…'
import blur from './photo.jpg?blurhash' // 'L6T9R…'
import thumb from './photo.jpg?thumbhash' // '1fsDBI…'Значение, которое не удалось посчитать, приходит как '' (для ?aspect — 0, для ?size — 0×0). У ?size, ?color, ?preview и ?aspect флаг должен быть голым: ?size=large остаётся нетронутым, так что одноимённый параметр другого плагина не перехватывается.
Настройки для одного импорта
Любой из этих импортов принимает настройки из раздела настройка хешей только для этого файла:
components— компоненты BlurHash, по умолчанию4x3, каждая сторона 1–9.sample— размер, до которого изображение уменьшается перед хешированием, 8–256.strategy—dominant(по умолчанию) илиaverageдля цвета.
import hash from './photo.jpg?blurhash&components=6x4'
import ph from './photo.jpg?placeholder=blurhash,color&sample=64&strategy=average'Неверное значение печатает предупреждение, и используется значение по умолчанию. Настройки одного импорта никогда не затрагивают общий кэш и манифест плейсхолдеров.
Типы для списка
/// <reference types="@macrulez/vue-image-kit/vite/client" /> типизирует фиксированные импорты (?color, ?size, ?placeholder=color и т. д.). Список или импорт с настройками так не типизировать: в шаблоне модуля TypeScript допускает только одну *, и она уже нужна для пути к файлу. Пусть декларации напишет плагин:
vueImageKit({ types: true })Плагин запоминает каждый такой импорт, который встретил, и пишет src/vik-imports.d.ts (types: 'path/to/file.d.ts' выбирает другое место). Список типизируется свободно, с необязательными полями (hazehash?: string, blurhash?: string, placeholderColor?: string, …), поэтому порядок и набор полей не важны. Записи только добавляются и никогда не удаляются, поэтому dev-сервер, загрузивший лишь часть страниц, не урезает файл; чтобы пересоздать его, удалите файл. Пока импорт не встретился хотя бы раз, редактор сообщает о неизвестном модуле.
Примеры
Размытие и размер для одного изображения. size задаёт <VImage> его width и height, поэтому страница не прыгает, когда изображение загрузится:
<script setup lang="ts">
import photo from './assets/photo.jpg'
import ph from './assets/photo.jpg?placeholder=blurhash,size'
</script>
<template>
<VImage :src="photo" v-bind="ph" alt="Photo" />
</template>Готовое превью как CSS-фон. ?preview — это data URI крошечного PNG, так что на странице ничего не нужно декодировать:
<script setup lang="ts">
import hero from './assets/hero.jpg'
import preview from './assets/hero.jpg?preview'
</script>
<template>
<section class="hero" :style="{ backgroundImage: `url(${preview})` }">
<img :src="hero" alt="" loading="lazy" />
</section>
</template>Заранее зарезервировать место через соотношение сторон.
<script setup lang="ts">
import cover from './assets/card.jpg'
import aspect from './assets/card.jpg?aspect'
</script>
<template>
<div :style="{ aspectRatio: aspect }">
<img :src="cover" alt="" />
</div>
</template>Несколько значений сразу, под их собственными именами.
import raw from './assets/photo.jpg?placeholder=color,size,aspect&shape=raw'
const { color, size, aspect } = raw
console.log(color, size.width, size.height, aspect)Целая папка через import.meta.glob. Запрос — та же строка:
const placeholders = import.meta.glob('./assets/gallery/*.jpg', {
query: '?placeholder=blurhash,size',
import: 'default',
eager: true,
})Настройки только для одного изображения.
import hash from './assets/banner.jpg?blurhash&components=8x3'
import avg from './assets/banner.jpg?color&strategy=average'Типы для списков. Один раз подключите встроенные декларации, а остальное допишет плагин:
// vite.config.ts
vueImageKit({ generate: false, types: true })// env.d.ts
/// <reference types="@macrulez/vue-image-kit/vite/client" />SVG
У векторного изображения есть только color, size и aspect. Остальные поля пропускаются с предупреждением. См. SVG-изображения.
Параметры плейсхолдеров
Все настройки плейсхолдеров лежат под одним ключом, placeholders: в опциях Vite-плагина или Nuxt-модуля. Здесь они собраны вместе, с описанием, за что отвечает каждый; разделы ниже объясняют отдельные части подробнее.
В проекте на Vite
// vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { vueImageKit } from '@macrulez/vue-image-kit/vite'
export default defineConfig({
plugins: [
vue(),
vueImageKit({
generate: false,
types: true,
placeholders: {
mode: 'blurhash',
tuning: { components: [4, 3], sample: 100, color: 'dominant' },
imports: {
extensions: ['.png', '.jpg', '.jpeg', '.webp', '.avif'],
exclude: ['src/assets/sprites/'],
preview: ['src/assets/hero/', '**/cover-*.webp'],
},
dirs: ['public/images', { dir: 'src/img', urlPrefix: '/assets/img' }],
urls: ['https://cdn.example.com/hero.jpg'],
root: '.',
publicDir: 'public',
concurrency: 4,
timeout: 15000,
maxBytes: 15 * 1024 * 1024,
refreshRemote: false,
},
}),
],
})В проекте на Nuxt
Модуль сам регистрирует Vite-плагин, поэтому тот же объект placeholders кладётся под vueImageKit в nuxt.config.ts. generate: false выставляется за вас, а относительные пути считаются от корня Nuxt:
// nuxt.config.ts
export default defineNuxtConfig({
modules: ['@macrulez/vue-image-kit/nuxt'],
vueImageKit: {
placeholders: {
mode: 'blurhash',
tuning: { components: [4, 3], sample: 100, color: 'dominant' },
imports: {
extensions: ['.png', '.jpg', '.jpeg', '.webp', '.avif'],
exclude: ['src/assets/sprites/'],
preview: ['src/assets/hero/', '**/cover-*.webp'],
},
dirs: ['public/images', { dir: 'src/img', urlPrefix: '/assets/img' }],
urls: ['https://cdn.example.com/hero.jpg'],
manifest: './image-placeholders.ts',
},
},
})Всё сразу нужно редко. Минимальная полезная настройка — placeholders: { imports: true }; preview добавляйте только для картинок, которым нужен blur уже в HTML от сервера.
Опции Vite-плагина, которые здесь важны
generate—boolean· по умолчанию:true. Запускать пакетную обработкуinputвoutput.falseоставляет только возможности плейсхолдеров: плагин не трогает ни один файл, аinputможет не существовать. Nuxt-модуль всегда ставитfalseдля плагина плейсхолдеров.types—boolean | string· по умолчанию: выключено. Записать.d.tsдля импортов со списком полей или настройками;trueпишетsrc/vik-imports.d.ts, строка задаёт другой путь. См. Типизация списка.placeholders—object. Всё, что ниже.
placeholders
imports—boolean | object· по умолчанию: выключено. Считать плейсхолдер для каждого изображения, которое скрипт или однофайловый компонент импортирует, без запроса и правок шаблонов.trueберёт значения по умолчанию для трёх настроек ниже; объект их настраивает. См. Плейсхолдер для каждого импортируемого изображения.imports.extensions—string[]· по умолчанию:['.png', '.jpg', '.jpeg', '.webp', '.avif', '.gif', '.tif', '.tiff']. Какие типы файлов брать. SVG не берётся никогда.imports.exclude—string[]· по умолчанию:[]. Изображения, которые нужно пропустить. Список шаблонов путей.imports.preview—boolean | string[]· по умолчанию:false. Дополнительно сделать готовое превьюdata:и зарегистрировать его, чтобы<VImage ssr-placeholder>мог положить его в HTML от сервера.true— каждое импортируемое изображение; список шаблонов путей — только выбранные им. Нужен пакетthumbhash. См. Готовое превью для серверного рендеринга.
mode—'hazehash' | 'blurhash' | 'thumbhash' | 'color'· по умолчанию:'hazehash', если установлен пакетhazehash, иначе'blurhash'. Что несёт плейсхолдер кроме доминирующего цвета и размера: HazeHash, BlurHash, ThumbHash или ничего больше. Это режим автоматическихimports, голого импорта?placeholderи каждой записи манифеста.tuning—{ components?, sample?, color?, budget? }. Как считаются хеши и цвета: компоненты BlurHash (по умолчанию[4, 3]), размер, до которого уменьшается изображение перед хешированием (по умолчанию100), и'dominant'или'average'для цвета (по умолчанию'dominant'). См. Настройка хешей.dirs—(string | { dir, urlPrefix? })[]. Папки, изображения которых получают запись в манифесте плейсхолдеров (virtual:vue-image-kit/placeholders), для картинок, чейsrcстроится в рантайме.urlPrefix— URL, под которым папка отдаётся, если она лежит вне публичной директории.urls—string[]. Удалённые или CDN-изображения, которые скачиваются на этапе сборки и получают запись манифеста.manifest—string, только Nuxt. Файл манифеста (тот, что пишетnpx vue-image-kit placeholders) для слияния с папками; его записи главнее.root—string· по умолчанию: корень проекта. Директория, от которой считаются относительныеdirs. Nuxt ставит корень Nuxt. (Шаблоныexcludeиpreviewвсегда считаются от корня проекта Vite.)publicDir—string· по умолчанию: публичная директория Vite (public). Файлы внутри неё попадают в манифест под своим URL-путём.concurrency—number· по умолчанию:4. Сколько изображений обрабатывается параллельно.timeout—number· по умолчанию:15000. Сколько миллисекунд ждать удалённое изображение.maxBytes—number· по умолчанию:15728640(15 МБ). Удалённое изображение больше этого размера пропускается.refreshRemote—boolean· по умолчанию:false. Скачивать удалённые изображения заново, даже если есть копия в кэше.
Результаты кэшируются в node_modules/.cache/vue-image-kit/placeholders.json; локальный файл пересчитывается только при изменении времени правки или размера, а смена tuning сбрасывает кэш.
Плейсхолдер для каждого импортируемого изображения
Если проект импортирует свои изображения (import hero from './hero.webp' или просто src="@/assets/hero.webp" в шаблоне), включите imports — и у каждого из них при сборке появится плейсхолдер, без запроса и без правки каких-либо шаблонов:
// vite.config.ts
vueImageKit({
generate: false,
placeholders: { imports: true },
})// nuxt.config.ts
vueImageKit: {
placeholders: { imports: true },
}<script setup lang="ts">
import hero from '@/assets/hero.webp'
</script>
<template>
<VImage :src="hero" alt="Hero" />
</template><VImage> сам находит размытие и реальный размер. Плагин считает их по файлу, а затем регистрирует под значением, которое вернул импорт, — dev-URL или хешированный URL в продакшен-сборке, — поэтому поиск по src работает в dev, в сборке и при серверном рендеринге.
Что охвачено: default-импорты файлов .png, .jpg, .jpeg, .webp, .avif, .gif и .tif в скриптах и однофайловых компонентах, импорты, которые Vue сам генерирует из src="…" в шаблоне, и import.meta.glob(…, { eager: true }) (Vite разворачивает его в импорты). Не охвачено: SVG, импорты с запросом (?url), ленивые глобы (import()) и URL, собираемые во время выполнения. Для них импортируйте с ?placeholder или используйте манифест из папок.
Настройки идут рядом с imports:
placeholders: {
mode: 'thumbhash',
imports: {
extensions: ['.png', '.webp'],
exclude: ['/sprites/', 'canvas-'],
},
}mode—hazehash(по умолчанию, если установлен пакетhazehash),blurhash(по умолчанию в остальных случаях) илиthumbhash, та же опция, что и у остальных плейсхолдеров; дляthumbhashнужен пакетthumbhash.extensions— какие типы файлов брать.exclude— изображения, которые нужно пропустить, для тех, что никогда не показываются через<VImage>(например, спрайт для canvas). Принимает те же шаблоны путей, что иpreview.preview—true(каждое импортируемое изображение) или список шаблонов путей: дополнительно сделать готовое превьюdata:. См. Готовое превью для серверного рендеринга. По умолчанию выключено.
Битое изображение печатает предупреждение и просто остаётся без плейсхолдера; сборку оно не роняет. sharp должен быть установлен как dev-зависимость, а первая сборка считает каждое изображение один раз и хранит результат в том же кэше, что и остальные плейсхолдеры.
Выбор изображений по пути
exclude и preview принимают список шаблонов. Каждый шаблон сравнивается с настоящим путём файла относительно корня проекта (src/assets/hero/a.webp), поэтому неважно, как файл импортирован: @/assets/hero/a.webp, ~/assets/… и ../assets/… указывают на один и тот же путь. В dev-сервере берётся путь, который запрашивает браузер, без base.
- Директория — шаблон, заканчивающийся на
/:'src/assets/hero/'выбирает всё внутри этой директории на любой глубине. - Точный файл — полный относительный путь:
'src/assets/hero/cover.webp'. - Часть пути — любой другой текст ищется внутри пути:
'hero','-large','/sprites/'. - Glob — шаблон со
*сравнивается со всем путём целиком:*означает любые символы внутри имени одной директории,**— любое число директорий.'src/assets/*.png'выбирает PNG прямо вsrc/assets,'src/**/hero-*.webp'— подходящие файлы где угодно подsrc.
Ведущие ./ и / в шаблоне игнорируются. Если путь вычислить не удалось (импорт, который сборщик не может разрешить), шаблон сравнивается с текстом импорта как он записан.
Готовое превью для серверного рендеринга
Blur, который регистрирует imports, — это хеш: он декодируется в браузере, поэтому появляется только после запуска JavaScript. Для картинок, у которых blur должен быть уже в HTML от сервера, запросите ещё и готовое превью:
placeholders: {
imports: {
preview: ['src/assets/hero/', '**/cover-*.webp'],
},
}preview: true— превью для каждого импортируемого изображения.preview: ['src/assets/hero/', '**/cover-*.webp']— только для картинок, которые выбирают шаблоны: по директории, по точному файлу или по glob (см. Выбор изображений по пути). Так бандл остаётся небольшим.- не задано /
false— превью нет (по умолчанию).
Плагин рисует каждое превью (небольшой PNG как data: URL) и регистрирует его вместе с остальными полями, но само в HTML оно не попадает. Картинка просит об этом явно через ssrPlaceholder:
<VImage :src="hero" alt="Hero" ssr-placeholder />Тогда сервер отрендерит <img> с превью в качестве фона; любой <VImage> без пропса остаётся как был. Превью добавляет несколько килобайт на картинку в бандл (и в HTML страниц, где она используется), поэтому это отдельный переключатель, а для большого проекта список лучше, чем true.
Превью рисуется из ThumbHash, поэтому пакет thumbhash должен стоять как dev-зависимость, даже если mode равен blurhash. Для одной картинки без imports импортируйте превью напрямую — import preview from './hero.webp?preview' — и передайте как :placeholder="preview". См. Превью в серверном HTML.
Превью для серверного рендеринга: шаг за шагом
Установите зависимости. Превью рисуется из ThumbHash через
sharp, поэтому оба пакета нужны на этапе сборки, каким бы ни былmode:bashnpm install -D sharp thumbhashВключите превью в конфиге для тех картинок, которым оно нужно. В Vite:
ts// vite.config.ts vueImageKit({ generate: false, placeholders: { imports: { preview: ['src/assets/hero/'] }, }, })В Nuxt:
ts// nuxt.config.ts export default defineNuxtConfig({ modules: ['@macrulez/vue-image-kit/nuxt'], vueImageKit: { placeholders: { imports: { preview: ['src/assets/hero/'] }, }, }, })Именно
imports.previewзаставляет плагин сделать превью и сохранить его в реестре. Без негоssr-placeholderнечего показывать.Отметьте картинки, которые должны его показать, пропсом
ssr-placeholderу<VImage>. Изображение импортируется как обычно:vue<script setup lang="ts"> import hero from '@/assets/hero/cover.webp' </script> <template> <VImage :src="hero" alt="Cover" :width="1200" :height="600" ssr-placeholder /> </template>Перезапустите dev-сервер — опции модуля и плагина читаются при старте.
Проверьте HTML, который отдаёт сервер. У ленивой картинки вместо настоящего
srcпрозрачный пиксель, превью лежит фоном, а настоящее изображение — в<noscript>:html<img src="data:image/gif;base64,R0lGOD…" alt="Cover" width="1200" height="600" loading="lazy" style="background-image:url(data:image/png;base64,iVBOR…);background-size:cover;…" /> <noscript><img src="/_nuxt/cover.3f9a.webp" alt="Cover" width="1200" height="600" /></noscript>Если в
srcнастоящий файл, аbackground-imageнет, у картинки нет превью: проверьте, что файл подходит под шаблон вimports.preview, что установленthumbhashи что сервер перезапущен.
Какие картинки получают превью (конфиг) и какие <VImage> его используют (проп) — разные вещи намеренно: на этапе сборки плагин не знает, какой компонент получает какое изображение, а превью стоит несколько килобайт, поэтому оно делается только там, где вы о нём просите.
Манифест плейсхолдеров из папок
Задайте placeholders.dirs, и плагин посчитает манифест плейсхолдеров для каждого изображения в этих папках — в том числе для тех, чей src собирается во время выполнения. Манифест — это экспорт по умолчанию виртуального модуля virtual:vue-image-kit/placeholders:
vueImageKit({
generate: false,
placeholders: {
dirs: ['public/images', { dir: 'src/img', urlPrefix: '/assets/img' }],
urls: ['https://cdn.example.com/hero.jpg'],
mode: 'blurhash',
},
})import placeholders from 'virtual:vue-image-kit/placeholders'
app.use(VImageKitPlugin, { placeholders })dirs—(string | { dir, urlPrefix })[]. Папки, которые сканируются рекурсивно, пути — относительно корня проекта. Файл из публичной папки записывается по пути от неё; папке вне её нуженurlPrefix— без него файлы записываются по пути в проекте (/src/img/a.jpg), который совпадает только с URL dev-сервера, и сборка об этом предупредит.urls—string[]. Удалённые или CDN-изображения, они скачиваются во время сборки; CDN-адреса запрашиваются в уменьшенной версии.mode—'hazehash' | 'blurhash' | 'thumbhash' | 'color'· по умолчанию:hazehash, если пакет установлен, иначеblurhash. Что хранит каждая запись, кроме доминирующего цвета и размера. Это же значение по умолчанию для импорта?placeholderбез значения.tuning— см. Настройка хешей.publicDir,concurrency,timeout,maxBytes,refreshRemote— публичная папка (по умолчаниюpublic) и те же ограничения загрузки, что у командыplaceholders.
Модуль пересобирается, когда файл из dirs добавлен, удалён или изменён во время vite dev, а результаты кешируются в node_modules/.cache/vue-image-kit/placeholders.json — тот же кеш использует команда placeholders, — поэтому повторная сборка читает только изменившиеся изображения. Импорты ?placeholder, ?blurhash и ?thumbhash тоже используют этот кеш.
Тип модуля поставляется вместе с остальными декларациями @macrulez/vue-image-kit/vite/client.
Настройка хешей
Везде, где считается плейсхолдер, — импорты плагина ?placeholder/?blurhash/?thumbhash и его манифест, команда placeholders и опция Nuxt — принимается один и тот же объект tuning:
vueImageKit({
generate: false,
placeholders: {
dirs: ['public/images'],
tuning: { components: [6, 4], sample: 128, color: 'average' },
},
})components—[x, y]· по умолчанию:[4, 3]. Число компонент BlurHash по каждой оси, от 1 до 9. Больше компонент — больше деталей и длиннее строка.budget—number· по умолчанию:28. Размер строки HazeHash в байтах, 7–48. Для одного импорта —?hazehash&budget=16.sample—number· по умолчанию:100. Длиннейшая сторона в пикселях, до которой изображение уменьшается перед расчётом хеша; от 8 до 256. ThumbHash всегда считается не больше чем по 100px.color—'dominant' | 'average'· по умолчанию:'dominant'. Как выбирается цвет плейсхолдера: самый частый цвет или среднее по всем непрозрачным пикселям.
При смене настроек кеш сбрасывается, так что устаревший хеш не используется.
Обслуживание по запросу в dev-режиме
И CLI, и импорты на этапе сборки выше — это пакетная/заблаговременная обработка — они обрабатывают изображения до того, как их запросят. Если вы не хотите запускать шаг сборки вообще во время разработки, установите dev.onDemand: true, и изображения будут изменять размер по запросу, кэшируясь на диск после первого попадания:
vueImageKit({
dev: { onDemand: true }, // монтирует обработчик на /_vik/image во время `vite dev`
})<img src="/_vik/image?src=/photos/cat.jpg&w=800&format=webp" />Это работает только в dev — configureServer (хук Vite, который он использует) никогда не запускается во время vite build. Для продакшена без CDN смонтируйте тот же обработчик в своём собственном сервере — см. Самостоятельно размещаемый сервер по запросу.
Опции dev
Обработчик за dev.onDemand — тот же createImageHandler, что использует самостоятельный сервер — root фиксирован на собственном корне проекта Vite (server.config.root), всё остальное — та же поверхность настройки:
onDemand—boolean· по умолчанию:false. Монтирует обработчик во времяvite dev.route—string· по умолчанию:/_vik/image. Маршрут, на который монтируется.cacheDir—string· по умолчанию:<root>/.vik-cache. См. Самостоятельно размещаемый сервер по запросу → Опции.maxAge—number· по умолчанию:31536000(1 год).allowedWidths—number[], опционален. Ограничитьwстрого этими значениями.maxWidth—number· по умолчанию:4000. Верхняя граница дляw, когдаallowedWidthsне задан.