mirror of
https://github.com/facebook/docusaurus.git
synced 2025-07-13 14:57:54 +02:00
refactor(v2): import lqip-loader, fix build on Node 13 (#2544)
This commit is contained in:
parent
6a20183a68
commit
980f1041dc
9 changed files with 344 additions and 41 deletions
77
packages/lqip-loader/src/index.js
Normal file
77
packages/lqip-loader/src/index.js
Normal file
|
@ -0,0 +1,77 @@
|
|||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
const loaderUtils = require('loader-utils');
|
||||
const lqip = require('./lqip');
|
||||
|
||||
module.exports = function (contentBuffer) {
|
||||
if (this.cacheable) {
|
||||
this.cacheable();
|
||||
}
|
||||
const callback = this.async();
|
||||
const imgPath = this.resourcePath;
|
||||
|
||||
const config = loaderUtils.getOptions(this) || {};
|
||||
config.base64 = 'base64' in config ? config.base64 : true;
|
||||
config.palette = 'palette' in config ? config.palette : false;
|
||||
|
||||
let content = contentBuffer.toString('utf8');
|
||||
const contentIsUrlExport = /^module.exports = "data:(.*)base64,(.*)/.test(
|
||||
content,
|
||||
);
|
||||
const contentIsFileExport = /^module.exports = (.*)/.test(content);
|
||||
|
||||
let source = '';
|
||||
const SOURCE_CHUNK = 1;
|
||||
|
||||
if (contentIsUrlExport) {
|
||||
source = content.match(/^module.exports = (.*)/)[SOURCE_CHUNK];
|
||||
} else {
|
||||
if (!contentIsFileExport) {
|
||||
// eslint-disable-next-line global-require
|
||||
const fileLoader = require('file-loader');
|
||||
content = fileLoader.call(this, contentBuffer);
|
||||
}
|
||||
source = content.match(/^module.exports = (.*);/)[SOURCE_CHUNK];
|
||||
}
|
||||
|
||||
const outputPromises = [];
|
||||
|
||||
if (config.base64 === true) {
|
||||
outputPromises.push(lqip.base64(imgPath));
|
||||
} else {
|
||||
outputPromises.push(null);
|
||||
}
|
||||
|
||||
// color palette generation is set to false by default
|
||||
// since it is little bit slower than base64 generation
|
||||
|
||||
if (config.palette === true) {
|
||||
outputPromises.push(lqip.palette(imgPath));
|
||||
} else {
|
||||
outputPromises.push(null);
|
||||
}
|
||||
|
||||
Promise.all(outputPromises)
|
||||
.then((data) => {
|
||||
if (data) {
|
||||
const [preSrc, palette] = data;
|
||||
const param1 = preSrc ? `, "preSrc": ${JSON.stringify(preSrc)}` : '';
|
||||
const param2 = palette ? `, "palette": ${JSON.stringify(palette)}` : '';
|
||||
const result = `module.exports = {"src":${source}${param1}${param2}};`;
|
||||
callback(null, result);
|
||||
} else {
|
||||
callback('ERROR', null);
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error(error);
|
||||
callback(error, null);
|
||||
});
|
||||
};
|
||||
|
||||
module.exports.raw = true;
|
75
packages/lqip-loader/src/lqip.js
Normal file
75
packages/lqip-loader/src/lqip.js
Normal file
|
@ -0,0 +1,75 @@
|
|||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
const Vibrant = require('node-vibrant');
|
||||
const path = require('path');
|
||||
const sharp = require('sharp');
|
||||
|
||||
const {version} = require('../package.json');
|
||||
const {toPalette, toBase64} = require('./utils');
|
||||
|
||||
const ERROR_EXT = `Error: Input file is missing or uses unsupported image format, lqip v${version}`;
|
||||
|
||||
const SUPPORTED_MIMES = {
|
||||
jpeg: 'image/jpeg',
|
||||
jpg: 'image/jpeg',
|
||||
png: 'image/png',
|
||||
};
|
||||
|
||||
const base64 = (file) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
let extension = path.extname(file) || '';
|
||||
extension = extension.split('.').pop();
|
||||
|
||||
if (!SUPPORTED_MIMES[extension]) {
|
||||
return reject(ERROR_EXT);
|
||||
}
|
||||
|
||||
return sharp(file)
|
||||
.resize(10)
|
||||
.toBuffer()
|
||||
.then((data) => {
|
||||
if (data) {
|
||||
return resolve(toBase64(SUPPORTED_MIMES[extension], data));
|
||||
}
|
||||
return reject(
|
||||
new Error('Unhandled promise rejection in base64 promise'),
|
||||
);
|
||||
})
|
||||
.catch((err) => {
|
||||
return reject(err);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
const palette = (file) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const vibrant = new Vibrant(file, {});
|
||||
vibrant
|
||||
.getPalette()
|
||||
.then((pal) => {
|
||||
if (pal) {
|
||||
return resolve(toPalette(pal));
|
||||
}
|
||||
return reject(
|
||||
new Error('Unhandled promise rejection in colorPalette', pal),
|
||||
);
|
||||
})
|
||||
.catch((err) => {
|
||||
return reject(err);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
process.on('unhandledRejection', (up) => {
|
||||
throw up;
|
||||
});
|
||||
|
||||
module.exports = {
|
||||
base64,
|
||||
palette,
|
||||
};
|
49
packages/lqip-loader/src/utils.js
Normal file
49
packages/lqip-loader/src/utils.js
Normal file
|
@ -0,0 +1,49 @@
|
|||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
const sortBy = require('lodash.sortby');
|
||||
|
||||
/**
|
||||
* toBase64
|
||||
* @description it returns a Base64 image string with required formatting
|
||||
* to work on the web (<img src=".." /> or in CSS url('..'))
|
||||
*
|
||||
* @param extension: image file extension
|
||||
* @param data: base64 string
|
||||
* @returns {string}
|
||||
*/
|
||||
const toBase64 = (extMimeType, data) => {
|
||||
return `data:${extMimeType};base64,${data.toString('base64')}`;
|
||||
};
|
||||
|
||||
/**
|
||||
* toPalette
|
||||
* @description takes a color swatch object, converts it to an array & returns
|
||||
* only hex color
|
||||
*
|
||||
* @param swatch
|
||||
* @returns {{palette: Array}}
|
||||
*/
|
||||
const toPalette = (swatch) => {
|
||||
let palette = Object.keys(swatch).reduce((result, key) => {
|
||||
if (swatch[key] !== null) {
|
||||
result.push({
|
||||
popularity: swatch[key].getPopulation(),
|
||||
hex: swatch[key].getHex(),
|
||||
});
|
||||
}
|
||||
return result;
|
||||
}, []);
|
||||
palette = sortBy(palette, ['popularity']);
|
||||
palette = palette.map((color) => color.hex).reverse();
|
||||
return palette;
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
toBase64,
|
||||
toPalette,
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue