仅当src中有更改时才运行构建

时间:2015-07-02 18:30:46

标签: javascript angularjs build gruntjs protractor

故事:

我们有一个测试人员团队致力于使用量角器为我们的内部AngularJS应用程序自动化端到端测试。以下是他们通常为“本地”测试运行的任务:

grunt.registerTask('e2e:local', [
    'build:prod',
    'connect:test',
    'protractor:local'
]);

它运行“构建”任务,启动网络服务器并针对本地构建运行e2e测试。

build:prod任务本身定义为:

grunt.registerTask(
    'build:prod', [
        'clean',
        'copy:all',
        'copy:assets',
        'wiredep',
        'ngtemplates',
        'useminPrepare',
        'concat',
        'ngAnnotate',
        'autoprefixer',
        'uglify',
        'cssmin',
        'copy:cssfix',
        'usemin',
        'copy:html',
        'bowercopy',
        'template:setProdVersion'
    ]
);

这里我们有很多子任务(它肯定可以改进,但这就是它现在的样子)。

问题:

目前,构建完成大约需要25秒。而且,每当一个人运行端到端测试时,都会执行构建任务。

问题:

如果build:prod目录中有更改,我该如何运行src任务?

请注意,此处的要求是使运行测试的测试人员透明。我不希望他们记住何时需要执行构建,何时不需要。

换句话说,该过程应该是自动化的。目标是自动检测是否需要构建。

请注意,理想情况下我希望保持构建任务不变,因此如果直接通过grunt build:prod调用它,则无论前一版本的日期戳是什么,它都会重建。

思考和尝试:

  • 存在密切相关的grunt-newer package,但是,由于我们有一个相当复杂的构建,在开头有一个clean任务,我不知道如何将它应用于我的情况下

  • 我还在考虑的是,在e2e:local任务中,手动检查distsrc内的文件的时间戳,然后根据该值确定如果需要调用build:prod。我认为这是grunt-newer内部正在做的事情

  • 我们开始使用有助于改善效果的jit-grunt

6 个答案:

答案 0 :(得分:6)

如果您使用git:

,这是一个想法

如何使用像grunt-gitinfo这样的东西并使用HEAD中的最后一次提交作为基础?

这个想法是:

  • 您创建了一个新的grunt任务,用于检查最新的提交哈希值
  • 您将此提交哈希保存在已添加到gitignore的文件中(并且不在clean文件夹中,通常可以在回购根目录中)
  • 在保存到文件之前,它会检查其中已有的值(标准节点fs模块可以轻松进行读/写)
  • 如果哈希不匹配,请运行build:prod任务,然后保存新提交哈希
  • 测试人员的构建取决于您的新任务,而不是直接build:prod

另一种选择(仍然使用git):

您可以使用类似grunt-githooks的内容并创建一个在pull之后运行并调用git build:prod的git钩子,然后您可以从测试人员运行的grunt任务的依赖项中删除它。

您可能有另一个代码来检查githook并在必要时安装它,这可能是测试人员的一次性额外步骤,或者可能是他们调用的grunt任务。

答案 1 :(得分:5)

我很惊讶没有人提到grunt-contrib-watch(它在gruntjs.com示例文件中,我认为它是众所周知的!)。来自github:“每当添加,更改或删除观看的文件模式时运行预定义的任务。” - 下面是一个样本grunt文件,它可以在src /或test /中修改任何.js文件时运行你的任务,或者如果修改了Gruntfile。

var filesToWatch = ['Gruntfile.js', 'src/**/*.js', 'test/**/*.js'];
grunt.initConfig({
    watch: {
        files: filesToWatch,
        tasks: ['build:prod',
                'connect:test',
                'protractor:local']
    }
});
grunt.loadNpmTasks('grunt-contrib-watch');

您的开发人员在开始修改文件之前打开终端并运行grunt watch,每次修改这些文件时,任务都会自动运行(不再返回终端运行{{1}每一次)。

这是一个很棒的套餐,我建议你看一下。 - github - npmjs.org

grunt build:prod

答案 2 :(得分:2)

不是grunt所要求的答案,但使用gulp可以很容易。

var fs = require('fs');
var gulpif = require('gulp-if');

var sourceChanged = fs.statSync('build/directory').mtime > fs.statSync('source/directory').mtime;

gulp.task('build:prod', function() {
  if (!sourceChanged) {
    return false;
  } 
  return gulp.src('./src/*.js')
    .pipe(.... build ....)
    .pipe(gulp.dest('./dist/'));
});

答案 3 :(得分:2)

以下是我们为构建做了一些Git HEAD sha工作的方法。我们使用它来确定当前部署到我们的生产环境的版本 - 但是我很确定你可以重做它来返回一个布尔值并触发构建,如果真的。

<强> Gruntfile.js

function getHeadSha() {
  var curr, match, next = 'HEAD';
  var repoDir = process.env.GIT_REPO_DIR || path.join(__dirname, '..');
  try {
    do {
      curr  = grunt.file.read(path.join(repoDir, '.git', next)).trim();
      match = curr.match(/^ref: (.+)$/);
      next  = match && match[1];
    } while (next);
  } catch(ex) {
    curr = 'not-found';
  }

  return curr;
}

grunt.initConfig({
  replace: {
    applicationVersion: {
      src:  '<%= config.dist %>/index.html',
      overwrite: true,
      replacements: [{
        from: '{{APPLICATION_VERSION}}',
        to:   getHeadSha
      }]
    }
  }
});

grunt.registerTask('build', {
  'replace:applicationVersion',
  /** other tasks **/
});

grunt.registerTask('e2e:local', {
  'check_if_we_should_build',
  /** other tasks **/
});

<强>的index.html

<html data-version="{{APPLICATION_VERSION}}">
  <!-- -->
</html>

还有git-info包可以简化整个过程,我们正在考虑切换到自己。

编辑; 我刚注意到@meligy已经指向了git-info的方向。信用到期的信用。

答案 4 :(得分:1)

我不确定它是否有用,但我们在使用GULP framework的项目中完成了相同的操作。我们在gulp中编写了一个观察器,它不断检查源更改并运行快速功能来构建项目。它是一个量角器测试案例。

gulp.task('dome', function () {


    gulp.src(["maintest.js"])
        .pipe(notify("Change Found , Executing Scripts."))
        .pipe(protractor({

            configFile: "conf.js",
            args: ['--baseUrl', 'http://127.0.0.1:8000']


        })).on('error', function (e) {
        throw e
    });
})


gulp.task('default', function () {


    gulp.watch('./webpages/*.js', ['dome']);
    gulp.watch('maintest.js', ['dome']);
    gulp.watch('conf.js', ['dome']);
});

Link to repo.

答案 5 :(得分:0)

我没有量角器的经验,但从概念上讲,我认为这可行。

我建议只在{/ 1}}命令返回true时在〜/ .cshrc中设置别名才能运行构建命令。

diff

只需用git使用的任何内容替换#./cshrc alias build_on_diff 'diff -r branch_dir_1 branch_dir_2\ if ( $status == 1 ) then\ build:prod\ endif' 命令,它应该可以工作,前提是它为检测到的差异返回1状态。我们在工作场所应用类似的方法,以避免重建尚未更改的文件。