Como copio diretórios recursivamente com o gulp?

167

Estou tentando preparar um projeto de um diretório ativo para um servidor (mesma máquina). Usando o seguinte código:

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

Eu esperaria ver todos os arquivos copiados. No entanto, isso simplifica a estrutura do diretório - todos os diretórios são copiados, mas todos os arquivos são colocados na raiz/var/www

Gulp parece ser uma ótima ferramenta de construção, mas copiar itens deve ser um processo simples, com certeza?

M1ke
fonte
9
Para qualquer novo visualizador que esteja lendo esta pergunta, observe que a resposta mais votada não funciona para resolver a especificação original da pergunta, de não achatar os diretórios. Ele não resolve problemas que as pessoas estão tendo com nem todos os arquivos dentro de um diretório sejam copiados, de modo que é útil!
M1ke
1
Por não achatar, você quer dizer que deseja que os diretórios 'css', 'js' e 'src' estejam presentes /var/www/? Você poderia tentar{css,js,src}/**/*
Jason Goemaat
Eu sei que a expansão glob funciona dentro do gulp, mas eu ficaria confuso se isso funcionasse de maneira diferente para cada item como uma linha individual em uma lista - como a expansão glob é basicamente destinada apenas a expandir para uma lista antes da execução.
M1ke

Respostas:

319

O seguinte funciona sem nivelar a estrutura da pasta:

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

A '**/*'é a parte importante. Essa expressão é uma glob, que é uma poderosa ferramenta de seleção de arquivos. Por exemplo, para copiar apenas arquivos .js, use:'input/folder/**/*.js'

cancerbero
fonte
2
acho que você esqueceu de adicionar o gulp.dest. Deveria ser.pipe(gulp.dest('output/folder'));
Matthew Sprankle
3
Como você faz isso com uma extensão de arquivo específica?
Chev
1
Você pode editar a resposta para fornecer um exemplo para o conjunto de arquivos original? Não tenho certeza de como isso é mais apropriado, mas ficaria feliz em ver como funciona em comparação com o {base:"."}método.
Mar1
2
É importante observar que o basepadrão é "pasta", conforme indicado nesta resposta. Em outras palavras, a base começa onde o padrão glob começa. Isso me ajudou a entender onde meus arquivos terminariam e também é por isso que você não precisa **/*do gulp.destparâmetro Gulp pega tudo na glob e coloca na pasta dest com a mesma estrutura.
Neil Monroe
3
Isso não responde totalmente à pergunta que está sendo feita. É uma boa solução para copiar corretamente recursivamente, mas não responde como modificar o diretório base.
precisa
173

Acontece que, para copiar uma estrutura de diretórios completa, é gulpnecessário fornecer uma base para o seu gulp.src()método.

Portanto, gulp.src( [ files ], { "base" : "." })pode ser usado na estrutura acima para copiar todos os diretórios recursivamente.

Se, como eu, você pode esquecer isso, tente:

gulp.copy=function(src,dest){
    return gulp.src(src, {base:"."})
        .pipe(gulp.dest(dest));
};
M1ke
fonte
1
Adicione a configuração "cwd" para definir o diretório de trabalho atual.
Skarllot
3
Se baseainda estiver confuso, dê uma olhada em stackoverflow.com/a/35848322/11912, que explica muito bem.
James Skemp
60

Então - a solução de fornecer uma base funciona, pois todos os caminhos têm o mesmo caminho base. Mas se você deseja fornecer caminhos base diferentes, isso ainda não funcionará.

Uma maneira de resolver esse problema foi tornar o início do caminho relativo. Para o seu caso:

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

A razão pela qual isso funciona é que o Gulp define a base como o final do primeiro bloco explícito - o líder * faz com que ele defina a base no cwd (que é o resultado que todos queremos!)

Isso só funciona se você puder garantir que a estrutura da pasta não tenha certos caminhos que podem corresponder duas vezes. Por exemplo, se você tivesse randomjs/o mesmo nível js, acabaria correspondendo a ambos.

Esta é a única maneira que encontrei para incluí-las como parte de uma função gulp.src de nível superior. Provavelmente seria simples criar um plugin / função que pudesse separar cada um desses globs, para que você pudesse especificar o diretório base para eles.

ty1824
fonte
Eu acho que ter que começar com vários caminhos de base provavelmente vai além do escopo da questão. Da minha pergunta original, eu estava movendo os arquivos para um caminho absoluto, mas o problema ainda ocorria: sem especificar uma base, todos os arquivos de todos os meus globos eram copiados em um único diretório sem que a hierarquia existente fosse seguida.
M1ke
2
@ M1ke É verdade, o ponto principal da sua pergunta não foi direcionado para diferentes caminhos base. No entanto, você mencionou However it flattens the dir structure - all directories are copied but every file is placed in the root /var/www, e foi assim que encontrei sua pergunta - eu estava procurando uma solução de como copiar recursivamente com diferentes caminhos de base. Essencialmente, esta solução funciona para o seu caso sem ter que especificar uma base padrão, mas também para um caso caminho multi-base, enquanto você pode garantir que a estrela principal corresponde nada :)
ty1824
6
Esta resposta é excepcional. Ele lida especificamente com a cópia de um caminho de um ponto de partida arbitrário, por exemplo. src pode ser 'assets/subdir/*fonts/*'para copiar o diretório das fontes.
Wtower 24/02
-4

Se você deseja copiar todo o conteúdo de uma pasta recursivamente para outra pasta, é possível executar o seguinte comando do Windows no gulp:

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

A /yopção no final é suprimir a mensagem de confirmação de substituição.

No Linux, você pode executar o seguinte comando no gulp:

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

você pode usar o gulp-exec ou o plugin gulp-run para executar comandos do sistema a partir do gulp.

Links Relacionados:

  1. uso de xcopy

  2. gulp-exec e gulp-run

Manoj Amalraj
fonte
7
O problema de voltar ao shell aqui é que você perderia a capacidade de executar outros comandos no fluxo, como ferramentas de compactação ou análise.
M1ke