复制任务的 Grunt 循环,但只复制最后一个文件

Grunt loop for copy task, but copying only last file

你能帮我解决这个问题吗?

我正在尝试在 Gruntfile.js 中创建一个函数,使用循环将模板文件复制到我的项目,并将 .json 文件复制到 "automate" 一个复制作业,显然该函数看起来很棒,因为 Grunt 根据 .json 文件中的记录数运行复制作业,在循环中使用 grunt.log.write Grunt 显示 .json 文件的名称,但实际上它只复制最后注册的文件。

首先是我的 .json 文件:

{
    "config": {
        "modules": [
            {"name": "footer", "number": 2},
            {"name": "header", "number": 1}
        ]
    }
}

我的第二个带有循环变量的复制任务:

copy: {
    core: {
        files: [{
            expand: true,
            cwd: "core/<%=grunt.option('coreName')%>/<%=grunt.option('coreNumber')%>/",
            src: "**",
            dest: "../sass/2_deploy/core/"
        }]
    }
}

目的是获取"header /1/"、"footer/2/"版本目录下的文件,按照上面的代码调入deploy目录。

第三,这是读取.json文件并声明变量并在循环内执行任务的函数:

function moveCoreFiles() {
    var models = require('./variables.json');
    var cores = models.config.modules;
    for (core in cores) {
        grunt.option('coreName', cores[core].name);
        grunt.option('coreNumber', cores[core].number);
        grunt.task.run('copy:core');
        grunt.log.write(grunt.option("coreName"));
    }
}
// ... enter code here
grunt.registerTask('moveCore', moveCoreFiles);

此时,执行任务时,Grunt returns这个信息:

$ grunt moveCore
Running "moveCore" task
footerheader
Running "copy:core" (copy) task
Copied 1 file

Running "copy:core" (copy) task
Copied 1 file

从任务的描述来看,grunt 似乎对每条记录执行了两次任务一,但实际上它只是将最后一个 "header" 文件移动到目录中,我的问题是,如果这种类型的确实可以采取行动,或者我是否应该放弃 Gruntfile 中的循环。

非常感谢您的帮助! 问候!

我认为你应该构建一个要复制的文件数组,然后将该数组传递给任务,所以grunt将运行任务对所有文件夹只复制一次,而不是运行多次执行任务。

首先定义将创建要复制的文件数组的函数:

function getFiles() {
    var models = require('./variables.json');
    var cores = models.config.modules;
    var files = [];
    for (var core in cores) {
        files.push({
            expand: true,
            cwd: "core/" + cores[core].name + "/" + cores[core].number + "/",
            src: "**",
            dest: "../sass/2_deploy/core/"
        });
        grunt.log.write("core/" + cores[core].name + "/" + cores[core].number + "/\r\n");
    }
    return files;
}

然后,定义 copy 任务以使用文件数组:

grunt.initConfig({
    copy: {
        core: {
            files: getFiles()
        }
    }
});

然后定义任务即可:

grunt.registerTask('default', ['copy:core']);

生成的 Gruntfile.js 将如下所示:

module.exports = function(grunt) {

    function getFiles() {
        var models = require('./variables.json');
        var cores = models.config.modules;
        var files = [];
        for (var core in cores) {
            files.push({
                expand: true,
                cwd: "core/" + cores[core].name + "/" + cores[core].number + "/",
                src: "**",
                dest: "../sass/2_deploy/core/"
            });
            grunt.log.write("core/" + cores[core].name + "/" + cores[core].number + "/\r\n");
        }
        return files;
    }

    grunt.initConfig({
        copy: {
            core: {
                files: getFiles()
            }
        }
    });

    grunt.loadNpmTasks('grunt-contrib-copy');

    grunt.registerTask('default', ['copy:core']);

};

希望对您有所帮助!

您可以动态配置任务target (i.e. copy:core) via a separate Custom Task

在下面的示例 Gruntfile.js 中,我们根据 variables.jsonmodules 数组中的每个条目动态配置 copy:core 目标,在 运行 之前任务。这由 configCopyCoreAndRun 任务处理。

Gruntfile.js

module.exports = function (grunt) {

  grunt.loadNpmTasks('grunt-contrib-copy');

  grunt.initConfig({
    copy: {
      // <-- `core` target is intentionally not defined. It will be
      //      configured, set, and run by configCopyCoreAndRun task.  
      anotherTarget: {
        src: './variables.json',
        dest: '../sass/2_deploy/'
      }
    }
  });

  /**
   * Custom Helper function dynamically configures the `core` target in
   * `copy` task, based on data entered in an external `.json` file.
   */
  grunt.registerTask('configCopyCoreAndRun', function() {
    var modules = grunt.file.readJSON('./variables.json').config.modules;
    var core = {files: []};

    modules.forEach(function(module) {
      core.files.push({
        expand: true,
        cwd: 'core/' + module.name + '/' + module.number,
        src: '**',
        dest: '../sass/2_deploy/core/'
      })
    });

    grunt.config.set('copy.core', core);
    grunt.task.run('copy:core');
  });

  // We call `configCopyAndRun` then `copy:anotherTask` to demonstrate
  // that other copy target(s) can also exist and be used.
  grunt.registerTask('default', ['configCopyCoreAndRun', 'copy:anotherTarget']);
};

注:

为避免文件(同名)在将多个资产复制到 dest 目录(即 ../sass/2_deploy/core/)时被覆盖的可能性,您可能需要考虑更改此行在上面的 Grunfile.js 中:

dest: '../sass/2_deploy/core/'

改成这样:

dest: '../sass/2_deploy/core/' + module.name + '/' + module.number

这将确保命名模块文件夹和(源目录的)编号文件夹在目标路径中得到复制。