运行watchify之前运行eslint

7
我正在将watchify加入我们的构建流程,但我想在运行watchify之前设置前提条件,即更改的文件需通过我们的代码检查步骤(使用ESLint)。
我的想法是这样的:
function runBrowserify(watch){
  var babel = babelify.configure({
      optional: ['es7.objectRestSpread']
  });
  var b = browserify({
    entries: './app/main.js',
    debug: true,
    extensions: ['.jsx', '.js'],
    cache: {},
    packageCache: {},
    fullPaths: true
  })
  .transform(babel);

  if(watch) {
    // if watch is enable, wrap this bundle inside watchify
    b = watchify(b);
    b.on('update', function(ids) {
      //run the linting step
      lint(ids);

      //run the watchify bundle step
      gutil.log(gutil.colors.blue('watchify'), 'Started');
      bundleShare(b);
    });
    b.on('time', function (time) {
      gutil.log(gutil.colors.blue('watchify'), 'Finished', 'after', gutil.colors.magenta(time), gutil.colors.magenta('ms'));
    });
  }

  bundleShare(b);
}

function bundleShare(b) {
  b.bundle()
    .pipe(source('main.min.js'))
    .pipe(gulp.dest('./dist'));
}

function lint(glob) {
  return gulp.src(glob)
    .pipe(eslint())
    .pipe(eslint.format())
    .pipe(eslint.failOnError());
}

问题在于linting步骤是异步的,因此在捆绑完成之前它不会完成(它还会抛出异常,所以我可能需要使用plumber来防止它终止watch步骤)。
那么,在调用bundleShared之前,我该如何设置前置条件呢?

你解决了这个问题吗? - Loknar
不行。我只能让它们并排运行,所以有时会错过 ESLint 错误。 - Aaron Powell
1
我在想是否可以通过将闭包传递给watchify.on('update', func)来实现?https://github.com/substack/watchify 我会尝试一下并让您知道。 - Matthew Herbst
1个回答

2
我能够使用我之前提到的闭包方法来完成这个任务。我还将我的Browserify和Watchify代码移动到帮助函数中,以便每个构建都可以利用它们。

gulpfile.js(部分)

gulp.task('build:dev', buildDev); 
gulp.task('lint:js', lintJS);

function lintJS(callback) {
  return gulp.src(['src/**/*.js', 'src/**/*.jsx', '!src/js/vendor/**/*.*',])
      .pipe(eslint())
      .pipe(eslint.format())
      .pipe(eslint.failAfterError());
}

function buildDev(callback) {
  var bundler = getBundler('src/js/app.jsx', { debug: true }, callback);
  var watcher = getWatcher(bundler, rebundle);

  function rebundle() {
    lintJS(callback);

    return watcher.bundle()
      .pipe(source('bundle.min.js'))
      .pipe(buffer())
      .pipe(gulp.dest('dist/js'));
  }

  rebundle();
  // Call watch methods here, i.e.: watchHTML()
  return callback();
}

/****************************** Helper functions ******************************/

/**
 * Gets the default Browserify bundler used by all builds.
 *
 *
 * @param path A string representing where Browserify should start from
 * @param options An Object containing options for the bundler
 * @param callback The Gulp callback function from the calling task
 * @return A basically configured Browserify bundler
 */
function getBundler(path, options, callback) {
  var bundler = browserify(path, { debug: options.debug, cache: {}, packageCache: {} });
  bundler.transform(babelify);
  bundler.on('log', gutil.log);
  bundler.on('error', gutil.log.bind(gutil.colors.red, 'Browserify Error'));

  return bundler;
}

/**
 * Gets the default Watchify watcher used by dev builds. By default, the watcher
 * will rebundle the Browserify package when an update occurs.
 *
 * @param bundle The Browserify bundler object
 * @param rebundle A function to perform when Watchify detects a code update
 * @return A basically configured Watchify watcher
 */
function getWatcher(bundle, rebundle) {
  var watcher = watchify(bundle);
  watcher.on('update', rebundle);

  return watcher;
}

对于我的测试和生产构建,我不使用Watchify(因此没有rebundle()方法),所以我将'lint:js'任务作为依赖项:

gulp.task('build:test', ['lint:js'], buildTest);
gulp.task('build:prod', ['lint:js'], buildProd);

谢谢!如果我想在观察功能中运行实时重新加载服务器,那么在您的配置文件中应该放在哪里? - Olivier Lance
buildDev中调用rebundle()之后,你真正想做的是在dist/文件夹上创建一个监视任务。这样,每当dist/发生变化时,你的监视任务就会检测到并运行服务器重新加载代码。我已经更新了代码,并添加了一个注释来显示它应该放在哪里。 - Matthew Herbst
你可以轻松地将我的函数分解成几个相互依赖的任务。然后只需调用根任务,你就不应该遇到任何问题了。 - Matthew Herbst
对于第一次调用,是可以的,但是当文件发生更改时,它只会调用给定的 rebundle() 函数,而不是任务及其依赖项... 我不确定我表达清楚了吗?:\ - Olivier Lance
哎呀,我现在有点想不明白(这里是凌晨3点...),而且这不是聊天室...所以感谢你的帮助@MatthewHerbst,我稍后再考虑一下! - Olivier Lance
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接