Javascript 你如何在 Grunt.js 中观看多个文件,但只在更改的文件上运行任务?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12063266/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 07:02:24  来源:igfitidea点击:

How do you watch multiple files, but only run task on changed file, in Grunt.js?

javascriptnode.jsgruntjs

提问by Lance Pollard

In learning how to use grunt, I am trying to make a simple coffee-script watcher/compiler. The problem is, if I tell the watchtask to watch several files, and one changes, it is going to pass all of the files to the coffeecommand. This means when you change 1 file, it's going to recompile allof the files matching the srcpattern. Instead, I want to only recompile the single file that changed that matches the srcpattern.

在学习如何使用grunt 时,我正在尝试制作一个简单的咖啡脚本观察器/编译器。问题是,如果我告诉watch任务观察多个文件,并且其中一个发生变化,它会将所有文件传递给coffee命令。这意味着当您更改 1 个文件时,它将重新编译与该模式匹配的所有文件src。相反,我只想重新编译与src模式匹配的更改的单个文件。

Here is the grunt.js:

这是grunt.js

module.exports = function(grunt) {
  grunt.initConfig({
    coffee: {
      app: {
        src: ['test/cases/controller/*.coffee'],
        dest: 'tmp',
        options: {
          bare: true,
          preserve_dirs: true
        }
      }
    },
    watch: {
      files: ['<config:coffee.app.src>'],
      tasks: ['coffee:app']
    }
  });

  grunt.loadNpmTasks('grunt-coffee');
  grunt.registerTask('default', 'coffee');
};

This is using grunt-coffee, which is basically this: https://gist.github.com/2373159.

这是使用grunt-coffee,基本上是这样的:https: //gist.github.com/2373159

When I run grunt watch, and I save a file in test/cases/controller/*.coffee, it compiles allof the matching files (putting them in tmp/*).

当我运行grunt watch并将文件保存在 中时test/cases/controller/*.coffee,它会编译所有匹配的文件(将它们放入 中tmp/*)。

How do you instead only compile the changedfileusing grunt?

你如何使用 grunt编译更改过的文件

回答by Cowboy Ben Alman

The upcoming (and currently in-development) v0.4.0a grunt has the grunt.file.watchFilesobject, which was designed expressly for this purpose. The grunt-coffee plugin may have added support for this feature already, I'm not sure.

即将推出(目前正在开发)的 v0.4.0a grunt 有grunt.file.watchFiles对象,它是专门为此目的而设计的。grunt-coffee 插件可能已经添加了对这个功能的支持,我不确定。

Either way, if you're interested in trying an in-development version of grunt in your project, check out the When will I be able to use in-development feature 'X'?FAQ entry.

无论哪种方式,如果您有兴趣在您的项目中尝试开发中的 grunt 版本,请查看我何时能够使用开发中的功能“X”?常见问题入口。

回答by blachniet

I got this working when compiling my less files. You should be able to mess with this configuration a little bit to git it working with the coffeescript plugin. The portion of interest is the grunt.event.on('watch', ...). In this event handler I'm updating the filesproperty in the less command to only contain the changed file.

我在编译我的 less 文件时得到了这个工作。你应该能够稍微弄乱这个配置,让它与 coffeescript 插件一起工作。感兴趣的部分是grunt.event.on('watch', ...)。在此事件处理程序中,我正在更新filesless 命令中的属性以仅包含更改的文件。

path = require('path');

module.exports = function(grunt) {

  // Project configuration.
  grunt.initConfig({

    pkg: grunt.file.readJSON('package.json'),

    less: {
      development: {
        options: {
          paths: ["./library/less"],
        },
        files: [
          { src: "./library/less/bootstrap.less", dest: "./library/css/bootstrap.css"},
          { src: "./library/less/app.less", dest: "./library/css/app.css"}
        ]
      }
    },

    watch: {
      styles: {
        files: "./library/less/*",
        tasks: ["less"],
        options: {
          nospawn: true,
        },
      },
    },
  });

  // Event handling
  grunt.event.on('watch', function(action, filepath){
    // Update the config to only build the changed less file.
    grunt.config(['less', 'development', 'files'], [
      {src: filepath, dest: './library/css/' + path.basename(filepath, '.less') + '.css'}
    ]);
  });

  // Load the plugins
  grunt.loadNpmTasks('grunt-contrib-less');
  grunt.loadNpmTasks('grunt-contrib-watch');

  // Tasks
  grunt.registerTask('default', ['watch']);
};

回答by Ryan Smith

None of these answers worked very well for me. Here is my solution if anyone is interested (I know I'm a little late in replying to this question).

这些答案都不适合我。如果有人感兴趣,这是我的解决方案(我知道我回答这个问题有点晚了)。

https://gist.github.com/ryansmith94/8569178

https://gist.github.com/ryansmith94/8569178

回答by Lajos Veres

https://github.com/tschaub/grunt-newerlooks like exactly for similar tasks:

https://github.com/tschaub/grunt-newer看起来与类似任务完​​全一样:

Configure Grunt tasks to run with newer files only.

Synopsis: The newer task will configure another task to run with src files that are a) newer than the dest files or b) newer than the last successful run (if there are no dest files). See below for examples and more detail.

将 Grunt 任务配置为仅使用较新的文件运行。

概要:较新的任务将配置另一个任务以使用 a) 比 dest 文件新或 b) 比上次成功运行(如果没有 dest 文件)新的 src 文件运行。有关示例和更多详细信息,请参见下文。

You can prepend easily to any task. In your case:

您可以轻松地添加到任何任务。在你的情况下:

  grunt.loadNpmTasks('grunt-newer');
  grunt.registerTask('default', 'newer:coffee');

回答by luissquall

In this issue, Kyle Robinson suggests using the watchevent. It's very important to set watch task nospawnproperty to trueto make it work. I modified his solution to selectively run the tasks:

本期中,Kyle Robinson 建议使用该watch事件。将监视任务nospawn属性设置true为使其工作非常重要。我修改了他的解决方案以有选择地运行任务:

grunt.event.on('watch', function(action, filepath) {
    if (minimatch(filepath, grunt.config('watch.stylesheets.files'))) {
        grunt.config('compass.dist.options.specify', [filepath]);
    }

    if (minimatch(filepath, grunt.config('watch.scripts.files'))) {
        var uglifySrc = filepath.replace(grunt.config('uglify.dist.cwd'), '');
        grunt.config('jshint.dist.src', [filepath]);
        grunt.config('uglify.dist.src', [uglifySrc]);
    }
});

Here is the complete solution: https://gist.github.com/luissquall/5408257

这是完整的解决方案:https: //gist.github.com/luissquall/5408257

回答by Michael

So new to Grunt 0.4 is more named tasks

所以 Grunt 0.4 的新功能是更多命名任务

Let us give you an example!

让我们给你举个例子!

watch: {
    package1: {
        files: [
            './modules/package1/**/*.coffee'
        ],
        tasks: ['coffee:package3']
    },
    package2: {
        files: [
            './test_packages/package2/**/*.coffee'
        ],
        tasks: ['coffee:package3']
    },
    package3: {
        files: [
            './test_packages/package3/**/*.coffee'
        ],
        tasks: ['coffee:package3']
    },
}

To run all those watch tasks, simply do grunt.registerTask('default', ['myInitialBuild', 'watch']);

要运行所有这些监视任务,只需执行 grunt.registerTask('default', ['myInitialBuild', 'watch']);

Where myInitialBuildis whatever initial build (all of the files) then follow it up with a watch on each package. In reality you could do this for every file but that sounds sucky.

myInitialBuild无论初始构建(所有文件)在哪里,然后在每个包上观察它。实际上,您可以对每个文件都执行此操作,但这听起来很糟糕。

回答by smets.kevin

The task grunt-contrib-watch now supports this.

任务 grunt-contrib-watch 现在支持这一点。

https://npmjs.org/package/grunt-contrib-watch-> look for "Compiling Files As Needed"

https://npmjs.org/package/grunt-contrib-watch-> 寻找“根据需要编译文件”

grunt.initConfig({
  watch: {
    scripts: {
      files: ['lib/*.js'],
      tasks: ['jshint'],
      options: {
        nospawn: true,
      },
    },
  },
  jshint: {
    all: ['lib/*.js'],
  },
});

// on watch events configure jshint:all to only run on changed file
grunt.event.on('watch', function(action, filepath) {
  grunt.config(['jshint', 'all'], filepath);
});

This should prevent the tasks from compiling all files every time when something changes.

这应该可以防止任务每次发生变化时编译所有文件。