Grunt:监视多个文件,只编译更改的文件 - livereload会出现问题?

7

我对Grunt和Javascript/Coffeescript完全不熟悉。

我们在一个非常大的项目中使用Grunt,其中有数百个.coffee文件。由于Grunt编译了所有的coffeefiles(尽管只有一个文件发生了更改),我的最初问题是如何让Grunt仅编译已更改的文件。 通过stackoverflow,我能够回答这个问题,谢谢大家:)

但现在似乎实施的解决方案破坏了livereload。当我用“grunt server”开始并在浏览器中显示我的页面时,一切看起来都很好。然后我改变了一个.coffee文件并保存它。文件被编译了(我检查过),但我的浏览器从未重新加载。只有当我手动重新加载浏览器时,新修改的代码才会显示。

所以问题是:为什么livereload不再起作用?

我不知道这是否重要,但Gruntfile是在旧版本中使用yeoman创建的(带有grunt-regarde)。我更新了package.json和Gruntfile以使用grunt-contrib-watch和内置的livereload的较新规范。没有grunt.event.on一切正常。

来源(部分):

grunt.initConfig({

    watch: {
            coffee: {
                files: ['<%= yeoman.app %>/coffeescripts/**/*.coffee'],
                tasks: ['coffee:app'],
                options: {
                    nospawn: true
                },
            },
            compass: {
                files: ['<%= yeoman.app %>/styles/**/*.{scss,sass}'],
                tasks: ['compass']
            },
            templates: {
                files: ['<%= yeoman.app %>/templates/**/*.tpl'],
                tasks: ['handlebars']
            },
            livereload: {
                options: {
                    livereload: LIVERELOAD_PORT
                },
                files: [
                    '<%= yeoman.app %>/*.html',
                    '<%= yeoman.tmp %>/styles/**/*.css',
                    '<%= yeoman.tmp %>/scripts/**/*.js',
                    '<%= yeoman.tmp %>/spec/**/*.js',
                    '<%= yeoman.app %>/img/{,*/}*.{png,jpg,jpeg,webp}',
                ]
            }
        },
        coffee: {
            app: {
                expand: true,
                cwd: '<%= yeoman.app %>/coffeescripts',
                src: '**/*.coffee',
                dest: '<%= yeoman.tmp %>/scripts',
                ext: '.js',
                options: {
                    runtime: 'inline',
                    sourceMap: true
                },
            }
        }
    }
});

grunt.event.on('watch', function(action, filepath) {
    filepath = filepath.replace(grunt.config('coffee.app.cwd')+'/', '' );
    grunt.config('coffee.app.src', [filepath]);
});

grunt.registerTask('server', function (target) {
    if (target === 'dist') {
        return grunt.task.run(['build', 'open', 'connect:dist:keepalive']);
    }

    grunt.task.run([
        'clean:server',
        'coffee',
        'compass:server',
        'symlink:bower',
        'connect:livereload',
        'handlebars',
        'notify:watch',
        'watch'
    ]);
});

grunt-contrib-watch与版本v0.4.4一起使用, connect-livereload与版本0.2.0一起使用。


你使用的是哪个Watch版本? - imjared
grunt-contrib-watch 与版本 v0.4.4 一起使用,connect-livereload 与版本 0.2.0 一起使用。我已经在上面更新了我的问题,并提供了这些信息。抱歉我忘记了。 - EmilioMg
2个回答

0

我猜你正在寻找的是grunt-concurrent

这是我的方法。(注意它是用CoffeeScript编写的,但你应该很容易地适应它。)

watch:
  compass:
    files: ['private/compass/**/*.scss']
    tasks: ['compass:dist']
    options:
      livereload: true
  coffee:
    options:
      livereload: 34567
    files: ['private/coffee/**/*/.coffee']
    tasks: ['coffee:dist']
  ci:
    options:
      livereload: 34568
    files: ['application/views/**/*.php', 'application/controllers/**/*.php']

concurrent:
  options:
    logConcurrentOutput: true
  dev: ['watch:compass', 'watch:coffee', 'watch:ci']

0

我的解决方案:

grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),
        cssmin: {
            dist: {
                expand: true,
                cwd: 'app',
                src: ['**/*.css'],
                dest: 'WebContent'
            }
        },
        uglify: {
            options: {
                mangle: false
            },
            dist: {
                expand: true,
                cwd: 'app/js',
                src: ['**/*.js'],
                dest: 'WebContent/js'
            }
        },
        htmlmin: {
            options: {
                collapseWhitespace: true
            },
            dist: {
                expand: true,
                cwd: 'app',
                src: ['**/*.html'],
                dest: 'WebContent'
            }
        },
        watch: {
            options: {
                spawn: false
            },
            cssmin: {
                files: 'app/css/**/*.css',
                tasks: ['cssmin']
            },
            uglify: {
                files: 'app/js/**/*.js',
                tasks: ['uglify']
            },
            htmlmin: {
                files: 'app/**/*.html',
                tasks: ['htmlmin']
            }
        },
    });

    // Faz com que seja salvo somente o arquivo que foi alterado
    grunt.event.on('watch', function(action, filepath) {
        var tasks = ['cssmin', 'uglify', 'htmlmin'];

        for (var i=0, len=tasks.length; i < tasks.length; i++) {
            var taskName = tasks[i];

            if (grunt.file.isMatch(grunt.config('watch.'+ taskName +'.files'), filepath)) {
                var cwd = new String(grunt.config(taskName + '.dist.cwd')).split('/').join('\\') + '\\'; //inverte as barras e adiciona uma "\" no final
                var pathWithoutCwd = filepath.replace(cwd, ''); //obtem somente o path sem o cwd

                grunt.config(taskName + '.dist.src', pathWithoutCwd); //configura a task
            }   
        }
    });

    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.loadNpmTasks('grunt-contrib-cssmin');
    grunt.loadNpmTasks('grunt-contrib-uglify');
    grunt.loadNpmTasks('grunt-contrib-htmlmin');

    // Tarefas padrão
    grunt.registerTask('default', ['cssmin', 'uglify', 'htmlmin']);
};

谢谢你的回答,但是这并没有起作用。 在对代码进行了一些小修改以使其在我的环境下运行后,我尝试了你的代码,但是虽然只编译了修改后的咖啡文件,但之后livereload任务从未被触发 :( - EmilioMg

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