Created
March 5, 2021 09:17
-
-
Save takumifukasawa/4c502098c62317987798f4ba57583dbb to your computer and use it in GitHub Desktop.
node: minify [jpg, png] images
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ------------------------------------------------------------------------------ | |
// | |
// ディレクトリ以下の画像、もしくは単一ファイルを一括圧縮するバッチスクリプト | |
// | |
// 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