Wie kopiere ich Verzeichnisse rekursiv mit gulp?

166

Ich versuche, ein Projekt von einem Arbeitsverzeichnis auf einen Server (denselben Computer) zu übertragen. Verwenden Sie den folgenden Code:

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

Ich würde erwarten, dass alle Dateien kopiert werden. Die Verzeichnisstruktur wird jedoch abgeflacht - alle Verzeichnisse werden kopiert, aber jede Datei wird im Stammverzeichnis abgelegt/var/www

Gulp scheint ein großartiges Build-Tool zu sein, aber das Kopieren von Elementen sollte sicherlich ein einfacher Vorgang sein?

M1ke
quelle
9
Für alle neuen Zuschauer, die diese Frage lesen, sollte beachtet werden, dass die Antwort mit der höchsten Stimme nicht funktioniert, um die ursprüngliche Fragenspezifikation zu lösen, Verzeichnisse nicht zu reduzieren. Es löst Probleme, die Menschen haben, wenn nicht alle Dateien in einem Verzeichnis kopiert werden. Das ist also nützlich!
M1ke
1
Meinen Sie damit, dass die Verzeichnisse 'css', 'js' und 'src' vorhanden sein sollen, wenn Sie nicht abflachen /var/www/? Sie könnten versuchen{css,js,src}/**/*
Jason Goemaat
Ich weiß, dass die Glob-Erweiterung in gulp funktioniert, aber ich wäre verwirrt, wenn dies für jedes Element als einzelne Zeile in einer Liste anders funktionieren würde - da die Glob-Erweiterung im Grunde nur dazu gedacht ist, vor der Ausführung zu einer Liste zu expandieren.
M1ke

Antworten:

318

Folgendes funktioniert, ohne die Ordnerstruktur zu reduzieren:

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

Das '**/*'ist der wichtige Teil. Dieser Ausdruck ist ein Glob, der ein leistungsstarkes Dateiauswahlwerkzeug ist. Verwenden Sie zum Kopieren von .js-Dateien beispielsweise Folgendes:'input/folder/**/*.js'

Cancerbero
quelle
2
Ich glaube, Sie haben vergessen, die Datei gulp.dest hinzuzufügen. Sollte sein.pipe(gulp.dest('output/folder'));
Matthew Sprankle
3
Wie machen Sie das mit einer bestimmten Dateierweiterung?
Chev
1
Können Sie die Antwort bearbeiten, um ein Beispiel für den ursprünglichen Dateisatz bereitzustellen? Ich bin nicht sicher , wie das ist mehr angemessen , aber ich würde gerne prüfen , wie es mit dem Vergleich funktioniert {base:"."}Methode.
M1ke
2
Es ist wichtig zu beachten, dass der baseStandardwert "Ordner" ist, wie in dieser Antwort angegeben. Mit anderen Worten, die Basis beginnt dort, wo das Glob-Muster beginnt. Dies hat mir geholfen zu verstehen, wo meine Dateien landen würden, und ist auch der Grund, warum Sie das **/*im gulp.destParameter nicht benötigen . Gulp nimmt alles in den Globus und legt es mit derselben Struktur im Zielordner ab.
Neil Monroe
3
Dies beantwortet die gestellte Frage nicht vollständig. Es ist eine gute Lösung, um rekursiv korrekt zu kopieren, aber es gibt keine Antwort darauf, wie das Basisverzeichnis geändert werden kann.
ty1824
173

Es stellt sich heraus, dass zum Kopieren einer vollständigen Verzeichnisstruktur gulpeine Basis für Ihre gulp.src()Methode bereitgestellt werden muss.

So gulp.src( [ files ], { "base" : "." })kann in der Struktur verwendet werden , vor allem rekursiv die Verzeichnisse zu kopieren.

Wenn Sie dies wie ich vergessen, versuchen Sie Folgendes:

gulp.copy=function(src,dest){
    return gulp.src(src, {base:"."})
        .pipe(gulp.dest(dest));
};
M1ke
quelle
1
Fügen Sie die "cwd" -Konfiguration hinzu, um das aktuelle Arbeitsverzeichnis festzulegen.
Skarllot
3
Wenn Sie baseimmer noch verwirrt sind, schauen Sie sich stackoverflow.com/a/35848322/11912 an, wo Sie dies hervorragend erklären können.
James Skemp
60

Die Lösung für die Bereitstellung einer Basis funktioniert also, da alle Pfade denselben Basispfad haben. Wenn Sie jedoch unterschiedliche Basispfade bereitstellen möchten, funktioniert dies immer noch nicht.

Eine Möglichkeit, dieses Problem zu lösen, bestand darin, den Anfang des Pfades relativ zu machen. Für Ihren Fall:

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

Der Grund, warum dies funktioniert, ist, dass Gulp die Basis als das Ende des ersten expliziten Blocks festlegt - das führende * bewirkt, dass die Basis am cwd festgelegt wird (was das Ergebnis ist, das wir alle wollen!).

Dies funktioniert nur, wenn Sie sicherstellen können, dass Ihre Ordnerstruktur nicht über bestimmte Pfade verfügt, die zweimal übereinstimmen könnten. Wenn Sie zum Beispiel randomjs/das gleiche Level wie hätten js, würden Sie am Ende beide übereinstimmen.

Dies ist der einzige Weg, den ich gefunden habe, um diese als Teil einer gulp.src-Funktion der obersten Ebene einzuschließen. Es wäre wahrscheinlich einfach, ein Plugin / eine Funktion zu erstellen, die jeden dieser Globs trennen könnte, sodass Sie jedoch das Basisverzeichnis für sie angeben könnten.

ty1824
quelle
Ich denke, dass das Beginnen mit mehreren Basispfaden wahrscheinlich den Rahmen der Frage sprengt. Von meiner ursprünglichen Frage habe ich die Dateien auf einen absoluten Pfad verschoben, aber es trat immer noch das Problem auf, dass ohne Angabe einer Basis alle Dateien aus allen meinen Globs in ein einziges Verzeichnis kopiert wurden, ohne dass ihre vorhandene Hierarchie befolgt wurde.
M1ke
2
@ M1ke Es ist wahr, der Hauptpunkt Ihrer Frage war nicht auf unterschiedliche Basispfade gerichtet. Sie haben jedoch erwähnt However it flattens the dir structure - all directories are copied but every file is placed in the root /var/www, und genau so habe ich Ihre Frage gefunden. Ich habe nach einer Lösung gesucht, wie rekursiv mit verschiedenen Basispfaden kopiert werden kann. Im Wesentlichen funktioniert diese Lösung für Ihren Fall, ohne eine Standardbasis angeben zu müssen, aber auch für einen Fall mit mehreren
Basispfaden
6
Diese Antwort ist außergewöhnlich. Es befasst sich speziell mit dem Kopieren eines Pfades von einem beliebigen Startpunkt, z. src könnte sein 'assets/subdir/*fonts/*', das Schriftartenverzeichnis zu kopieren.
Wtower
-4

Wenn Sie den gesamten Inhalt eines Ordners rekursiv in einen anderen Ordner kopieren möchten, können Sie den folgenden Windows-Befehl von gulp ausführen:

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

Die /yOption am Ende besteht darin, die Bestätigungsnachricht zum Überschreiben zu unterdrücken.

Unter Linux können Sie den folgenden Befehl von gulp aus ausführen:

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

Sie können das Plugin gulp-exec oder gulp-run verwenden , um Systembefehle von gulp auszuführen.

Verwandte Links:

  1. xcopy Verwendung

  2. gulp-exec und gulp-run

Manoj Amalraj
quelle
7
Das Problem beim Zurückgreifen auf die Shell besteht darin, dass Sie nicht mehr andere Befehle im Stream ausführen können, z. B. Komprimierungs- oder Analysetools.
M1ke