#StackBounty: #node.js #gulp #imagemin #gulp-imagemin Gulp Imagemin "MaxBufferError: stdout maxBuffer exceeded" when I try to…

Bounty: 50

Gulp Imagemin errors MaxBufferError: stdout maxBuffer exceeded when I try to minify a large amount of files (230). It will run the task if I minify 40-50 files at a time.

How do Increase the buffer? Or stop the task discontinuing?

node version 14.5,
gulp version 4.0.2,
gulp-imagemin version 7.1.0.

function imageMin(done) {
 // Locate unprocessed images
return gulp.src('./src/assets/images/*')
 // Optimise images and reduce file size, use gulp-cache to stop repeating
.pipe(cache(imagemin([
    imagemin.gifsicle({interlaced: true, optimizationLevel: 3,}), // 1 to 3
    imagemin.mozjpeg({quality: 90, progressive: true,}),
    imagemin.optipng({optimizationLevel: 5,}), // 0 to 7
    imagemin.svgo({
        plugins: [{cleanupIDs: false,}]
        })
    ],
    // Shows files optimastion results in the terminal
    {verbose: true } 
)))
// Send optimised images to folder
.pipe(gulp.dest('./dist/assets/images')),
done();
}


Get this bounty!!!

#StackBounty: #css #sass #gulp Gulp compiling sass out of order

Bounty: 50

I’m having issues with Gulp compiling my sass out of the order that I’m dictating in my sass files.

Here’s an example of my file structure for one of my sass components:
enter image description here

Within my general-page.scss file, I compile _desktop.scss, _mobile.scss and _tablet.scss in this order:

@import 'mobile';

@media ($bp-tablet) {
  @import 'tablet';
}

@media ($bp-desktop) {
  @import 'desktop';
}

However, in my styles.css, it’s injecting my _tablet.scss after my _desktop.scss, which is causing my tablet breakpoint to override my desktop breakpoint.

@media (min-width:1140px) {
    .node--type-general-page .hero-headings h1 {
        font-size: 3em
    }
    .node--type-general-page .hero-headings .subhead {
        font-size: 1.3em
    }
    .node--type-general-page .hero,
    .node--type-general-page .hero-background,
    .node--type-general-page .hero-background img {
        height: 250px
    }
}
@media (min-width:768px) {
    .node--type-general-page .hero,
    .node--type-general-page .hero-background,
    .node--type-general-page .hero-background img {
        height: 220px
    }
}

Here’s my gulp file:

// Initialize modules
const { src, dest, watch, series, parallel } = require('gulp');
const autoprefixer = require('autoprefixer');
const cssnano = require('cssnano');
const concat = require('gulp-concat');
const postcss = require('gulp-postcss');
const sass = require('gulp-sass');
const sourcemaps = require('gulp-sourcemaps');
const uglify = require('gulp-uglify');

// File path variables
const files = {
    scssPath: 'app/styles.scss',
    scssSubPaths: 'app/**/*.scss',
    jsPath: 'app/js/*.js'
}

// Sass task
function scssTask(){
    return src(files.scssPath)
        .pipe(sourcemaps.init())
        .pipe(sass())
        .pipe(postcss([ autoprefixer(), cssnano() ]))
        .pipe(sourcemaps.write('.'))
        .pipe(dest('dist')
    );
}

// JS task
function jsTask(){
    return src(files.jsPath)
        .pipe(concat('all.js'))
        .pipe(uglify())
        .pipe(dest('dist')
    );
}

// Watch task
function watchTask(){
    watch([files.scssPath, files.scssSubPaths, files.jsPath],
        parallel(scssTask, jsTask)
    );
}

// Default task
exports.default = series(
    parallel(scssTask, jsTask),
    watchTask);

Am I doing something wrong?

UPDATE: Oddly, we’ve had no issues with our other sass components. For example, we tested another component, nested at the same level as the general-page component. Gulp compiled that component in the correct order. We’ve run through the code numerous times, but there’s no obvious reason why this component is being compiled out of order. It follows the exact same structure as our other components.


Get this bounty!!!

#StackBounty: #node.js #typescript #gulp Depending on completion of multiple parallel gulp tasks

Bounty: 100

I have a complex NodeJS application, composed from several yarn workspace packages. The following gulpconfig.ts file defines a gulp build task for the entire set of packages:

import { series, parallel, TaskFunction, src, dest } from 'gulp';
import gulpTslint from 'gulp-tslint';
import { createProject } from 'gulp-typescript';
import tslint, { Linter } from 'tslint';
import { resolve } from 'path';
import { DestOptions } from 'vinyl-fs';
import { exec } from 'child_process';
import { promisify } from 'util';

const execPromise = promisify(exec);

interface GulpTasks {
  [key: string]: TaskFunction;
}

type TaskFunctionCallback = (error?: any) => void;

class Project {
  public projectFiles: NodeJS.ReadWriteStream;
  public constructor(
    public readonly projectDirectory: string,
    public readonly sourcemaps: boolean = false,
  ) {
    this.projectFiles = src('./src/**/*.ts', { cwd: projectDirectory, sourcemaps });
  }

  public lint(): this {
    this.projectFiles = this.projectFiles.pipe(
      gulpTslint({
        tslint,
        configuration: resolve(__dirname, 'tslint.json'),
        program: Linter.createProgram(
          resolve(this.projectDirectory, 'tsconfig.json'),
          this.projectDirectory,
        ),
      }),
    );

    return this;
  }

  public build(): this {
    const opts: DestOptions = {};
    if (this.sourcemaps) {
      opts.sourcemaps = true;
    }
    this.projectFiles = this.projectFiles
      .pipe(createProject(resolve(this.projectDirectory, 'tsconfig.build.json'))())
      .pipe(dest(resolve(this.projectDirectory, 'dist'), opts));

    return this;
  }
}

const buildDatabase = (cb: TaskFunctionCallback): NodeJS.ReadWriteStream =>
  new Project(resolve(__dirname, 'server/database')).build().projectFiles;

const buildSharedCommon = (cb: TaskFunctionCallback): NodeJS.ReadWriteStream =>
  new Project(resolve(__dirname, 'shared/common')).lint().build().projectFiles;
const buildSharedFrontoffice = (cb: TaskFunctionCallback): NodeJS.ReadWriteStream =>
  new Project(resolve(__dirname, 'shared/frontoffice')).lint().build().projectFiles;
const buildSharedBackoffice = (cb: TaskFunctionCallback): NodeJS.ReadWriteStream =>
  new Project(resolve(__dirname, 'shared/backoffice')).lint().build().projectFiles;

const buildClientCommon = (cb: TaskFunctionCallback): NodeJS.ReadWriteStream =>
  new Project(resolve(__dirname, 'client/common')).lint().build().projectFiles;
const buildClientFrontoffice = async (cb: TaskFunctionCallback): Promise<unknown> =>
  execPromise('yarn run build', { cwd: 'client/frontoffice' });
const buildClientBackoffice = async (cb: TaskFunctionCallback): Promise<unknown> =>
  execPromise('yarn run build', { cwd: 'client/backoffice' });

const buildServerCommon = (cb: TaskFunctionCallback): NodeJS.ReadWriteStream =>
  new Project(resolve(__dirname, 'server/common')).lint().build().projectFiles;
const buildServerFrontoffice = (cb: TaskFunctionCallback): NodeJS.ReadWriteStream =>
  new Project(resolve(__dirname, 'server/frontoffice')).lint().build().projectFiles;
const buildServerBackoffice = (cb: TaskFunctionCallback): NodeJS.ReadWriteStream =>
  new Project(resolve(__dirname, 'server/backoffice')).lint().build().projectFiles;

const tasks: GulpTasks = {
  build: parallel(
    buildDatabase,
    series(
      buildSharedCommon,
      parallel(buildSharedBackoffice, buildSharedFrontoffice),
      parallel(
        series(buildClientCommon, parallel(buildClientFrontoffice, buildClientBackoffice)),
        series(buildServerCommon, parallel(buildServerFrontoffice, buildServerBackoffice)),
      ),
    ),
  ),
};

export = tasks;

Because of how my application is structured, the buildServerCommon depends on buildDatabase. The buildDatabase however doesn’t depend on anything, and takes a long time, which is why I start it in parallel with the rest.

With the setup above though, buildDatabase may (and does) finish later than buildServerCommon starts.

How can I make buildServerCommon start only after buildDatabase and buildSharedCommon, but still have everything else start as early as possible?

Basically, in my dependency tree:

  • I have “client”, “server” and “shared” package folders.
  • “{client,server,shared}/common” is required by the “frontoffice” and “backoffice” packages in that same package folder.
  • “shared/{common,frontoffice,backoffice}” is required by both the “client” and “server” of the respective package.
  • “server/database” is special, in that it only exists in “server”, and is required by “server/common”.

I tried to use

const tasks: GulpTasks = {
  build: series(
    parallel(buildSharedCommon, buildDatabase),
    parallel(buildServerCommon, buildSharedFrontoffice, buildSharedBackoffice),
    parallel(
      series(buildClientCommon, parallel(buildClientFrontoffice, buildClientBackoffice)),
      parallel(buildServerFrontoffice, buildServerBackoffice),
    ),
  ),
};

but that isn’t optimal, since buildSharedFrontoffice and buildSharedBackoffice are not being compiled until buildDatabase is done, and from there the client is also needlessly delayed.


Get this bounty!!!

#StackBounty: #javascript #build #gulp #gulp-watch #gulp-4 How to get Gulp watch working after migration from v3 to v4?

Bounty: 50

I have an app with a very moderate gulpfile. I’ve just upgraded Gulp from v3.9.1 to v4.0.2 and adapted the gulpfile.js. All tasks are working fine again, only the watching is not.

There are no errors, but Gulp watch seems not to be checking the defined files for changes:

$ gulp
[11:39:34] Using gulpfile /var/www/.../my-app/gulpfile.js
[11:39:34] Starting 'default'...
[11:39:34] Starting 'run'...
[11:39:34] Starting 'build-less'...
[11:39:34] Finished 'build-less' after 16 ms
[11:39:34] Starting 'build-vendors'...
[11:39:34] Finished 'build-vendors' after 5.5 ms
[11:39:34] Finished 'run' after 23 ms
[11:39:34] Starting 'watch-files'...
[11:39:34] Starting 'watchFiles'...

How to get Gulp watch working for Gulp v4?


Here is my original gulpfile.js for Gulp v3:

/**
 * Gulp File
 *
 * run `gulp run && gulp watch-files` on the command line
 */

// Include Gulp plugins
var gulp = require('gulp'),
    less = require('gulp-less'),
    watch = require('gulp-watch'),
    prefix = require('gulp-autoprefixer'),
    plumber = require('gulp-plumber'),
    filter = require('gulp-filter'),
    rename = require('gulp-rename'),
    path = require('path')
;

// Compile LESS to CSS
gulp.task('build-less', function() {
    const fileFilter = filter(['**/*', '!**/mixins.less', '!**/variables.less']);
    gulp.src('./public/less/*.less') // path to less file
        .pipe(fileFilter)
        .pipe(plumber())
        .pipe(less())
        .pipe(gulp.dest('./public/css/')) // path to css directory
    ;
});

// Get vendors' code
gulp.task('build-vendors', function() {
    gulp.src(['./public/components/bootstrap/less/theme.less', './public/components/bootstrap/less/bootstrap.less']) // path to less file
        .pipe(plumber())
        .pipe(less())
        .pipe(rename(function (path) {
            //rename all files except 'bootstrap.css'
            if (path.basename + path.extname !== 'bootstrap.css') {
                path.basename = 'bootstrap-' + path.basename;
            }
        }))
        .pipe(gulp.dest('./public/css')) // path to css directory
    ;
});

// Run the build process
gulp.task('run', ['build-less', 'build-vendors']);

// Watch all LESS files, then run build-less
gulp.task('watch', function() {
    gulp.watch('public/less/*.less', ['run'])
});

// Default will run the 'entry' task
gulp.task('default', ['watch', 'run']);

Here is the new variant for Gulp v4:

/**
 * Gulp File
 *
 * run `gulp run && gulp watch-files` on the command line
 */

// Include Gulp plugins
var gulp = require('gulp'),
    less = require('gulp-less'),
    watch = require('gulp-watch'),
    prefix = require('gulp-autoprefixer'),
    plumber = require('gulp-plumber'),
    filter = require('gulp-filter'),
    rename = require('gulp-rename'),
    path = require('path')
;

// Compile LESS to CSS
function buildLess(done) {
    const fileFilter = filter(['**/*', '!**/mixins.less', '!**/variables.less']);
    gulp.src('./public/less/*.less') // path to less file
        .pipe(fileFilter)
        .pipe(plumber())
        .pipe(less())
        .pipe(gulp.dest('./public/css/')) // path to css directory
    ;
    done();
};

// Get vendors' code
function buildVendors(done) {
    gulp.src(['./public/components/bootstrap/less/theme.less', './public/components/bootstrap/less/bootstrap.less']) // path to less file
        .pipe(plumber())
        .pipe(less())
        .pipe(rename(function (path) {
            //rename all files except 'bootstrap.css'
            if (path.basename + path.extname !== 'bootstrap.css') {
                path.basename = 'bootstrap-' + path.basename;
            }
        }))
        .pipe(gulp.dest('./public/css')) // path to css directory
    ;
    done();
};

// Watch all LESS files, then run build-less
function watchFiles() {
    return gulp.watch(['public/less/*.less'], gulp.series('build-less'));
};

gulp.task('build-less', buildLess);
gulp.task('build-vendors', buildVendors);
gulp.task('run', gulp.series('build-less', 'build-vendors'));
gulp.task('watch-files', gulp.series(watchFiles));
gulp.task('default', gulp.series('run', 'watch-files'));


Get this bounty!!!

#StackBounty: #gulp Change gulp task structure to match Gulp v4

Bounty: 100

Gulp.js 4 gulpfile.js configuration files are not compatible with those developed for version 3. How to update gulp tasks?

///// Plugin Includes /////
var gulp = require('gulp'),
        uglify = require('gulp-uglify'),
        plumber = require('gulp-plumber'),
        concat = require('gulp-concat'),
        jshint = require('gulp-jshint'),
        autoprefixer = require('gulp-autoprefixer'),
        browserSync = require('browser-sync'),
        reload = browserSync.reload,
        sass = require('gulp-sass');

///// Compile/Validate JS /////
function js(){
    gulp.src('./assets/js/main.js')
    .pipe(plumber())
    .pipe(jshint())
    .pipe(jshint.reporter('default', { verbose: true }))
    .pipe(concat('main.min.js'))
    .pipe(uglify())
    .pipe(gulp.dest('./js/dist/'))
};

///// Compile Sass /////
function sass(){
    gulp.src('./assets/scss/style.scss')
    .pipe(plumber())
    .pipe(sass().on('error', sass.logError))
    .pipe(sass( {outputStyle: 'compressed'} ))
    .pipe(autoprefixer('last 2 versions'))
    .pipe(gulp.dest('./'))
    .pipe(browserSync.stream())
};

///// Get PHP /////
function php(){
    gulp.src('./**/*.php')
    .pipe(gulp.dest('./'))
};

///// Browser Sync /////
function browsersync(){
    browserSync.init({
        proxy: "bshaia.test",
        notify: false
    });
    gulp.watch('./assets/scss/**/*.scss', sass);
    gulp.watch('./assets/js/main.js', js).on('change', browserSync.reload);
    gulp.watch('./**/.php', php).on('change', browserSync.reload);
};

//////////////////////////////
// Default Task
//////////////////////////////
gulp.task('default', browsersync);

I except browserSync to reload on php file changes but it is not happen. Task Arrays got changed in V4 to series() and parallel() Calls in which I am not yet familiar with their new structure.


Get this bounty!!!

#StackBounty: #node.js #templates #gulp Trying to figure a way to read all the files in a directory, re-create and write files programm…

Bounty: 50

I’m trying to use node built in file structure module/package in trying to read and write files. I’m looking for a way on how I can read all the files in specific directory, re-create the files and write for any changes.

Basically if I have a file called templates/_template-1.html it would re-create it to a different directory called pages/template-1.html. Instead of having to declare each file manually within the gulpfile.js. The code below is currently a work in progress.

It basically prints tpl files written then re-writes them to basic html.

/*------------------ INDEX -------------------*/
/* Build index file for the final HTML form
 */
gulp.task("build:index", function() {
    let templateFiles = glob.sync("templates/**/*.tpl"),
        templates = {},

        RESPONSIVE_HTML = fs.readFileSync("_responsive.html", "utf8"),
        THE_HTML = fs.readFileSync("_design-system.html", "utf8"),
        THE_VISUAL_LIBRARY = fs.readFileSync("_visual-library.html", "utf8");

    // Discover all templates
    for (let file in templateFiles) {
        file = templateFiles[file];

        let template = /templates/(.+?).tpl/gi.exec(file)[1],
            text = fs.readFileSync(file, "utf8");

        template = path.basename(file, '.tpl');
        templates[template] = text;
    }

    // --------------------------------------------------------
    // Visible templates:
    _.each(templates, (partial, name) => {
        interpolateTemplate(partial, name, templates);
    });

    // replace the main HTML file
    for (let template in templates) {
        RESPONSIVE_HTML = RESPONSIVE_HTML.replace(new RegExp(`{[@$]${template}}`, "g"), templates[template]);
        THE_HTML = THE_HTML.replace(new RegExp(`{[@$]${template}}`, "g"), templates[template]);
        THE_VISUAL_LIBRARY = THE_VISUAL_LIBRARY.replace(new RegExp(`{[@$]${template}}`, "g"), templates[template]);
    }

    fs.writeFileSync("design-system.html", beautify(THE_HTML), "utf8");
    fs.writeFileSync("responsive.html", beautify(RESPONSIVE_HTML), "utf8");
    fs.writeFileSync("visual-library.html", beautify(THE_VISUAL_LIBRARY), "utf8");
});

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>BDO Components</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.7.5/beautify.js
    https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.7.5/beautify-css.js
    https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.7.5/beautify-html.js
    http://assets/js/libs.js

    <link rel="stylesheet" href="assets/css/assets-page.css" />
    <link rel="stylesheet" href="assets/css/component-guide.css" />
</head>

<body>

    
{$control-bar}
{$globals} {$design-references} {$component-modifiers}
{$typesetting}
{$elements}
{$low-level-components}
{$high-level-components}
</div>
</div> http://assets/js/app.js </body> </html>


Get this bounty!!!

#StackBounty: #javascript #gulp Read environment variables and then replace them in client-side JS when using gulp for building prod or…

Bounty: 150

So lets say I have some code in js

const myApiKey = 'id_0001'

But instead of harcoding it I want to put it in some bash script with other env vars and read from it and then replace it in the JS

So lets say for prod I would read from prod-env.sh or for dev I would read them from dev-env.sh and then gulp or some other tool does the magic and replaces MY_API_KEY based on whatever is established inside of prod-env.sh or dev-env.sh.

const myApiKey = MY_API_KEY


Get this bounty!!!