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
Это обеспечит репликацию именованной папки модуля и нумерованной папки (из исходных каталогов) в путь назначения.