Issue with task not executing when using gulp with

2019-08-29 19:24发布

问题:

I am new to gulp and so I put a simple script together to 1) learn how gulp works and 2) improve my development workflow.

The issue I am having is that if I set the runSequence task list to be in the order of jscs and then lint, the lint task does not get executed. However, if I reverse them, and run lint first, then jscs, both tasks execute successfully. After doing more tests, I'm certain that there is something about the way I am using jscs that is causing the problem, or there is an issue with jscs that prevents this from executing in this way.

Things I have checked:

  1. Dependencies have been installed globally.
  2. Dependencies have been setup in my package.json.
  3. All of the needed require statements at the top of my gulpfile.js are established.
  4. Checked that the .jshintrc file that I reference for jshint does in fact exist
  5. Checked that the .jscsrc file that I reference for jscs does in fact exist

gulpfile.js:

/* File: gulpfile.js */

/* grab the packages we will be using */
var gulp = require('gulp');
var gutil = require('gulp-util');
var jscs = require('gulp-jscs');
var jsHint = require('gulp-jshint');
var jsHintStylish = require('jshint-stylish');
var runSequence = require('run-sequence');
var console = require('better-console');

// configure the default task and add the watch task to it
gulp.task('default', ['watch']);

// configure the jscs task
gulp.task('jscs', function() {
    return gulp.src('src/app/**/*.js')
        .pipe(jscs('.jscsrc'));
});

// configure the lint task
gulp.task('lint', function() {
    return gulp.src("src/app/**/*.js")
        .pipe(jsHint('.jshintrc'))
        .pipe(jsHint.reporter(jsHintStylish));
});

// configure the watch task - set up which files to watch and what tasks to use when those files change
gulp.task('watch',function() {

    // Clear console
    console.clear();

    // setup a watch against the files that need to be checked on save
    gulp.watch('src/app/**/*.js', function(){
        // Clear console so only current issues are shown
        console.clear();

        // Execute tasks to check code for issues
        runSequence('lint','jscs',function(){
            gutil.log("Code Check Complete.");
        });
    });

});

package.json:

{
  "name": "my project name",
  "version": "0.1.0",
  "author": {
    "name": "my name",
    "email": "myemail@domain.com"
  },
  "devDependencies": {
    "better-console": "^0.2.4",
    "gulp": "^3.8.11",
    "gulp-jscs": "^1.6.0",
    "gulp-jshint": "^1.11.0",
    "gulp-util": "^3.0.4",
    "jshint-stylish": "^1.0.2",
    "run-sequence": "^1.1.0"
  }
}

JavaScript file in the folder that is being watched. Notice the errors that I placed so that both jscs and lint will report issues:

(function() {

    'use strict;

    var x = ;

})();

Sample output when the run sequence task ordering is 'lint','jscs',function(){...}:

[15:10:49] Starting 'lint'...

c:\Users\anatha\My Projects\Tracks\Tracks.Client\src\app\app.js
  line 3  col 17  Unclosed string.
  line 4  col 1   Unclosed string.
  line 5  col 14  Unclosed string.
  line 6  col 1   Unclosed string.
  line 7  col 6   Unclosed string.
  line 8  col 1   Unclosed string.
  line 3  col 5   Unclosed string.
  line 1  col 13  Missing semicolon.
  line 8  col 1   Missing "use strict" statement.
  line 1  col 13  Unmatched '{'.
  line 1  col 1   Unmatched '('.
  line 8  col 1   Expected an assignment or function call and instead saw an expression.
  line 8  col 1   Missing semicolon.

  ×  4 errors
  ‼  9 warnings

[15:10:49] Finished 'lint' after 104 ms
[15:10:49] Starting 'jscs'...
[15:10:49] 'jscs' errored after 157 ms
[15:10:49] Error in plugin 'gulp-jscs'
Message:
    Unexpected token ILLEGAL at app.js :
     1 |(function() {
     2 |
     3 | 'use strict;
-----------------------^
     4 |
     5 | var x = ;
[15:10:49] Code Check Complete.

Sample output when the run sequence task ordering is 'jscs','lint',function(){...} (Notice that the lint statement is never executed):

[15:09:48] Starting 'jscs'...
[15:09:48] 'jscs' errored after 178 ms
[15:09:48] Error in plugin 'gulp-jscs'
Message:
    Unexpected token ILLEGAL at app.js :
     1 |(function() {
     2 |
     3 | 'use strict;
-----------------------^
     4 |
     5 | var x = ;
[15:09:48] Code Check Complete.

回答1:

After spending a number of hours researching the cause of the issue, I narrowed it down to the fact that JSCS throws an error when it determines that the code it has checked doesn't abide by the specs set by the user. When this error is thrown, it inhibits subsequent tasks in the run-sequence from being executed; however, what is strange is that an unhandled error event is never generated to alert the user of the issue.

This is different than the way JSHINT operates. When JSHINT determines there is an error in the code, it simply outputs the code violations, but doesn't throw an error that causes subsequent tasks to never be triggered.

I updated my script to work around this issue by catching the unhandled error, and performing the minimal amount of processing for that error that was needed to allow the remaining tasks specified in the run-sequence to be completed.

Updated gulpfile.js file:

/* File: gulpfile.js */

/* grab the packages we will be using */
var gulp = require('gulp');
var gUtil = require('gulp-util');
var jscs = require('gulp-jscs');
var jsHint = require('gulp-jshint');
var jsHintStylish = require('jshint-stylish');
var runSequence = require('run-sequence');
var console = require('better-console');

// default error handler
var handleJscsError = function(err) {
    console.log("Error: " + err.toString());
    this.emit('end');
}

// configure the default task and add the watch task to it
gulp.task('default', ['watch']);

// configure the jscs task
gulp.task('jscs', function() {
    return gulp.src('src/app/**/*.js')
        .pipe(jscs('.jscsrc'))
        .on('error',handleJscsError);
});

// configure the lint task
gulp.task('lint', function() {
    return gulp.src("src/app/**/*.js")
        .pipe(jsHint('.jshintrc'))
        .pipe(jsHint.reporter(jsHintStylish));
});

// configure the watch task - set up which files to watch and what tasks to use when those files change
gulp.task('watch', function() {

    // Clear console
    console.clear();

    // setup a watch against the files that need to be checked on save
    return gulp.watch('src/app/**/*.js', function(){

        // Clear console so only current issues are shown
        console.clear();

        // Execute tasks to check code for issues
        runSequence('jscs','lint',function(){
            console.log("Tasks Completed.")
        });

    });

});

Another thing to note:

I tried working around the issue by creating a custom JSCS reporter. And while I did get this somewhat functional, it really felt like a kludge to me rather than a solid solution. And to add that JSCS doesn't provide custom reporting like JSHINT does made this even uglier knowing that once support is added for custom reporting, I'd have to refactor the code anyway.