Skip to content

Модуль Nuxt ​

hazehash-nuxt — модуль Nuxt, который регистрирует компонент PlaceholderImage и генерирует хеши ваших картинок при сборке, так что компоненту достаточно одного src. На сервере разметка содержит только средний цвет и соотношение сторон; в браузере размытое превью рисуется в canvas, а настоящая картинка плавно проявляется поверх него.

ts
// nuxt.config.ts
export default defineNuxtConfig({
  modules: ['hazehash-nuxt'],
})
vue
<template>
  <PlaceholderImage src="/images/hero.jpg" alt="Hero" :width="1600" :height="900" />
</template>

Модулю нужен Nuxt 3.9 или новее. Добавьте в проект sharp, чтобы можно было генерировать хеши:

bash
npm install hazehash-nuxt
npm install --save-dev sharp

Как это работает ​

  1. При сборке модуль сканирует указанные директории и кодирует каждую картинку через hazehash/node. Одновременно кодируются до четырёх картинок, а результат для каждого файла кэшируется вместе с его размером, временем изменения, бюджетом и профилем в node_modules/.cache/hazehash/manifest.json, так что неизменившиеся картинки повторно не кодируются.
  2. Манифест, объект вроде { "/images/hero.jpg": "Ed7UwRWKKv5znm6a7sC1tziHDNpMuCikxrYpIg" }, становится виртуальным модулем #hazehash/manifest. Ключ это URL-префикс директории, за которым идёт путь файла внутри неё.
  3. Зарегистрированный компонент ищет хеш по своему src, если проп hash не задан. Явно переданный хеш всегда главнее: так подключаются хеши из базы данных или CMS.
  4. В режиме разработки манифест пересоздаётся, когда картинка внутри сканируемой директории добавляется, меняется или удаляется.

Если sharp не установлен, сборка продолжается без хешей и выводит одно предупреждение ([hazehash] hash generation disabled). Картинка, которую не удалось декодировать, пропускается с предупреждением ([hazehash] skipped …), так что один битый файл никогда не ломает сборку.

Конфигурация ​

Опции задаются под ключом hazehash в nuxt.config.ts:

ts
export default defineNuxtConfig({
  modules: ['hazehash-nuxt'],
  hazehash: {
    componentName: 'PlaceholderImage',
    generate: true,
    dirs: [{ dir: 'public', prefix: '/' }],
    extensions: ['.jpg', '.jpeg', '.png', '.webp', '.avif', '.gif'],
    budget: 28,
    profile: 'default',
  },
})

componentName ​

string · по умолчанию: 'PlaceholderImage'

Имя, под которым регистрируется компонент, например 'HazeImage', чтобы избежать конфликта с вашим собственным компонентом.

generate ​

boolean · по умолчанию: true

Генерировать ли хеши при сборке. false отключает сканирование, манифест остаётся пустым, а sharp не нужен; используйте, когда каждому <PlaceholderImage> явно передаётся hash.

dirs ​

{ dir: string; prefix?: string }[] · по умолчанию: [{ dir: 'public', prefix: '/' }]

Директории для сканирования и URL-префикс их файлов в манифесте. dir задаётся относительно корня проекта, если путь не абсолютный, а сканирование рекурсивное. prefix по умолчанию '/'. Файл public/images/hero.jpg в директории по умолчанию получает ключ /images/hero.jpg, ровно тот src, который вы пишете в шаблоне.

ts
dirs: [
  { dir: 'public', prefix: '/' },
  { dir: 'media/photos', prefix: '/photos/' },
]

Вторая запись для папки, которую ваш сервер отдаёт под другим URL: media/photos/lake.jpg получает ключ /photos/lake.jpg.

extensions ​

string[] · по умолчанию: ['.jpg', '.jpeg', '.png', '.webp', '.avif', '.gif']

Расширения файлов, которые считаются изображениями; сравниваются без учёта регистра.

budget ​

number · по умолчанию: 28

Максимальное число байт в хеше. См. Выбор бюджета.

profile ​

'fast' | 'default' | 'high' · по умолчанию: 'default'

Насколько усердно энкодер ищет решение, как у encode().

Авто-импорты ​

useHazeHash(src) ​

ComputedRef<string | undefined>

Хеш, который модуль сгенерировал для URL картинки вроде /images/hero.jpg, либо undefined, если его нет. src может быть обычным значением, ref или геттером. Используйте с собственной разметкой:

vue
<script setup lang="ts">
const props = defineProps<{ src: string }>()
const hash = useHazeHash(() => props.src)
const { canvas, backgroundColor, aspectRatio } = usePlaceholder(hash)
</script>

usePlaceholder(hash, options?) ​

Composable из hazehash-vue, импортируемый автоматически для удобства. См. Состояние плейсхолдера.

Компонент ​

Компонент, который регистрирует модуль, это PlaceholderImage из hazehash-vue с одним дополнением: если hash не задан, он использует хеш, сгенерированный для src. Пропсы те же (hash, src, alt, width, height, size, fade).

Хеши из другого источника ​

Модуль подходит и проектам, которые хранят хеши в базе данных. Задайте generate: false и передавайте каждому компоненту его hash:

ts
hazehash: {
  generate: false,
}
vue
<PlaceholderImage
  :src="photo.url"
  :hash="photo.hash"
  :width="photo.width"
  :height="photo.height"
  alt=""
/>

Чтобы создать такие хеши, используйте команду hazehash или хелперы для Node.js.

Требования ​

Nuxt 3.9 или новее, Node.js 20+ и sharp в вашем проекте для генерации при сборке. Модуль сам транспилирует hazehash и hazehash-vue.