gulp-less icon indicating copy to clipboard operation
gulp-less copied to clipboard

Memory Leak

Open DaveyJake opened this issue 5 years ago • 6 comments

Has anyone experienced a memory leak while using gulp-less 3.5.0 on gulp 3.9.0? For the last week I've been continuously getting the following when trying to compile:

<--- Last few GCs --->

   52803 ms: Mark-sweep 1363.0 (1436.8) -> 1363.0 (1436.8) MB, 1680.6 / 0.0 ms [allocation failure] [GC in old space requested].
   54461 ms: Mark-sweep 1363.0 (1436.8) -> 1363.0 (1436.8) MB, 1657.8 / 0.0 ms [allocation failure] [GC in old space requested].
   56133 ms: Mark-sweep 1363.0 (1436.8) -> 1364.2 (1412.8) MB, 1671.0 / 0.0 ms [last resort gc].
   57790 ms: Mark-sweep 1364.2 (1412.8) -> 1365.6 (1412.8) MB, 1656.7 / 0.0 ms [last resort gc].


<--- JS stacktrace --->

==== JS stack trace =========================================

Security context: 0x23b7736cfb39 <JS Object>
    1: cancel [/my/path/to/project/wp-content/themes/mytheme/node_modules/less/lib/less/tree/unit.js:90] [pc=0x346b8702e71a] (this=0x21c59c058df9 <an Unit with map 0x290404173fe9>)
    2: operate [/my/path/to/project/wp-content/themes/mytheme/node_modules/less/lib/less/tree/dimension.js:~59] [pc=0x346b8704401e] (this=0x1b73d776919 <a Dimension with map 0x29040416a171>,context=0x1b73d777129 ...

FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory
 1: node::Abort() [/my/homedir/.nvm/versions/node/v6.10.2/bin/node]
 2: node::FatalException(v8::Isolate*, v8::Local<v8::Value>, v8::Local<v8::Message>) [/my/homedir/.nvm/versions/node/v6.10.2/bin/node]
 3: v8::internal::V8::FatalProcessOutOfMemory(char const*, bool) [/my/homedir/.nvm/versions/node/v6.10.2/bin/node]
 4: v8::internal::Factory::NewTransitionArray(int) [/my/homedir/.nvm/versions/node/v6.10.2/bin/node]
 5: v8::internal::TransitionArray::Insert(v8::internal::Handle<v8::internal::Map>, v8::internal::Handle<v8::internal::Name>, v8::internal::Handle<v8::internal::Map>, v8::internal::SimpleTransitionFlag) [/my/homedir/.nvm/versions/node/v6.10.2/bin/node]
 6: v8::internal::Map::CopyReplaceDescriptors(v8::internal::Handle<v8::internal::Map>, v8::internal::Handle<v8::internal::DescriptorArray>, v8::internal::Handle<v8::internal::LayoutDescriptor>, v8::internal::TransitionFlag, v8::internal::MaybeHandle<v8::internal::Name>, char const*, v8::internal::SimpleTransitionFlag) [/my/homedir/.nvm/versions/node/v6.10.2/bin/node]
 7: v8::internal::Map::CopyAddDescriptor(v8::internal::Handle<v8::internal::Map>, v8::internal::Descriptor*, v8::internal::TransitionFlag) [/my/homedir/.nvm/versions/node/v6.10.2/bin/node]
 8: v8::internal::Map::CopyWithField(v8::internal::Handle<v8::internal::Map>, v8::internal::Handle<v8::internal::Name>, v8::internal::Handle<v8::internal::FieldType>, v8::internal::PropertyAttributes, v8::internal::Representation, v8::internal::TransitionFlag) [/my/homedir/.nvm/versions/node/v6.10.2/bin/node]
 9: v8::internal::Map::TransitionToDataProperty(v8::internal::Handle<v8::internal::Map>, v8::internal::Handle<v8::internal::Name>, v8::internal::Handle<v8::internal::Object>, v8::internal::PropertyAttributes, v8::internal::Object::StoreFromKeyed) [/my/homedir/.nvm/versions/node/v6.10.2/bin/node]
10: v8::internal::LookupIterator::PrepareTransitionToDataProperty(v8::internal::Handle<v8::internal::JSObject>, v8::internal::Handle<v8::internal::Object>, v8::internal::PropertyAttributes, v8::internal::Object::StoreFromKeyed) [/my/homedir/.nvm/versions/node/v6.10.2/bin/node]
11: v8::internal::StoreIC::LookupForWrite(v8::internal::LookupIterator*, v8::internal::Handle<v8::internal::Object>, v8::internal::Object::StoreFromKeyed) [/my/homedir/.nvm/versions/node/v6.10.2/bin/node]
12: v8::internal::StoreIC::UpdateCaches(v8::internal::LookupIterator*, v8::internal::Handle<v8::internal::Object>, v8::internal::Object::StoreFromKeyed) [/my/homedir/.nvm/versions/node/v6.10.2/bin/node]
13: v8::internal::StoreIC::Store(v8::internal::Handle<v8::internal::Object>, v8::internal::Handle<v8::internal::Name>, v8::internal::Handle<v8::internal::Object>, v8::internal::Object::StoreFromKeyed) [/my/homedir/.nvm/versions/node/v6.10.2/bin/node]
14: v8::internal::KeyedStoreIC::Store(v8::internal::Handle<v8::internal::Object>, v8::internal::Handle<v8::internal::Object>, v8::internal::Handle<v8::internal::Object>) [/my/homedir/.nvm/versions/node/v6.10.2/bin/node]
15: v8::internal::Runtime_StoreIC_Miss(int, v8::internal::Object**, v8::internal::Isolate*) [/my/homedir/.nvm/versions/node/v6.10.2/bin/node]
16: 0x346b853092a7

Any advice would be greatly appreciated.

Cheers!

DaveyJake avatar Apr 09 '19 06:04 DaveyJake

UPDATE Even after updating to gulp-less 4.0.1, same issue but with fewer errors:

<--- Last few GCs --->

   65201 ms: Mark-sweep 1366.9 (1444.8) -> 1366.9 (1444.8) MB, 1615.9 / 0.0 ms [allocation failure] [GC in old space requested].
   66836 ms: Mark-sweep 1366.9 (1444.8) -> 1366.9 (1444.8) MB, 1634.4 / 0.0 ms [allocation failure] [GC in old space requested].
   68460 ms: Mark-sweep 1366.9 (1444.8) -> 1366.9 (1415.8) MB, 1623.8 / 0.0 ms [last resort gc].
   70036 ms: Mark-sweep 1366.9 (1415.8) -> 1366.9 (1415.8) MB, 1576.6 / 0.0 ms [last resort gc].


<--- JS stacktrace --->

==== JS stack trace =========================================

Security context: 0x2943cf3cfb39 <JS Object>
    1: InnerArrayReduce(aka InnerArrayReduce) [native array.js:~1107] [pc=0x193f9491217c] (this=0x2943cf304381 <undefined>,bw=0xbd1a6bc0dd1 <JS Function (SharedFunctionInfo 0x23ebc4925c11)>,aa=0xbd1a6bc0e19 <an Object with map 0x133d337075e9>,w=0x35bdf0e1bd31 <JS Array[32767]>,x=32767,bv=2)
    2: reduce [native array.js:~1130] [pc=0x193f934d00c3] (this=0x35bdf0e1bd31 <JS Array[32767]>,bw=0xbd1...

FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory
 1: node::Abort() [/my/homedir/.nvm/versions/node/v6.10.2/bin/node]
 2: node::FatalException(v8::Isolate*, v8::Local<v8::Value>, v8::Local<v8::Message>) [/my/homedir/.nvm/versions/node/v6.10.2/bin/node]
 3: v8::internal::V8::FatalProcessOutOfMemory(char const*, bool) [/my/homedir/.nvm/versions/node/v6.10.2/bin/node]
 4: v8::internal::Factory::NewRawOneByteString(int, v8::internal::PretenureFlag) [/my/homedir/.nvm/versions/node/v6.10.2/bin/node]
 5: v8::internal::Factory::NumberToString(v8::internal::Handle<v8::internal::Object>, bool) [/my/homedir/.nvm/versions/node/v6.10.2/bin/node]
 6: v8::internal::Object::ToString(v8::internal::Isolate*, v8::internal::Handle<v8::internal::Object>) [/my/homedir/.nvm/versions/node/v6.10.2/bin/node]
 7: v8::internal::Object::ConvertToName(v8::internal::Isolate*, v8::internal::Handle<v8::internal::Object>) [/my/homedir/.nvm/versions/node/v6.10.2/bin/node]
 8: v8::internal::Runtime_HasProperty(int, v8::internal::Object**, v8::internal::Isolate*) [/my/homedir/.nvm/versions/node/v6.10.2/bin/node]
 9: 0x193f930092a7

DaveyJake avatar Apr 09 '19 07:04 DaveyJake

How many files are you parsing? If it is an actual memory leak the less.js repo would be a better place to ask

stephenlacy avatar Apr 09 '19 14:04 stephenlacy

@DaveyJake Can you create a github repo that reproduces the issue?

yocontra avatar Apr 09 '19 15:04 yocontra

How many files are you parsing? If it is an actual memory leak the less.js repo would be a better place to ask

The only LESS module of any sort that I've installed is gulp-less.

Can you create a github repo that reproduces the issue?

Even when I attempt to parse just one single file, the issue is still occurring. Here's my package.json if it helps?

{
  "name": "custom-project",
  "version": "1.0.0",
  "description": "The official theme for this custom project",
  "main": "gulpfile.babel.js",
  "dependencies": {
    "@webcomponents/webcomponentsjs": "^1.3.3",
    "autolinker": "^1.8.3",
    "chosen-js": "^1.8.3",
    "flag-icon-css": "^2.9.0",
    "foundation-sites": "^6.5.3",
    "hammerjs": "^2.0.8",
    "headroom.js": "^0.9.4",
    "imagesloaded": "^4.1.4",
    "infinite-scroll": "^3.0.3",
    "isotope-layout": "^3.0.5",
    "isotope-packery": "^2.0.1",
    "jquery-bracket": "^0.11.1",
    "jquery-hammerjs": "^2.0.0",
    "jquery-match-height": "^0.7.2",
    "jquery.mmenu": "^5.7.8",
    "jquery.nicescroll": "^3.7.6",
    "js-cookie": "^2.2.0",
    "masonry-layout": "^4.2.1",
    "motion-ui": "^1.1.0",
    "nanoreset": "^1.2.0",
    "pace-progress": "^1.0.2",
    "selectize": "^0.12.4",
    "slick-carousel": "^1.8.1",
    "smoothscroll-for-websites": "^1.4.9",
    "stacktable.js": "^1.0.3",
    "tablesorter": "2.31.0",
    "tabletop": "^1.5.2",
    "what-input": "^5.2.1",
    "x-tag": "^1.5.11",
    "yadcf": "^0.9.4"
  },
  "devDependencies": {
    "accord": "^0.29.0",
    "acorn": "^6.1.1",
    "ansi-colors": "^1.1.0",
    "babel-cli": "^6.23.0",
    "babel-core": "^6.26.3",
    "babel-eslint": "^7.1.1",
    "babel-helper-fixtures": "^6.22.0",
    "babel-helper-plugin-test-runner": "^6.22.0",
    "babel-loader": "^7.1.5",
    "babel-plugin-istanbul": "^3.1.2",
    "babel-preset-env": "^1.7.0",
    "babel-register": "^6.23.0",
    "browser-sync": "^2.26.3",
    "colors": "^1.3.3",
    "critical": "^1.3.4",
    "dateformat": "^3.0.2",
    "del": "^4.1.0",
    "eslint": "^3.17.1",
    "eslint-config-babel": "^6.0.0",
    "eslint-config-wordpress": "^2.0.0",
    "eslint-plugin-import": "^2.16.0",
    "fancy-log": "^1.3.2",
    "gulp": "~3.9.0",
    "gulp-autoprefixer": "^3.1.0",
    "gulp-babel": "^6.1.2",
    "gulp-clean-css": "^3.7.0",
    "gulp-concat": "^2.6.0",
    "gulp-cssbeautify": "^1.0.0",
    "gulp-flatten": "^0.2.0",
    "gulp-if": "^2.0.0",
    "gulp-imagemin": "^5.0.3",
    "gulp-jshint": "^2.1.0",
    "gulp-less": "^4.0.1",
    "gulp-load-plugins": "^1.1.0",
    "gulp-minify-inline": "1.1.0",
    "gulp-notify": "^2.2.0",
    "gulp-plumber": "^1.0.1",
    "gulp-remove-empty-lines": "^0.1.0",
    "gulp-rev": "^8.1.1",
    "gulp-sourcemaps": "^2.6.5",
    "gulp-strip-comments": "^2.5.2",
    "gulp-uglify": "^1.5.1",
    "gulp-uncss": "^1.0.4",
    "gulp-util": "^3.0.7",
    "gulp-zip": "^3.0.2",
    "js-yaml": "^3.13.1",
    "jshint": "^2.10.2",
    "less-plugin-autoprefix": "^1.5.1",
    "panini": "^1.6.3",
    "rimraf": "^2.6.3",
    "run-sequence": "^1.2.2",
    "style-sherpa": "^1.0.0",
    "vinyl-named": "^1.1.0",
    "webpack": "^4.8.3",
    "webpack-stream": "^4.0.0",
    "yargs": "^3.8.0"
  },
  "scripts": {
    "start": "gulp",
    "dev": "gulp build --dev",
    "build": "gulp build --production",
    "package": "gulp package --production",
    "postinstall": "gulp build",
    "phpcs": "gulp phpcs",
    "phpcbf": "gulp phpcbf"
  }
}

DaveyJake avatar Apr 09 '19 17:04 DaveyJake

@DaveyJake Yeah, it would help us to debug if you can make a standalone github repo that reproduces the issue - without that there isn't much we can help with.

yocontra avatar Apr 09 '19 20:04 yocontra

@contra Here's some good news: I finally found the issue to solve the memory leak. Even though I explicitly set my config to only compile specific files, it was compiling all of them. It wasn't until I set an ! flag in front of all the subdirectories that things started working (somewhat) normally again. Here's the current issue I'm now facing:

[14:18:09] Starting 'less'...
[14:18:10] Starting 'webpack:build'...
[14:18:10] Starting 'lint'...
[14:18:10] Finished 'less' after 454 ms

It's almost as if my LESS block is getting completely ignored.

Here are the contents of my gulpfile.babel.js file:

'use strict';

import path             from 'path';
import accord           from 'accord';
import gulp             from 'gulp';
import plugins          from 'gulp-load-plugins';
import cleanCSS         from 'gulp-clean-css';
import critical         from 'critical';
import minifyInline     from 'gulp-minify-inline';
import stripComments    from 'gulp-strip-comments';
import removeEmptyLines from 'gulp-remove-empty-lines';
import yargs            from 'yargs';
import browser          from 'browser-sync';
import rimraf           from 'rimraf';
import yaml             from 'js-yaml';
import fs               from 'fs';
import dateFormat       from 'dateformat';
import webpackStream    from 'webpack-stream';
import webpack2         from 'webpack';
import named            from 'vinyl-named';
import log              from 'fancy-log';
import colors           from 'ansi-colors';
import sequence         from 'run-sequence';

// Critical CSS
const criticalCSS = critical.stream;

// Load all Gulp plugins into one variable
const $ = plugins();

// Check for --production flag
const PRODUCTION = !!(yargs.argv.production);

// Check for --development flag unminified with sourcemaps
const DEV = !!(yargs.argv.dev);

// Paths
const PATHS = {
    // Paths to static assets that aren't images, CSS, or JavaScript
    assets: [
      'src/assets/**/*',
      '!src/assets/{images,images/**/*,js,js/**/*,less,less/**/*}'
    ],
    // Paths to JavaScript entry points for webpack to bundle modules
    entries: 'src/assets/js/main.js',
    // Path to `dist` folder
    dist: 'dist',

    images: [
      'src/assets/images/**/*',
      'src/assets/images/*'
    ],

    less: [
      'src/assets/less/*.less',
      '!src/assets/less/**/*.less'
    ],

    js: [
      // WordPress Defaults
      'src/assets/js/components/jscookie/src/js.cookie.js',

      // Non-Dependent
      'src/assets/js/plugins/modernizr.usarugby.js',
      'src/assets/js/plugins/modernizr.retina.js',

      // jQuery DOM Router
      'src/assets/js/components/jquery-dom-router/jquery.dom-router.js',

      // Sitewide JS Plugins
      'src/assets/js/plugins/jquery.matchHeight.js',
      'src/assets/js/plugins/autolink.js',

      // ZURB Defaults
      //'node_modules/what-input/what-input.js',
      './node_modules/foundation-sites/js/foundation.core*.js',
      './node_modules/foundation-sites/js/foundation.util.*.js',

      // Paths to individual Foundation JS components defined below
      './node_modules/foundation-sites/js/foundation.abide.js',
      './node_modules/foundation-sites/js/foundation.accordion.js',
      './node_modules/foundation-sites/js/foundation.accordionMenu.js',
      './node_modules/foundation-sites/js/foundation.dropdown.js',
      './node_modules/foundation-sites/js/foundation.dropdownMenu.js',
      './node_modules/foundation-sites/js/foundation.interchange.js',
      './node_modules/foundation-sites/js/foundation.magellan.js',
      './node_modules/foundation-sites/js/foundation.positionable.js',
      './node_modules/foundation-sites/js/foundation.responsiveMenu.js',
      './node_modules/foundation-sites/js/foundation.responsiveToggle.js',
      './node_modules/foundation-sites/js/foundation.reveal.js',
      './node_modules/foundation-sites/js/foundation.slider.js',
      './node_modules/foundation-sites/js/foundation.sticky.js',
      './node_modules/foundation-sites/js/foundation.tabs.js',
      './node_modules/foundation-sites/js/foundation.toggler.js',
      './node_modules/foundation-sites/js/foundation.tooltip.js',

      // jQuery.MMenu - Core - Addons
      'src/assets/js/components/jQuery.mmenu/js/jquery.mmenu.oncanvas.js',
      'src/assets/js/components/jQuery.mmenu/js/jquery.mmenu.offcanvas.js',
      'src/assets/js/components/jQuery.mmenu/js/jquery.mmenu.scrollbugfix.js',
      'src/assets/js/components/jQuery.mmenu/js/jquery.mmenu.screenreader.js',
      'src/assets/js/components/jQuery.mmenu/js/jquery.mmenu.autoheight.js',
      'src/assets/js/components/jQuery.mmenu/js/jquery.mmenu.backbutton.js',
      'src/assets/js/components/jQuery.mmenu/js/jquery.mmenu.dropdown.js',
      'src/assets/js/components/jQuery.mmenu/js/jquery.mmenu.fixedelements.js',
      'src/assets/js/components/jQuery.mmenu/js/jquery.mmenu.lazysubmenus.js',
      'src/assets/js/components/jQuery.mmenu/js/jquery.mmenu.navbars.js',
      'src/assets/js/components/jQuery.mmenu/js/jquery.mmenu.navbar.*.js',
      'src/assets/js/components/jQuery.mmenu/js/jquery.mmenu.pagescroll.js',
      'src/assets/js/components/jQuery.mmenu/js/jquery.mmenu.searchfield.js',
      'src/assets/js/components/jQuery.mmenu/js/jquery.mmenu.setselected.js',

      // Include your own custom scripts
      'src/assets/js/custom.js'
    ]
};

// Load settings from settings.yml
const { BROWSERSYNC, COMPATIBILITY, REVISIONING } = loadConfig();

// Check if file exists synchronously
function checkFileExists(filepath) {
  let flag = true;
  try {
    fs.accessSync(filepath, fs.F_OK);
  } catch(e) {
    flag = false;
  }
  return flag;
}

// Load default or custom YML config file
function loadConfig() {
  log('Loading config file...');

  if (checkFileExists('config.yml')) {
    // config.yml exists, load it
    log(colors.bold(colors.cyan('config.yml')), 'exists, loading', colors.bold(colors.cyan('config.yml')));
    let ymlFile = fs.readFileSync('config.yml', 'utf8');
    return yaml.load(ymlFile);

  } else if(checkFileExists('config-default.yml')) {
    // config-default.yml exists, load it
    log(colors.bold(colors.cyan('config.yml')), 'does not exist, loading', colors.bold(colors.cyan('config-default.yml')));
    let ymlFile = fs.readFileSync('config-default.yml', 'utf8');
    return yaml.load(ymlFile);

  } else {
    // Exit if config.yml & config-default.yml do not exist
    log('Exiting process, no config file exists.');
    log('Error Code:', err.code);
    process.exit(1);
  }
}

// Delete compiled CSS
gulp.task('clean:css', function(done) {
  rimraf(PATHS.dist + '/assets/css', done);
});

// Delete compiled JS
gulp.task('clean:javascript', function(done) {
  rimraf(PATHS.dist + '/assets/js', done);
});

// Compless Less into CSS
// In production, CSS is compressed
gulp.task('less', function() {
  return gulp.src(PATHS.less)
    .pipe($.sourcemaps.init())
    .pipe($.less().on('error', $.util.log))
    .pipe($.autoprefixer({
      browsers: COMPATIBILITY
    }))
    .pipe($.if(!PRODUCTION, $.cssbeautify({
      indent: '    ',
      openbrace: 'end-of-line',
      autosemicolon: true
    })))
    .pipe(cleanCSS())
    .pipe($.if(!PRODUCTION, $.sourcemaps.write(PATHS.dist + '/assets/css', {
        sourceMappingURLPrefix: 'my.custom.tld/wp-content/themes/usacr'
    })))
    .pipe(gulp.dest(PATHS.dist + '/assets/css'))
    .pipe(browser.reload({ stream: true }));
});

// Copy files out of the assets folder
// This task skips over the "images", "js", and "less" folders, which are parsed separately
gulp.task('copy', function() {
  return gulp.src(PATHS.assets)
    .pipe(gulp.dest(PATHS.dist + '/assets'));
});

// Combine JavaScript into one file
// In production, the file is minified
const webpack = {
  config: {
    module: {
      rules: [
        {
          test: /\.js$/,
          loader: 'babel-loader',
          exclude: /node_modules(?![\\\/]foundation-sites)/,
        }
      ],
    },
    externals: {
      jquery: 'jQuery'
    },
  },

  changeHandler(err, stats) {
    log('[webpack]', stats.toString({
      colors: true,
    }));

    browser.reload();
  },

  build() {
    return gulp.src(PATHS.entries)
      .pipe(named())
      .pipe(webpackStream(webpack.config, webpack2))
      .pipe($.if(PRODUCTION, $.uglify()
        .on('error', e => { fs.writeSync(process.stdout.fd, (e) + '\n'); })
      ))
      .pipe($.if(REVISIONING && PRODUCTION || REVISIONING && DEV, $.rev()))
      .pipe(gulp.dest(PATHS.dist + '/assets/js'))
      .pipe($.if(REVISIONING && PRODUCTION || REVISIONING && DEV, $.rev.manifest()))
      .pipe(gulp.dest(PATHS.dist + '/assets/js'));
  },

  watch() {
    const watchConfig = Object.assign(webpack.config, {
      watch: true,
      devtool: 'inline-source-map',
    });

    return gulp.src(PATHS.entries)
      .pipe(named())
      .pipe(webpackStream(watchConfig, webpack2, webpack.changeHandler)
        .on('error', (err) => {
          log('[webpack:error]', err.toString({
            colors: true,
          }));
        }),
      )
      .pipe(gulp.dest(PATHS.dist + '/assets/js'));
  }
};

gulp.task('webpack:build', webpack.build);
gulp.task('webpack:watch', webpack.watch);

// Copy images to the "dist" folder
// In production, the images are compressed
gulp.task('images', function() {
  return gulp.src(PATHS.images)
    .pipe($.if(PRODUCTION, $.imagemin([
      $.imagemin.jpegtran({
        progressive: true,
      }),
      $.imagemin.optipng({
        optimizationLevel: 5,
      }),
      $.imagemin.gifsicle({
        interlaced: true,
      }),
      $.imagemin.svgo({
        plugins: [
          {cleanupAttrs: true},
          {removeComments: true},
        ]
      })
    ])))
    .pipe(gulp.dest(PATHS.dist + '/assets/images'));
});

// Create a .zip archive of the theme
gulp.task('archive', function() {
  var time  = dateFormat(new Date(), "yyyy-mm-dd_HH-MM");
  var pkg   = JSON.parse(fs.readFileSync('./package.json'));
  var title = pkg.name + '_' + time + '.zip';

  return gulp.src(PATHS.package)
    .pipe($.zip(title))
    .pipe(gulp.dest('packaged'));
});

// Lint all JS files in custom directory
gulp.task('lint', function() {
  return gulp.src('src/assets/js/custom.js')
    .pipe($.jshint({ 'esversion': 6 }))
    .pipe($.notify(function (file) {
      if (file.jshint.success) {
        return false;
      }

      var errors = file.jshint.results.map(function (data) {
        if (data.error) {
          return "(" + data.error.line + ':' + data.error.character + ') ' + data.error.reason;
        }
      }).join("\n");
      return file.relative + " (" + file.jshint.results.length + " errors)\n" + errors;
    }));
});

// Start BrowserSync to preview the site in
gulp.task('server', ['build'], function(done) {
  browser.init('**/*.php', {
    proxy: BROWSERSYNC.url,
    ui: {
      port: 8080
    }
  });
  done();
});

// Reload
gulp.task('reload', function(done) {
  browser.reload();
  done();
});

// Build task
// Runs copy then runs sass & javascript in parallel
gulp.task('build', ['clean'], function(done) {
  sequence('copy',
          ['images', 'less', 'webpack:build', 'lint'],
          done);
});

// Clean task
gulp.task('clean', ['clean:javascript', 'clean:css'], function(done) {
  rimraf(PATHS.dist + '/assets', done);
});

// Default gulp task
// Run build task and watch for file changes
gulp.task('default', ['build', 'server'], function() {
  // Assets
  gulp.watch(PATHS.assets, ['copy']);
  // Less Watch
  gulp.watch(['src/assets/less/**/*.less', 'src/assets/less/*.less'], ['less'])
    .on('change', path => log('File ' + colors.bold(colors.magenta(path)) + ' changed.'))
    .on('unlink', path => log('File ' + colors.bold(colors.magenta(path)) + ' was removed.'));
  // JS Watch
  gulp.watch(['src/assets/js/**/*.js', 'src/assets/js/custom.js', 'src/assets/js/main.js'], ['clean:javascript', 'webpack:build', 'lint'])
    .on('change', path => log('File ' + colors.bold(colors.magenta(path)) + ' changed.'))
    .on('unlink', path => log('File ' + colors.bold(colors.magenta(path)) + ' was removed.'));
  // Images
  gulp.watch(['src/assets/images/**/*','src/assets/images/*'], function(done) {
    sequence('images', 'copy', 'reload', done);
  });

});

Any thoughts?

DaveyJake avatar Apr 09 '19 20:04 DaveyJake