mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-10-26 08:36:12 +01:00
refactor: meta/minifier use async/await
This commit is contained in:
@@ -73,36 +73,37 @@ function removeChild(proc) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function forkAction(action, callback) {
|
function forkAction(action) {
|
||||||
const proc = getChild();
|
return new Promise((resolve, reject) => {
|
||||||
|
const proc = getChild();
|
||||||
|
proc.on('message', (message) => {
|
||||||
|
freeChild(proc);
|
||||||
|
|
||||||
proc.on('message', (message) => {
|
if (message.type === 'error') {
|
||||||
freeChild(proc);
|
return reject(new Error(message.message));
|
||||||
|
}
|
||||||
|
|
||||||
if (message.type === 'error') {
|
if (message.type === 'end') {
|
||||||
return callback(message.message);
|
resolve(message.result);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
proc.on('error', (err) => {
|
||||||
|
proc.kill();
|
||||||
|
removeChild(proc);
|
||||||
|
reject(err);
|
||||||
|
});
|
||||||
|
|
||||||
if (message.type === 'end') {
|
proc.send({
|
||||||
callback(null, message.result);
|
type: 'action',
|
||||||
}
|
action: action,
|
||||||
});
|
});
|
||||||
proc.on('error', (err) => {
|
|
||||||
proc.kill();
|
|
||||||
removeChild(proc);
|
|
||||||
callback(err);
|
|
||||||
});
|
|
||||||
|
|
||||||
proc.send({
|
|
||||||
type: 'action',
|
|
||||||
action: action,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const actions = {};
|
const actions = {};
|
||||||
|
|
||||||
if (process.env.minifier_child) {
|
if (process.env.minifier_child) {
|
||||||
process.on('message', (message) => {
|
process.on('message', async (message) => {
|
||||||
if (message.type === 'action') {
|
if (message.type === 'action') {
|
||||||
const { action } = message;
|
const { action } = message;
|
||||||
if (typeof actions[action.act] !== 'function') {
|
if (typeof actions[action.act] !== 'function') {
|
||||||
@@ -112,121 +113,81 @@ if (process.env.minifier_child) {
|
|||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
actions[action.act](action, (err, result) => {
|
const result = await actions[action.act](action);
|
||||||
if (err) {
|
|
||||||
process.send({
|
|
||||||
type: 'error',
|
|
||||||
message: err.stack || err.message || 'unknown error',
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
process.send({
|
process.send({
|
||||||
type: 'end',
|
type: 'end',
|
||||||
result: result,
|
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) {
|
if (fork && (pool.length - free.length) < Minifier.maxThreads) {
|
||||||
forkAction(action, callback);
|
return await forkAction(action);
|
||||||
} else {
|
|
||||||
if (typeof actions[action.act] !== 'function') {
|
|
||||||
return callback(Error('Unknown action'));
|
|
||||||
}
|
|
||||||
actions[action.act](action, callback);
|
|
||||||
}
|
}
|
||||||
|
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) {
|
if (data.files && data.files.length) {
|
||||||
async.mapLimit(data.files, 1000, (ref, next) => {
|
const files = await async.mapLimit(data.files, 1000, async ref => await fs.promises.readFile(ref.srcPath, 'utf8'));
|
||||||
fs.readFile(ref.srcPath, 'utf8', (err, file) => {
|
const output = files.join('\n;');
|
||||||
if (err) {
|
await fs.promises.writeFile(data.destPath, output);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
callback();
|
actions.minifyJS_batch = async function minifyJS_batch(data) {
|
||||||
}
|
await async.eachLimit(data.files, 100, async (fileObj) => {
|
||||||
actions.concat = concat;
|
const source = await fs.promises.readFile(fileObj.srcPath, 'utf8');
|
||||||
|
const filesToMinify = [
|
||||||
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, {
|
|
||||||
srcPath: fileObj.srcPath,
|
srcPath: fileObj.srcPath,
|
||||||
filename: fileObj.filename,
|
filename: fileObj.filename,
|
||||||
source: source,
|
source: source,
|
||||||
});
|
},
|
||||||
});
|
];
|
||||||
}, (err, filesToMinify) => {
|
|
||||||
if (err) {
|
|
||||||
return callback(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
minifyAndSave({
|
await minifyAndSave({
|
||||||
files: filesToMinify,
|
files: filesToMinify,
|
||||||
destPath: data.destPath,
|
destPath: fileObj.destPath,
|
||||||
filename: data.filename,
|
filename: fileObj.filename,
|
||||||
}, callback);
|
});
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
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 = {};
|
const scripts = {};
|
||||||
data.files.forEach((ref) => {
|
data.files.forEach((ref) => {
|
||||||
if (!ref) {
|
if (ref && ref.filename && ref.source) {
|
||||||
return;
|
scripts[ref.filename] = ref.source;
|
||||||
}
|
}
|
||||||
|
|
||||||
scripts[ref.filename] = ref.source;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const minified = uglify.minify(scripts, {
|
const minified = uglify.minify(scripts, {
|
||||||
@@ -239,66 +200,57 @@ function minifyAndSave(data, callback) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (minified.error) {
|
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}`);
|
||||||
}
|
}
|
||||||
|
await Promise.all([
|
||||||
async.parallel([
|
fs.promises.writeFile(data.destPath, minified.code),
|
||||||
async.apply(fs.writeFile, data.destPath, minified.code),
|
fs.promises.writeFile(`${data.destPath}.map`, minified.map),
|
||||||
async.apply(fs.writeFile, `${data.destPath}.map`, minified.map),
|
]);
|
||||||
], callback);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Minifier.js = {};
|
Minifier.js = {};
|
||||||
Minifier.js.bundle = function (data, minify, fork, callback) {
|
Minifier.js.bundle = async function (data, minify, fork) {
|
||||||
executeAction({
|
return await executeAction({
|
||||||
act: minify ? 'minifyJS' : 'concat',
|
act: minify ? 'minifyJS' : 'concat',
|
||||||
files: data.files,
|
files: data.files,
|
||||||
filename: data.filename,
|
filename: data.filename,
|
||||||
destPath: data.destPath,
|
destPath: data.destPath,
|
||||||
}, fork, callback);
|
}, fork);
|
||||||
};
|
};
|
||||||
|
|
||||||
Minifier.js.minifyBatch = function (scripts, fork, callback) {
|
Minifier.js.minifyBatch = async function (scripts, fork) {
|
||||||
executeAction({
|
return await executeAction({
|
||||||
act: 'minifyJS_batch',
|
act: 'minifyJS_batch',
|
||||||
files: scripts,
|
files: scripts,
|
||||||
}, fork, callback);
|
}, fork);
|
||||||
};
|
};
|
||||||
|
|
||||||
function buildCSS(data, callback) {
|
actions.buildCSS = async function buildCSS(data) {
|
||||||
less.render(data.source, {
|
const lessOutput = await less.render(data.source, {
|
||||||
paths: data.paths,
|
paths: data.paths,
|
||||||
javascriptEnabled: true,
|
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);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
|
||||||
actions.buildCSS = buildCSS;
|
const postcssArgs = [autoprefixer];
|
||||||
|
if (data.minify) {
|
||||||
|
postcssArgs.push(clean({
|
||||||
|
processImportFrom: ['local'],
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
const result = await postcss(postcssArgs).process(lessOutput.css, {
|
||||||
|
from: undefined,
|
||||||
|
});
|
||||||
|
return { code: result.css };
|
||||||
|
};
|
||||||
|
|
||||||
Minifier.css = {};
|
Minifier.css = {};
|
||||||
Minifier.css.bundle = function (source, paths, minify, fork, callback) {
|
Minifier.css.bundle = async function (source, paths, minify, fork) {
|
||||||
executeAction({
|
return await executeAction({
|
||||||
act: 'buildCSS',
|
act: 'buildCSS',
|
||||||
source: source,
|
source: source,
|
||||||
paths: paths,
|
paths: paths,
|
||||||
minify: minify,
|
minify: minify,
|
||||||
}, fork, callback);
|
}, fork);
|
||||||
};
|
};
|
||||||
|
|
||||||
require('../promisify')(exports);
|
require('../promisify')(exports);
|
||||||
|
|||||||
Reference in New Issue
Block a user