Grunt监听:仅上传已更改的文件

9

相关链接

我成功地设置了一个 Grunt 任务,使用 grunt-ssh 将文件通过 SFTP 上传到我的开发服务器:

sftp: {
    dev: {
        files: {
            './': ['**','!{node_modules,artifacts,sql,logs}/**'],
        },
        options: {
            path: '/path/to/project',
            privateKey: grunt.file.read(process.env.HOME+'/.ssh/id_rsa'),
            host: '111.111.111.111',
            port: 22,
            username: 'marksthebest',
        }
    }
},

但是当我运行它时,它会上传所有内容。有成千上万个文件。我没有时间等待每次修改文件时一个一个地上传。
我该如何设置监视器,只上传我已更改的文件,以及在我更改它们后立即上传?
(对于好奇的人,服务器是本地网络上的虚拟机。它运行在不同的操作系统上,设置与生产环境更相似。如果我能正确地让它工作,上传速度应该非常快)
5个回答

7
你所需要的是grunt-newer,它是一种任务,专门根据刚刚更改的文件更新任何依赖于它的任务的配置,然后运行它。一个示例配置可能如下所示:
watch: {
  all: {
    files: ['**','!{node_modules,artifacts,sql,logs}/**'],
    tasks: ['newer:sftp:dev']
  }
}

这在实践中似乎效果不太好...它正在上传所有东西,而且速度非常慢。我不确定第二次它是否只会上传新的东西,但我不认为我有耐心等几个小时。我想我的IDE捆绑并上传了一些东西,所以速度更快。手表也需要很长时间才能启动,但我认为这是SFTP的问题。 - mpen
3
我可以看到问题所在。你尝试过使用rsync吗?它只会上传更改的文件部分,因此与传统的FTP相比速度超级快。还有一个grunt包装器可供使用:https://github.com/jedrichards/grunt-rsync。 - Ben
哇。 rsync 上传整个项目目录的速度快了一亿倍,而且设置起来非常容易,但它与 newer 不兼容。我在 ticket 上向他们提出了问题;不确定这是新版本的错误还是我弄错了什么。 - mpen

5
你可以使用grunt-contrib-watchwatch事件来完成这个任务。基本上,你需要处理watch事件,修改sftp文件配置以仅包括更改的文件,然后让grunt运行sftp任务。
类似于这样:
module.exports = function(grunt) {
    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),
        secret: grunt.file.readJSON('secret.json'),
        watch: {
            test: {
                files: 'files/**/*',
                tasks: 'sftp',
                options: {
                    spawn: false
                }
            }
        },
        sftp: {
          test: {
            files: {
              "./": "files/**/*"
            },
            options: {
              path: '/path/on/the/server/',
              srcBasePath: 'files/',
              host: 'hostname.com',
              username: '<%= secret.username %>',
              password: '<%= secret.password %>',
              showProgress: true
            }
          }
        }
    }); // end grunt.initConfig

    // on watch events configure sftp.test.files to only run on changed file
    grunt.event.on('watch', function(action, filepath) {
        grunt.config('sftp.test.files', {"./": filepath});
    });

    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.loadNpmTasks('grunt-ssh');
};

请注意 "spawn: false" 选项,以及您需要在事件处理程序内设置配置的方式。
注2:此代码每次只会上传一个文件,同一链接中有更强大的方法。

3
你可以使用Grunt来实现这个目标:
  • grunt-contrib-watch

  • grunt-rsync

首先,我正在使用Docker容器。我还在我的Docker容器中添加了一个公共SSH密钥。因此,我只上传了在本地环境中发生更改的文件到我的“远程”容器中,使用以下Grunt任务:

'use strict';

module.exports = function(grunt) {

    grunt.initConfig({

        rsync: {
            options: {
                args: ['-avz', '--verbose', '--delete'],
                exclude: ['.git*', 'cache', 'log'],
                recursive: true
            },
            development: {
                options: {
                    src: './',
                    dest: '/var/www/development',
                    host: 'root@www.localhost.com',
                    port: 2222
                }
            }
        },

        sshexec: {
            development: {
                command: 'chown -R www-data:www-data /var/www/development',
                options: {
                    host: 'www.localhost.com',
                    username: 'root',
                    port: 2222,
                    privateKey: grunt.file.read("/Users/YOUR_USER/.ssh/id_containers_rsa")
                }
            }
        },

        watch: {
            development: {
                files: [
                'node_modules',
                'package.json',
                'Gruntfile.js',
                '.gitignore',
                '.htaccess',
                'README.md',
                'config/*',
                'modules/*',
                'themes/*',
                '!cache/*',
                '!log/*'
                ],
                tasks: ['rsync:development', 'sshexec:development']
            }
        },

    });

    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.loadNpmTasks('grunt-rsync');
    grunt.loadNpmTasks('grunt-ssh');

    grunt.registerTask('default', ['watch:development']);
};

祝好运并享受黑客乐趣!


2

我最近遇到了一个类似的问题,我想只上传已更改的文件。我只使用grunt-exec。如果您可以访问服务器的ssh,则可以以更高的效率执行此任务。我还创建了一个被git忽略的rsync.json,这样协作者就可以拥有自己的rsync数据。

好处是,如果有人进行更改,它会自动上传到他们的阶段。

    // Watch - runs tasks when any changes are detected.
    watch: {
        scripts: {
            files: '**/*',
            tasks: ['deploy'],
            options: {
                spawn: false
            }
        }
    }

我的部署任务是一个已注册的任务,它编译脚本,然后运行exec:deploy

   // Showing exec:deploy task 
   // Using rsync with ssh keys instead of login/pass
    exec: {
        deploy: {
            cmd: 'rsync public_html/* <%= rsync.options %> <%= rsync.user %>@<%= rsync.host %>:<%=rsync.path %>'
    }

你看到了很多<%= rsync %>这样的东西吗?我用它来从rysnc.json中获取信息,而这个文件被git忽略了。我之所以有这个文件,是因为这是一个团队工作流程。

// rsync.json
{
  "options": "-rvp --progress -a --delete -e 'ssh -q'",
  "user": "mmcfarland",
  "host": "example.com",
  "path": "~/stage/public_html"
}

请确保在grunt中定义了rsync.json

module.exports = function(grunt) {

  var rsync = grunt.file.readJSON('path/to/rsync.json');
  var pkg = grunt.file.readJSON('path/to/package.json');

  grunt.initConfig({
    pkg: pkg,
    rsync: rsync,

1
看起来非常不错!谢谢分享! - mpen

0

我认为一次性将所有更改上传到暂存服务器并在暂存服务器上工作都不是一个好主意。你需要配置本地机器服务器,使其与暂存/生产环境相同。

最好的方法是在部署时只上传一次。

您可以使用grunt-contrib-compress归档所有文件。然后使用grunt-ssh将它们作为1个文件推送,然后在服务器上提取它,这样会更快。

这是压缩任务的示例:

compress: {
            main: {
                options:{
                    archive:'build/build.tar.gz',
                    mode: 'tgz'
                },
                files: [
                    {cwd: 'build/', src: ['sites/all/modules/**'], dest:'./'},
                    {cwd: 'build/', src: ['sites/all/themes/**'], dest:'./'},
                    {cwd: 'build/', src: ['sites/default/files/**'], dest:'./'}
                ]
            }
        }

附注:从未查看过rsync grunt模块。 我明白这可能不是你要找的。但我决定将我的答案作为独立回答。


这不完全是一个严格的分阶段,只是我们办公室里的另一台机器。我猜这样我们的服务器管理员可以更轻松地管理所有虚拟机,但是除此之外,我同意--我通常在本地开发或使用 Vagrant。不过,这个压缩想法以后会很有用的,谢谢! - mpen

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