Как мне рекурсивно копировать каталоги с помощью gulp?


167

Я пытаюсь организовать проект из рабочего каталога на сервер (на той же машине). Используя следующий код:

gulp.src([
    'index.php',
    'css/**',
    'js/**',
    'src/**',
])
.pipe(gulp.dest('/var/www/'));

Я ожидаю увидеть все скопированные файлы. Однако это выравнивает структуру dir - все каталоги копируются, но каждый файл помещается в корень/var/www

Gulp кажется отличным инструментом для сборки, но копирование элементов должно быть простым процессом?


9
Любому новому зрителю, читающему этот вопрос, следует отметить, что ответ с наибольшим количеством голосов не работает для решения первоначальной спецификации вопроса о неразглаживании каталогов. Это решает проблемы людей , имеющих с не все файлы внутри директории от копирования, так что это полезно!
M1ke

1
Вы не имеете в виду, что вы хотите, чтобы каталоги css, js и src присутствовали /var/www/? Вы можете попробовать{css,js,src}/**/*
Джейсон Гомаат

Я знаю, что расширение glob работает внутри gulp, но я бы запутался, если бы это работало по-разному для каждого элемента как отдельной строки в списке - поскольку расширение glob в основном просто предназначено для расширения до списка перед выполнением.
M1ke

Ответы:


319

Следующее работает без выравнивания структуры папок:

gulp.src(['input/folder/**/*']).pipe(gulp.dest('output/folder'));

Это '**/*'важная часть. Это выражение представляет собой глобус, который является мощным инструментом выбора файлов. Например, для копирования только файлов .js используйте:'input/folder/**/*.js'


2
думаю, что вы забыли добавить gulp.dest. Должно быть.pipe(gulp.dest('output/folder'));
Мэтью Спранкл

3
Как вы делаете это с определенным расширением файла?
Chev

1
Можете ли вы отредактировать ответ, чтобы привести пример для исходного набора файлов? Я не уверен, как это более уместно, но я был бы рад взглянуть на то, как это работает по сравнению с {base:"."}методом.
M1ke

2
Важно отметить, что по baseумолчанию «папка», как указано в этом ответе. Другими словами, основание начинается там, где начинается шаблон глобуса. Это помогло мне понять , где мои файлы будут в конечном итоге , а также , почему вам не нужен **/*в gulp.destпараметре. Gulp берет все в глобус и помещает в папку dest с такой же структурой.
Нил Монро,

3
Это не полностью отвечает на вопрос. Это хорошее решение для правильного рекурсивного копирования, но оно не дает ответа на то, как изменить базовый каталог.
ty1824

173

Оказывается, что для копирования полной структуры каталогов gulpнеобходимо предоставить базу для вашего gulp.src()метода.

Таким образом, gulp.src( [ files ], { "base" : "." })можно использовать в приведенной выше структуре для рекурсивного копирования всех каталогов.

Если, как и я, вы можете забыть об этом, попробуйте:

gulp.copy=function(src,dest){
    return gulp.src(src, {base:"."})
        .pipe(gulp.dest(dest));
};

1
Добавьте конфигурацию "cwd" для установки текущего рабочего каталога.
Скарллот

3
Если вас baseвсе еще смущает, взгляните на stackoverflow.com/a/35848322/11912, который отлично справляется с объяснением.
Джеймс Скемп

60

Итак, решение обеспечения базы работает, учитывая, что все пути имеют один и тот же базовый путь. Но если вы хотите указать разные базовые пути, это все равно не сработает.

Одним из способов решения этой проблемы было создание относительного начала пути. Для вашего случая:

gulp.src([
    'index.php',
    '*css/**/*',
    '*js/**/*',
    '*src/**/*',
])
.pipe(gulp.dest('/var/www/'));

Причина, по которой это работает, заключается в том, что Gulp устанавливает основание как конец первого явного чанка - ведущий * заставляет его устанавливать основание на cwd (что является результатом, которого мы все хотим!)

Это работает, только если вы можете убедиться, что в структуре вашей папки не будет определенных путей, которые могут совпадать дважды. Например, если бы вы были randomjs/на том же уровне, что jsи вы, в конечном итоге вы сопоставите оба.

Это единственный способ, который я нашел, чтобы включить их как часть функции gulp.src верхнего уровня. Вероятно, было бы просто создать плагин / функцию, которая могла бы отделить каждый из этих глобусов, чтобы вы могли указать для них базовый каталог.


Я думаю, что необходимость начинать с нескольких базовых путей, вероятно, выходит за рамки вопроса. Исходя из моего первоначального вопроса, я перемещал файлы по абсолютному пути, но проблема все еще возникала, так как без указания базы все файлы со всех моих глобусов были скопированы в один каталог без соблюдения существующей иерархии.
M1ke

2
@ M1ke Это правда, главное, что ваш вопрос не был направлен на различные базовые пути. Однако вы упомянули However it flattens the dir structure - all directories are copied but every file is placed in the root /var/www, и именно так я и нашел ваш вопрос - я искал решение о том, как рекурсивно копировать с разными базовыми путями. По сути, это решение работает для вашего случая, не требуя указания базы по умолчанию, но также для случая с несколькими базовыми путями, при условии, что вы можете быть уверены, что ведущая звезда ничего не соответствует :)
ty1824

6
Этот ответ является исключительным. В частности, речь идет о копировании пути из произвольной начальной точки, например. Src может быть 'assets/subdir/*fonts/*'скопировать шрифты DIR.
Wtower

-4

Если вы хотите рекурсивно скопировать все содержимое папки в другую папку, вы можете выполнить следующую команду Windows из gulp:

xcopy /path/to/srcfolder /path/to/destfolder /s /e /y

/yВариант в конце, чтобы подавить сообщение перезаписи подтверждения.

В Linux вы можете выполнить следующую команду из gulp:

cp -R /path/to/srcfolder /path/to/destfolder

Вы можете использовать gulp-exec или gulp-run плагин для выполнения системных команд из gulp.

Ссылки по теме:

  1. использование xcopy

  2. глоток и глоток


7
Проблема с возвратом к оболочке заключается в том, что вы потеряете возможность запуска других команд в потоке, таких как инструменты сжатия или аналитики.
M1ke
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.