From b2429ef00e45c558625d340461542d0c488519ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Wed, 20 Oct 2021 11:52:23 -0400 Subject: [PATCH] refactor: meta/minifier use async/await --- src/meta/minifier.js | 248 +++++++++++++++++-------------------------- 1 file changed, 100 insertions(+), 148 deletions(-) diff --git a/src/meta/minifier.js b/src/meta/minifier.js index 4c1af4bab7..f388b3159e 100644 --- a/src/meta/minifier.js +++ b/src/meta/minifier.js @@ -73,36 +73,37 @@ function removeChild(proc) { } } -function forkAction(action, callback) { - const proc = getChild(); - - proc.on('message', (message) => { - freeChild(proc); - - if (message.type === 'error') { - return callback(message.message); - } +function forkAction(action) { + return new Promise((resolve, reject) => { + const proc = getChild(); + proc.on('message', (message) => { + freeChild(proc); + + if (message.type === 'error') { + return reject(new Error(message.message)); + } - if (message.type === 'end') { - callback(null, message.result); - } - }); - proc.on('error', (err) => { - proc.kill(); - removeChild(proc); - callback(err); - }); + if (message.type === 'end') { + resolve(message.result); + } + }); + proc.on('error', (err) => { + proc.kill(); + removeChild(proc); + reject(err); + }); - proc.send({ - type: 'action', - action: action, + proc.send({ + type: 'action', + action: action, + }); }); } const actions = {}; if (process.env.minifier_child) { - process.on('message', (message) => { + process.on('message', async (message) => { if (message.type === 'action') { const { action } = message; if (typeof actions[action.act] !== 'function') { @@ -112,121 +113,81 @@ if (process.env.minifier_child) { }); return; } - - actions[action.act](action, (err, result) => { - if (err) { - process.send({ - type: 'error', - message: err.stack || err.message || 'unknown error', - }); - return; - } - + try { + const result = await actions[action.act](action); process.send({ type: 'end', result: result, }); - }); + } catch (err) { + process.send({ + type: 'error', + message: err.stack || err.message || 'unknown error', + }); + } } }); } -function executeAction(action, fork, callback) { +async function executeAction(action, fork) { if (fork && (pool.length - free.length) < Minifier.maxThreads) { - forkAction(action, callback); - } else { - if (typeof actions[action.act] !== 'function') { - return callback(Error('Unknown action')); - } - actions[action.act](action, callback); + return await forkAction(action); } + if (typeof actions[action.act] !== 'function') { + throw new Error('Unknown action'); + } + return await actions[action.act](action); } -function concat(data, callback) { +actions.concat = async function concat(data) { if (data.files && data.files.length) { - async.mapLimit(data.files, 1000, (ref, next) => { - fs.readFile(ref.srcPath, 'utf8', (err, file) => { - if (err) { - return next(err); - } - - next(null, file); - }); - }, (err, files) => { - if (err) { - return callback(err); - } - - const output = files.join('\n;'); - fs.writeFile(data.destPath, output, callback); - }); - - return; + const files = await async.mapLimit(data.files, 1000, async ref => await fs.promises.readFile(ref.srcPath, 'utf8')); + const output = files.join('\n;'); + await fs.promises.writeFile(data.destPath, output); } +}; - callback(); -} -actions.concat = concat; - -function minifyJS_batch(data, callback) { - async.eachLimit(data.files, 100, (fileObj, next) => { - fs.readFile(fileObj.srcPath, 'utf8', (err, source) => { - if (err) { - return next(err); - } - - const filesToMinify = [ - { - srcPath: fileObj.srcPath, - filename: fileObj.filename, - source: source, - }, - ]; - minifyAndSave({ - files: filesToMinify, - destPath: fileObj.destPath, - filename: fileObj.filename, - }, next); - }); - }, callback); -} -actions.minifyJS_batch = minifyJS_batch; - -function minifyJS(data, callback) { - async.mapLimit(data.files, 1000, (fileObj, next) => { - fs.readFile(fileObj.srcPath, 'utf8', (err, source) => { - if (err) { - return next(err); - } - - next(null, { +actions.minifyJS_batch = async function minifyJS_batch(data) { + await async.eachLimit(data.files, 100, async (fileObj) => { + const source = await fs.promises.readFile(fileObj.srcPath, 'utf8'); + const filesToMinify = [ + { srcPath: fileObj.srcPath, filename: fileObj.filename, source: source, - }); - }); - }, (err, filesToMinify) => { - if (err) { - return callback(err); - } + }, + ]; - minifyAndSave({ + await minifyAndSave({ files: filesToMinify, - destPath: data.destPath, - filename: data.filename, - }, callback); + destPath: fileObj.destPath, + filename: fileObj.filename, + }); }); -} -actions.minifyJS = minifyJS; +}; -function minifyAndSave(data, callback) { +actions.minifyJS = async function minifyJS(data) { + const filesToMinify = await async.mapLimit(data.files, 1000, async (fileObj) => { + const source = await fs.promises.readFile(fileObj.srcPath, 'utf8'); + return { + srcPath: fileObj.srcPath, + filename: fileObj.filename, + source: source, + }; + }); + await minifyAndSave({ + files: filesToMinify, + destPath: data.destPath, + filename: data.filename, + }); +}; + +async function minifyAndSave(data) { const scripts = {}; data.files.forEach((ref) => { - if (!ref) { - return; + if (ref && ref.filename && ref.source) { + scripts[ref.filename] = ref.source; } - - scripts[ref.filename] = ref.source; }); const minified = uglify.minify(scripts, { @@ -239,66 +200,57 @@ function minifyAndSave(data, callback) { }); if (minified.error) { - return callback({ stack: `Error minifying ${minified.error.filename}\n${minified.error.stack}` }); + throw new Error(`Error minifying ${minified.error.filename}\n${minified.error.stack}`); } - - async.parallel([ - async.apply(fs.writeFile, data.destPath, minified.code), - async.apply(fs.writeFile, `${data.destPath}.map`, minified.map), - ], callback); + await Promise.all([ + fs.promises.writeFile(data.destPath, minified.code), + fs.promises.writeFile(`${data.destPath}.map`, minified.map), + ]); } Minifier.js = {}; -Minifier.js.bundle = function (data, minify, fork, callback) { - executeAction({ +Minifier.js.bundle = async function (data, minify, fork) { + return await executeAction({ act: minify ? 'minifyJS' : 'concat', files: data.files, filename: data.filename, destPath: data.destPath, - }, fork, callback); + }, fork); }; -Minifier.js.minifyBatch = function (scripts, fork, callback) { - executeAction({ +Minifier.js.minifyBatch = async function (scripts, fork) { + return await executeAction({ act: 'minifyJS_batch', files: scripts, - }, fork, callback); + }, fork); }; -function buildCSS(data, callback) { - less.render(data.source, { +actions.buildCSS = async function buildCSS(data) { + const lessOutput = await less.render(data.source, { paths: data.paths, javascriptEnabled: true, - }, (err, lessOutput) => { - if (err) { - // display less parser errors properly - return callback(new Error(String(err))); - } + }); - postcss(data.minify ? [ - autoprefixer, - clean({ - processImportFrom: ['local'], - }), - ] : [autoprefixer]).process(lessOutput.css, { - from: undefined, - }).then((result) => { - process.nextTick(callback, null, { code: result.css }); - }).catch((err) => { - process.nextTick(callback, err); - }); + const postcssArgs = [autoprefixer]; + if (data.minify) { + postcssArgs.push(clean({ + processImportFrom: ['local'], + })); + } + const result = await postcss(postcssArgs).process(lessOutput.css, { + from: undefined, }); -} -actions.buildCSS = buildCSS; + return { code: result.css }; +}; Minifier.css = {}; -Minifier.css.bundle = function (source, paths, minify, fork, callback) { - executeAction({ +Minifier.css.bundle = async function (source, paths, minify, fork) { + return await executeAction({ act: 'buildCSS', source: source, paths: paths, minify: minify, - }, fork, callback); + }, fork); }; require('../promisify')(exports);