222 lines
7.6 KiB
TypeScript
222 lines
7.6 KiB
TypeScript
import * as path from 'path'
|
|
import * as sharp from 'sharp'
|
|
import { sync as dir } from '@plastichub/fs/dir'
|
|
import { sync as exists } from '@plastichub/fs/exists'
|
|
|
|
import { files as _glob } from '@plastichub/osr-commons'
|
|
|
|
import { logger } from '../src'
|
|
|
|
const fg = require('fast-glob')
|
|
|
|
export const getFormats = (product, folder) => {
|
|
return [{
|
|
src: `${product}/${folder}/*.jpg`,
|
|
dist: `${product}/${folder}/webp`,
|
|
format: 'webp',
|
|
}];
|
|
}
|
|
/*
|
|
const updateImages = async (root, product_root, content) => {
|
|
// Feed the content into JSDOM
|
|
const dom = new JSDOM(content);
|
|
const document = dom.window.document;
|
|
|
|
// Find the image elements via `querySelectorAll`, replace this selector with your own custom one
|
|
const imageElems = document.querySelectorAll('img');
|
|
|
|
// If there are no matching elements, just return the original content :)
|
|
|
|
if (imageElems.length === 0) {
|
|
return content;
|
|
}
|
|
|
|
for (const imgElem of imageElems) {
|
|
// Get the `src` of the image element
|
|
const imgSrc = imgElem.getAttribute('src');
|
|
|
|
// Only add this transform for internal images
|
|
if (imgSrc.startsWith('https') || imgSrc.startsWith('http')) {
|
|
let srcSet = [];
|
|
|
|
// Replace all of the image sources with a new one that matches the results of the Sharp build
|
|
|
|
|
|
if (imgSrc.indexOf('.png') !== -1) {
|
|
continue;
|
|
}
|
|
if (imgSrc.indexOf('.png') !== -1) {
|
|
continue;
|
|
}
|
|
|
|
const parsed = URI.parse(decodeURIComponent(imgSrc));
|
|
const pParsed = path.parse(parsed.path);
|
|
const imageName = (url) => {
|
|
return decodeURIComponent(pParsed.base);
|
|
}
|
|
// const parts = url.parse(imgSrc);
|
|
// Get the metadata for the file and add it as the `${width}w` needed in defining a `srcset` in HTML for `<img>`
|
|
const name = imageName(imgSrc);
|
|
const _path = decodeURIComponent(parsed.path).replace('//', '');
|
|
const imageSrcPath = `${root}/${_path}`;
|
|
if (!exists(imageSrcPath)) {
|
|
console.log('image doesnt exists : ' + imageSrcPath + ' \n\t' + imgSrc);
|
|
return;
|
|
}
|
|
const imageSrcPathParts = path.parse(imageSrcPath);
|
|
|
|
const imgSrc80 = imgSrc.replace(name, '80/' + name);
|
|
const imgSrc60 = imgSrc.replace(name, '60/' + name);
|
|
const imgSrc40 = imgSrc.replace(name, '40/' + name);
|
|
const imgSrc20 = imgSrc.replace(name, '20/' + name);
|
|
|
|
const _set = (res) => {
|
|
return path.resolve(imageSrcPathParts.dir + '/' + res + '/' + name);
|
|
}
|
|
|
|
if (!exists(_set(80))) {
|
|
console.error('doesnt exists ', _set(80), imgSrc);
|
|
continue;
|
|
}
|
|
|
|
if (!exists(_set(60))) {
|
|
console.error('doesnt exists ', _set(60), imgSrc);
|
|
continue;
|
|
}
|
|
if (!exists(_set(40))) {
|
|
console.error('doesnt exists ', _set(40), imgSrc);
|
|
continue;
|
|
}
|
|
if (!exists(_set(20))) {
|
|
console.error('doesnt exists ', _set(20), imgSrc);
|
|
continue;
|
|
}
|
|
|
|
const img80 = await sharp(_set(80));
|
|
const md80 = await img80.metadata();
|
|
srcSet.push(`${imgSrc80.replace(/\s/g,'%20')} ${md80.width}w`);
|
|
|
|
// Repeat
|
|
const img60 = await sharp(_set(60));
|
|
const md60 = await img60.metadata();
|
|
srcSet.push(`${imgSrc60.replace(/\s/g,'%20')} ${md60.width}w`);
|
|
|
|
// Repeat
|
|
const img40 = await sharp(_set(40));
|
|
const md40 = await img40.metadata();
|
|
srcSet.push(`${imgSrc40.replace(/\s/g,'%20')} ${md40.width}w`);
|
|
|
|
// Repeat
|
|
const img20 = await sharp(_set(20));
|
|
const md20 = await img20.metadata();
|
|
srcSet.push(`${imgSrc20.replace(/\s/g,'%20')} ${md20.width}w`);
|
|
|
|
// Join the `srcset` into a string. that can be added to the `<img>` tag
|
|
srcSet = srcSet.join(', ');
|
|
// Set the `srcset` attribute
|
|
imgElem.setAttribute('srcset', srcSet);
|
|
// Find the new `src` for the WebP image
|
|
|
|
let webpSrc = imgSrc.replace(name, 'webp/' + encodeURIComponent(name)).replace('.png', '.webp').replace('.jpg', '.webp');
|
|
|
|
// const webpSrc = imgSrc
|
|
// .replace('/images/', '/images/webp/')
|
|
// .replace('.png', '.webp');
|
|
// Create a separate `source` element for the WebP with feature detection via `type`
|
|
|
|
const webpElement = document.createElement('source');
|
|
webpElement.setAttribute('srcset', webpSrc);
|
|
webpElement.setAttribute('type', 'image/webp');
|
|
|
|
// Wrap the `<img>` and the `<source>` into one `<picture>` tag in order for it to work
|
|
|
|
const pictureElement = document.createElement('picture');
|
|
pictureElement.appendChild(webpElement);
|
|
pictureElement.appendChild(imgElem.cloneNode());
|
|
|
|
// Replace the `<img>` with the `<picture>`
|
|
|
|
imgElem.replaceWith(pictureElement);
|
|
}
|
|
}
|
|
return document.documentElement.outerHTML;
|
|
}
|
|
*/
|
|
|
|
export const format = (formats) => {
|
|
return formats.forEach((format) => {
|
|
if (!exists(format.dist)) {
|
|
dir(format.dist)
|
|
}
|
|
|
|
// Find all files matching the glob patterns specified in `src`
|
|
let _files = fg.sync(format.src)
|
|
|
|
_files.forEach((file) => {
|
|
let filename = path.basename(file);
|
|
if (exists(path.resolve(`${format.dist}/${filename.replace('jpg', format.format)}`))) {
|
|
return;
|
|
}
|
|
|
|
const image = sharp(file);
|
|
|
|
// Convert to WebP via Sharp's inferencing automatically of extensions
|
|
image
|
|
.toFile(`${format.dist}/${filename.replace('jpg', format.format)}`)
|
|
.catch((err) => {
|
|
console.log(err);
|
|
});
|
|
});
|
|
});
|
|
}
|
|
|
|
export const getResizePatterns = (product, folder) => {
|
|
return [{
|
|
src: `${product}/${folder}/*.jpg`,
|
|
dist: `${product}/${folder}/80`,
|
|
percent: 80,
|
|
},
|
|
{
|
|
src: `${product}/${folder}/*.jpg`,
|
|
dist: `${product}/${folder}/60`,
|
|
percent: 60,
|
|
},
|
|
{
|
|
src: `${product}/${folder}/*.jpg`,
|
|
dist: `${product}/${folder}/40`,
|
|
percent: 40,
|
|
},
|
|
{
|
|
src: `${product}/${folder}/*.jpg`,
|
|
dist: `${product}/${folder}/20`,
|
|
percent: 20,
|
|
},
|
|
];
|
|
}
|
|
|
|
const resize = (patterns) => {
|
|
return patterns.forEach((resize) => {
|
|
if (!exists(resize.dist)) {
|
|
dir(resize.dist)
|
|
}
|
|
let _files = fg.sync(resize.src)
|
|
_files.forEach((file) => {
|
|
let filename = path.basename(file)
|
|
const image = sharp(file)
|
|
if (exists(`${resize.dist}/${filename}`)) {
|
|
return
|
|
}
|
|
image
|
|
.metadata()
|
|
.then((metadata) => {
|
|
return image
|
|
.resize(Math.round(metadata.width * (resize.percent / 100)))
|
|
.png()
|
|
.toFile(`${resize.dist}/${filename}`)
|
|
.catch(logger.error);
|
|
})
|
|
.catch(logger.error)
|
|
})
|
|
})
|
|
}
|