Commit 7b99b8b3 authored by Philipp Nowinski's avatar Philipp Nowinski
Browse files

[FEATURE] make every async function return a promise and log correct execution times

parent 558f57a5
const hirestime = require('hirestime');
const Task = require('../task');
const sass = require('node-sass');
const fs = require('fs');
......@@ -27,47 +28,62 @@ module.exports = class Css extends Task {
* @override
*/
async run(_subTask = null) {
const steps = [];
this.getElapsed = hirestime();
if (_subTask) {
if (_subTask === 'qa') {
this._runQa();
} else if(_subTask === 'compile') {
this._runCompile();
} else if(_subTask === 'svg') {
this._svg();
steps.push(this._runQa());
} else if (_subTask === 'compile') {
steps.push(this._runCompile());
} else if (_subTask === 'svg') {
steps.push(this._svg());
} else {
this._logTaskNotDefined(`css:${_subTask}`);
}
} else {
if (this._config.cssPipeline.qa) {
this._runQa();
steps.push(this._runQa());
}
this._runCompile();
steps.push(this._runCompile());
}
await Promise.all(steps);
this._logger.info(`Task ${chalk.bold('css')} finished after ${this.getElapsed(hirestime.S)}s`);
}
/**
* Kicks off the compile task
*/
async _runCompile() {
await this._svg();
const files = await globby([
`${this._path}/${this._config.directories.sass}/*.scss`,
'!**/_*.scss'
]);
files.forEach(file => {
this._compile(file, this._getOutputPath(file));
});
return new Promise(async resolve => {
await this._svg();
const files = await globby([
`${this._path}/${this._config.directories.sass}/*.scss`,
'!**/_*.scss'
]);
const compilations = [];
files.forEach(file => {
compilations.push(this._compile(file, this._getOutputPath(file)));
});
await Promise.all(compilations);
resolve();
});
}
/**
* Kicks off the QA task
*/
async _runQa() {
const files = await globby([
`${this._path}/${this._config.directories.sass}/**/*.scss`
].concat(this._config.css.excludeFromQa));
files.forEach(file => {
this._qa(file);
return new Promise(async resolve => {
const files = await globby([
`${this._path}/${this._config.directories.sass}/**/*.scss`
].concat(this._config.css.excludeFromQa));
const qaSteps = [];
files.forEach(file => {
qaSteps.push(this._qa(file));
});
await Promise.all(qaSteps);
resolve();
});
}
......@@ -76,7 +92,7 @@ module.exports = class Css extends Task {
*
* @param {String} _fileName The name of the input file
*/
_getOutputPath(_fileName) {
_getOutputPath(_fileName) {
let newSuffix = this._config.cssPipeline.renameToDotMin
? '.min.css'
: '.css';
......@@ -101,56 +117,59 @@ module.exports = class Css extends Task {
* @param {String} _output The path to the output file
*/
async _compile(_input, _output) {
this._logger.displayBrowserSyncNotification('Compiling Sass – hang in there...');
const render = util.promisify(sass.render);
const sourceMapPath = this._getSourceMapsPath(_output);
let compiledSass;
try {
compiledSass = await render({
file: _input,
outFile: _output,
outputStyle: 'expanded',
sourceMap: this._config.cssPipeline.sourceMaps,
sourceMapEmbed: false,
precision: 8
});
} catch(_error) {
return this._logger.error(_error.stack);
}
return new Promise(async (_resolve, _reject) => {
this._logger.displayBrowserSyncNotification('Compiling Sass – hang in there...');
const render = util.promisify(sass.render);
const sourceMapPath = this._getSourceMapsPath(_output);
let compiledSass;
try {
compiledSass = await render({
file: _input,
outFile: _output,
outputStyle: 'expanded',
sourceMap: this._config.cssPipeline.sourceMaps,
sourceMapEmbed: false,
precision: 8
});
} catch (_error) {
return this._logger.error(_error.stack);
}
let cssString = this._imageDimensions(compiledSass.css.toString());
let cssString = this._imageDimensions(compiledSass.css.toString());
let postCssPlugins = [autoprefixer];
if (this._config.cssPipeline.cleanCss) {
postCssPlugins.push(postcssClean);
}
let postProcessedCss = await postcss(postCssPlugins).process(cssString, {
from: _input,
to: _output,
map: this._config.cssPipeline.sourceMaps ? {
prev: compiledSass.map.toString(),
inline: false,
annotation: path.join(path.relative(path.dirname(_output), path.dirname(sourceMapPath)), path.basename(sourceMapPath))
} : undefined
});
let postCssPlugins = [autoprefixer];
if (this._config.cssPipeline.cleanCss) {
postCssPlugins.push(postcssClean);
}
let postProcessedCss = await postcss(postCssPlugins).process(cssString, {
from: _input,
to: _output,
map: this._config.cssPipeline.sourceMaps ? {
prev: compiledSass.map.toString(),
inline: false,
annotation: path.join(path.relative(path.dirname(_output), path.dirname(sourceMapPath)), path.basename(sourceMapPath))
} : undefined
});
await this._writeFile(_output, postProcessedCss.css);
if (this._config.cssPipeline.sourceMaps) {
await this._writeFile(sourceMapPath, postProcessedCss.map);
}
const outFileName = path.basename(_output);
const mapFileName = path.basename(sourceMapPath);
await this._writeFile(_output, postProcessedCss.css);
if (this._config.cssPipeline.sourceMaps) {
await this._writeFile(sourceMapPath, postProcessedCss.map);
}
if (this._config.mode === 'dev') {
browserSync.reload([outFileName, mapFileName]);
}
const outFileName = path.basename(_output);
const mapFileName = path.basename(sourceMapPath);
this._logger.success(`Written ${chalk.white(outFileName)}`);
if (this._config.cssPipeline.sourceMaps) {
this._logger.success(`Written ${chalk.white(mapFileName)}`);
}
if (this._config.mode === 'dev') {
browserSync.reload([outFileName, mapFileName]);
}
this._logger.success(`Written ${chalk.white(outFileName)}`);
if (this._config.cssPipeline.sourceMaps) {
this._logger.success(`Written ${chalk.white(mapFileName)}`);
}
_resolve();
});
}
/**
......@@ -159,19 +178,23 @@ module.exports = class Css extends Task {
* @param {String} _input The path to the input file
*/
async _qa(_input) {
let file = fs.readFileSync(_input, "utf8");
postcss([
stylelint({
configBasedir: `${process.cwd()}/sgc-core/`
}),
reporter({
clearReportedMessages: true
})
]).process(file, {
from: _input,
syntax: scss
}).catch(error => {
this._logger.error(error.stack)
return new Promise(resolve => {
let file = fs.readFileSync(_input, "utf8");
postcss([
stylelint({
configBasedir: `${process.cwd()}/sgc-core/`
}),
reporter({
clearReportedMessages: true
})
]).process(file, {
from: _input,
syntax: scss
}).then(() => {
resolve();
}).catch(error => {
this._logger.error(error.stack)
});
});
}
......@@ -179,18 +202,21 @@ module.exports = class Css extends Task {
* Creates the inline-svg partial
*/
async _svg() {
const svgFolderPath = this._getFullPath(this._config.directories.svg);
if (fs.existsSync(svgFolderPath)) {
const svgPartial = await new InlineSvg(
svgFolderPath,
{
template: 'sgc-core/inline-svg-template.mustache'
}
);
const partialFilePath = path.join(this._getFullPath(this._config.directories.sass), '_svg.scss');
this._logger.success(`Ẁritten ${chalk.white(path.basename(partialFilePath))}`);
this._writeFile(partialFilePath, svgPartial);
}
return new Promise(async resolve => {
const svgFolderPath = this._getFullPath(this._config.directories.svg);
if (fs.existsSync(svgFolderPath)) {
const svgPartial = await new InlineSvg(
svgFolderPath,
{
template: 'sgc-core/inline-svg-template.mustache'
}
);
const partialFilePath = path.join(this._getFullPath(this._config.directories.sass), '_svg.scss');
this._logger.success(`Ẁritten ${chalk.white(path.basename(partialFilePath))}`);
await this._writeFile(partialFilePath, svgPartial);
}
resolve();
});
}
/**
......
const hirestime = require('hirestime');
const Task = require('../task');
const globby = require('globby');
const fs = require('fs');
......@@ -20,6 +21,7 @@ module.exports = class Watch extends Task {
* @override
*/
async run(_subTask) {
this.getElapsed = hirestime();
if (_subTask === 'uploaded') {
this._optimizeUploadedImages();
} else {
......@@ -33,7 +35,7 @@ module.exports = class Watch extends Task {
async _optimizeUploadedImages() {
this._config.images.optimize.forEach(async imagesPath => {
const files = await globby([`${imagesPath}/**/*.{png,jpg,gif,svg}`]);
this._optimize(files, imagesPath);
this._optimize(files);
});
}
......@@ -43,7 +45,8 @@ module.exports = class Watch extends Task {
async _optimizeExtensionImages() {
const imagesPath = this._getFullPath(this._config.directories.images);
const files = await globby([`${imagesPath}/**/*.{png,jpg,gif,svg}`]);
this._optimize(files, imagesPath);
await this._optimize(files);
this._logger.info(`Task ${chalk.bold('images')} finished after ${this.getElapsed(hirestime.S)}s`);
}
/**
......@@ -51,8 +54,15 @@ module.exports = class Watch extends Task {
*
* @param {Array} _files An array of filenames
*/
async _optimize(_files, _imagesPath) {
_files.forEach(async _image => {
async _optimize(_files) {
return new Promise(async (_resolve, _reject) => {
await Promise.all(_files.map(this._optimizeImage.bind(this)));
_resolve();
});
}
async _optimizeImage(_image) {
return new Promise(async resolve => {
let buffer = fs.readFileSync(_image);
let result = await imagemin.buffer(buffer, {
plugins: [
......@@ -69,9 +79,10 @@ module.exports = class Watch extends Task {
let saved = buffer.length - result.length;
info = `(saved ${prettyBytes(saved)} ~ ${Math.round((saved / buffer.length) * 100)}%)`;
}
let message = `${chalk.white(_image.replace(`${_imagesPath}/`, ''))} ${chalk.magenta(`${info}`)}`;
let message = `${chalk.white(_image.replace(`${this._getFullPath(this._config.directories.images)}/`, ''))} ${chalk.magenta(`${info}`)}`;
fs.writeFileSync(_image, result);
this._logger.success(message);
resolve();
});
}
}
const hirestime = require('hirestime');
const Task = require('../task');
const fs = require('fs');
const path = require('path');
......@@ -21,45 +22,57 @@ module.exports = class Js extends Task {
* @override
*/
async run(_subTask = null) {
this.getElapsed = hirestime();
const steps = [];
if (_subTask) {
// if _subTask is set, just execute that one task
if (_subTask === 'qa') {
this._runQa();
steps.push(this._runQa());
} else if(_subTask === 'compile') {
this._runCompile();
steps.push(this._runCompile());
} else {
this._logTaskNotDefined(`js:${_subTask}`);
}
} else {
// otherwise execute everything
if (this._config.jsPipeline.qa) {
this._runQa();
steps.push(this._runQa());
}
this._runCompile();
steps.push(this._runCompile());
}
await Promise.all(steps);
this._logger.info(`Task ${chalk.bold('js')} finished after ${this.getElapsed(hirestime.S)}s`);
}
/**
* Kicks off the compile task
*/
async _runCompile() {
const files = await globby([
`${this._path}/${this._config.directories.javascriptSrc}/*.js`
]);
files.forEach(file => {
this._compile(file, this._getOutputPath(file));
});
return new Promise(async resolve => {
const files = await globby([
`${this._path}/${this._config.directories.javascriptSrc}/*.js`
]);
const compilations = [];
files.forEach(file => {
compilations.push(this._compile(file, this._getOutputPath(file)));
});
await Promise.all(compilations);
resolve();
});
}
/**
* Kicks off the QA task
*/
async _runQa() {
const files = await globby([
`${this._path}/${this._config.directories.javascriptSrc}/**/*.js`,
'!**/*.min.js'
].concat(this._config.js.excludeFromQa));
this._qa(files);
return new Promise(async resolve => {
const files = await globby([
`${this._path}/${this._config.directories.javascriptSrc}/**/*.js`,
'!**/*.min.js'
].concat(this._config.js.excludeFromQa));
await this._qa(files);
resolve();
});
}
/**
......@@ -92,47 +105,52 @@ module.exports = class Js extends Task {
* @param {String} _output The path to the output file
*/
async _compile(_input, _output) {
const presetEnvConfiguration = this._config.jsPipeline.polyfills ? {
targets: {
browsers: this._config.supportedBrowsers
},
useBuiltIns: 'usage'
} : undefined;
try {
this._logger.displayBrowserSyncNotification('Compiling JS – hang in there...');
let relativeSourceMapPath
if (this._config.jsPipeline.sourceMaps) {
let sourceMapPath = this._getSourceMapsPath(_output);
relativeSourceMapPath = path.join(path.dirname(sourceMapPath), path.basename(sourceMapPath));
}
let bundler = browserify(_input, {
paths: this._config.js.libraryPaths,
debug: this._config.jsPipeline.sourceMaps
}).transform(babelify, {
presets: [
[require('@babel/preset-env'), presetEnvConfiguration],
]
}).bundle();
if (this._config.jsPipeline.uglify) {
bundler.pipe(minifyStream());
}
if (this._config.jsPipeline.sourceMaps) {
bundler.pipe(exorcist(
this._getSourceMapsPath(_output),
path.relative(path.dirname(_output), relativeSourceMapPath)
));
return new Promise(async resolve => {
const presetEnvConfiguration = this._config.jsPipeline.polyfills ? {
targets: {
browsers: this._config.supportedBrowsers
},
useBuiltIns: 'usage'
} : undefined;
try {
this._logger.displayBrowserSyncNotification('Compiling JS – hang in there...');
let relativeSourceMapPath
if (this._config.jsPipeline.sourceMaps) {
let sourceMapPath = this._getSourceMapsPath(_output);
relativeSourceMapPath = path.join(path.dirname(sourceMapPath), path.basename(sourceMapPath));
}
let bundler = browserify(_input, {
paths: this._config.js.libraryPaths,
debug: this._config.jsPipeline.sourceMaps
}).transform(babelify, {
presets: [
[require('@babel/preset-env'), presetEnvConfiguration],
]
}).bundle();
if (this._config.jsPipeline.uglify) {
bundler.pipe(minifyStream());
}
if (this._config.jsPipeline.sourceMaps) {
bundler.pipe(exorcist(
this._getSourceMapsPath(_output),
path.relative(path.dirname(_output), relativeSourceMapPath)
));
}
bundler.pipe(fs.createWriteStream(_output));
bundler.on('end', () => {
browserSync.reload('*.js');
this._logger.success(`Written ${chalk.white(path.basename(_output))}`);
resolve();
});
} catch(_error) {
this._logger.error(_error.stack);
}
bundler.pipe(fs.createWriteStream(_output));
browserSync.reload('*.js');
this._logger.success(`Written ${chalk.white(path.basename(_output))}`);
} catch(_error) {
this._logger.error(_error.stack);
}
});
}
/**
......@@ -141,14 +159,17 @@ module.exports = class Js extends Task {
* @param {Array} _files The array containing all src files
*/
async _qa(_files) {
let cli = new CLIEngine({
envs: ['browser'],
useEslintrc: true
return new Promise(resolve => {
let cli = new CLIEngine({
envs: ['browser'],
useEslintrc: true
});
let formatter = cli.getFormatter();
let report = cli.executeOnFiles(_files);
console.log(formatter(report.results));
resolve();
});
let formatter = cli.getFormatter();
let report = cli.executeOnFiles(_files);
console.log(formatter(report.results));
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment