Skip to content

Instantly share code, notes, and snippets.

@takumifukasawa
Created March 5, 2021 09:17
Show Gist options
  • Save takumifukasawa/4c502098c62317987798f4ba57583dbb to your computer and use it in GitHub Desktop.
Save takumifukasawa/4c502098c62317987798f4ba57583dbb to your computer and use it in GitHub Desktop.
node: minify [jpg, png] images
// ------------------------------------------------------------------------------
//
// ディレクトリ以下の画像、もしくは単一ファイルを一括圧縮するバッチスクリプト
//
// usage:
// $ node minify-images.js [src_path]
//
// ------------------------------------------------------------------------------
const fs = require("fs");
const imagemin = require("imagemin");
const imageminJpegtran = require("imagemin-jpegtran");
const imageminPngquant = require("imagemin-pngquant");
const path = require("path");
if (!process.argv[2]) {
console.error('command: "node minify-images.js [src_path]"');
process.exit(1);
}
const srcPath = process.argv[2];
/**
* base: https://gist.github.com/victorsollozzo/4134793
* ファイルパスを再帰的に取得
*
* @param {*} base
* @param {*} extensions
* @param {*} files
* @param {*} result
* @returns
*/
function recursiveFindByExtensions(base, extensions, files, result) {
const tmpFiles = files || fs.readdirSync(base);
let tmpResult = result || [];
tmpFiles.forEach(function (file) {
const newBase = path.join(base, file);
if (fs.statSync(newBase).isDirectory()) {
tmpResult = recursiveFindByExtensions(
newBase,
extensions,
fs.readdirSync(newBase),
tmpResult
);
return;
}
for (let i = 0; i < extensions.length; i += 1) {
const ext = extensions[i];
if (file.substr(-1 * (ext.length + 1)) === `.${ext}`) {
tmpResult.push(newBase);
return;
}
}
});
return tmpResult;
}
/**
* promiseを直列実行
*
* @param {*} arr
* @returns
*/
function execPromiseInSequence(arr) {
return arr.reduce((chained, func) => chained.then(func), Promise.resolve());
};
/**
* 単一ファイルを圧縮する
*
*/
async function compressImage(srcFile) {
const destination = path.dirname(srcFile);
console.log("----------------------------------------------------");
console.log(`minify: ${srcFile}`);
await imagemin([srcFile], {
destination,
plugins: [
imageminJpegtran(),
imageminPngquant({
quality: [0.6, 0.8],
speed: 1,
}),
],
});
console.log("succeeded.");
}
/**
* 実行関数
*
*/
async function main() {
const isDir = fs.lstatSync(path.join(process.cwd(), srcPath)).isDirectory();
const srcFiles = isDir
? recursiveFindByExtensions(path.join(process.cwd(), srcPath), [
"png",
"jpg",
])
: [srcPath];
await execPromiseInSequence(
srcFiles.map((srcFile) => async () => compressImage(srcFile))
);
}
main();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment