Grunt loop для задачи копирования, но копирование только последнего файла

Можете ли вы помочь мне с этой проблемой?

Я пытаюсь создать функцию в Gruntfile.js скопировать файлы шаблона в мой проект с помощью цикла и .json файл, чтобы "автоматизировать" задание копирования, по-видимому, функция выглядит великолепно, потому что Grunt запускает задание копирования в соответствии с количеством записей в .json файл, используя grunt.log.write в цикле Грант показывает имена .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 возвращает эту информацию:

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

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

Из описания задачи кажется, что grunt выполнил задачу одну для каждой записи дважды, но на практике он только переместил последний файл заголовка в каталог, мой вопрос был бы, возможен ли этот тип действия действительно или я следует отказаться от цикла в Gruntfile.

Большое спасибо за помощь! С уважением!

2 ответа

Решение

Я думаю, что вы должны создать массив файлов для копирования, а затем передать массив в задачу, поэтому 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']);

};

Надеюсь, поможет!

Вы можете динамически настроить цель задач (т.е. copy:core) с помощью отдельной пользовательской задачи.

В примере Gruntfile.js ниже мы динамически настраиваем copy:core цель на основе каждой записи в modules Массив в variables.jsonперед запуском задачи. Это обрабатывается 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

Это обеспечит репликацию именованной папки модуля и нумерованной папки (из исходных каталогов) в путь назначения.

Другие вопросы по тегам