Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Memory Leak #306

Open
DaveyJake opened this issue Apr 9, 2019 · 6 comments
Open

Memory Leak #306

DaveyJake opened this issue Apr 9, 2019 · 6 comments

Comments

@DaveyJake
Copy link

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
Copy link
Author

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

@stephenlacy
Copy link
Contributor

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

@yocontra
Copy link
Member

yocontra commented Apr 9, 2019

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

@DaveyJake
Copy link
Author

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"
  }
}

@yocontra
Copy link
Member

yocontra commented Apr 9, 2019

@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.

@DaveyJake
Copy link
Author

DaveyJake commented Apr 9, 2019

@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?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants