admin管理员组

文章数量:1290754

I'm new to Gulp and the concept of task runners. I am wanting to write some javascript using es6 and have gulp run it through jscs, jshint and finally use babel to convert it to es5.

The part I'm confused about is the order I should have these tasks in my gulp pipeline. If I run jshint first I get warnings about how I can't use let and arrow functions. However, if I convert my code using babel first the babel output then fails validation as well.

What I'm looking for is a correct way of ordering my gulp task so it validates and converts my code to es5.

This is my current gulp task.

gulp.task('js-validation', function() {
$.util.log('**Starting js validation**');

return gulp
    .src(config.alljs)
    .pipe($.print())
    .pipe($.jshint())
    .pipe($.jscs())
    .pipe($.babel())
    .pipe($.jshint.reporter('jshint-stylish', {verbose: true}))
    .pipe($.jshint.reporter('fail'))
    .pipe(gulp.dest(config.temp));

});

I'm new to Gulp and the concept of task runners. I am wanting to write some javascript using es6 and have gulp run it through jscs, jshint and finally use babel to convert it to es5.

The part I'm confused about is the order I should have these tasks in my gulp pipeline. If I run jshint first I get warnings about how I can't use let and arrow functions. However, if I convert my code using babel first the babel output then fails validation as well.

What I'm looking for is a correct way of ordering my gulp task so it validates and converts my code to es5.

This is my current gulp task.

gulp.task('js-validation', function() {
$.util.log('**Starting js validation**');

return gulp
    .src(config.alljs)
    .pipe($.print())
    .pipe($.jshint())
    .pipe($.jscs())
    .pipe($.babel())
    .pipe($.jshint.reporter('jshint-stylish', {verbose: true}))
    .pipe($.jshint.reporter('fail'))
    .pipe(gulp.dest(config.temp));

});

Share Improve this question edited Aug 24, 2015 at 14:54 Felix Kling 817k181 gold badges1.1k silver badges1.2k bronze badges asked Aug 24, 2015 at 13:51 DavidDavid 2194 silver badges18 bronze badges
Add a ment  | 

6 Answers 6

Reset to default 6

This work for me:

.pipe(jshint({
        esnext: true
    }))

First, if possible, consider moving to ESLint; I'm not saying that because it's a subjective opinion, I'm saying that because it's modular and supports ES6, and even React+JSX if that's where you want to go with it.

You aren't going to have a lot of luck with JSHint, yet, if ES6 is where you're going. If/when I'm wrong, please let me know, but I believe they have yet to replace their parser, to support all of ES6, and unless you're going to include the entirety of the browser polyfill+library in the pipeline (just for sake of having no missing methods, for validate to work), you may well be at a loss, here.

With ESLint in place, you could use the following config options (in .eslintrc, in the package.json, et cetera), to get ES6 support:

{
  "env": {
    "browser": true,
    "node": true,
    "es6": true
  },
  "ecmaFeatures": {
    "modules": true,
    "jsx": true
  }
}

Of course, if you don't need node globals, JSX or ES6 modules, feel free to rip those out.

The one other caveat there is that ESLint has no support for ES7 (ES2016), yet (but will, when it's standardized). So array/generator prehensions, async/await, trailing mas in function argument lists, et cetera, are not supported and will cause explosions.

There is a babel-eslint version of eslint which will validate these, if that's your requirement. You can put that in place by installing "babel-eslint" and then in your eslint config, setting { "parser": "babel-eslint" } to the root object, along with all of your other config preferences.

But typically, you would lint the code that you are putting into the system, pre-pile, using ESLint and Babel:

// ...
.pipe( eslint() )
.pipe( babel() )
// ...

To lint the source code (rather then the piled code) you have to call the linter before babel, so the order is correct.

However, you have to use a linter that really understands ES6. With JSHint, you have to set the esnext option, but I'm not sure whether it supports all ES6 features. I remend to have a look at eslint with babel-eslint instead.

Instead of JSHint, you can use ESLint, which will have support for numerous ES6 functions:

http://eslint/docs/user-guide/configuring

You are correct that you want your linting to occur prior to transpilation, also.

gulp.task('jshint', function () {
    gulp.src('js/**/*.js')
    .pipe(cache('jshint'))
    .pipe(jshint({esnext:true}))
    .pipe(jshint.reporter('default'));
});

.pipe(jshint({esnext:true}))

You have the correct order, but as suggested from other answers to use ESLint. You should also have a function to handle errors when linting. Here is my gulpfile.js (not a perfect example, but it's working for me):

const gulp = require("gulp"),
    babel = require("gulp-babel"),
    eslint = require("gulp-eslint");

gulp.task("babel", () => {
    gulp.src("src/*.js")
        .pipe(eslint())
        .pipe(eslint.format())
        .pipe(eslint.failAfterError())
        .on("error", onError) // handle error for eslint
        .pipe(babel())
        .on("error", onError) // handle error for babel
        .pipe(gulp.dest("dist"));
});

gulp.task("watch", () => {
    process.chdir(process.env.INIT_CWD);
    gulp.watch("src/*.js", ["babel"]);
});

// ignore if error is from babel, eslint error message is enough
if (err.plugin != "gulp-babel" && err.message) {
  console.log("Message: ", err.message);
}

本文标签: javascriptGulp workflow for validation and es 6Stack Overflow