Làm cách nào để sao chép thư mục đệ quy với gulp?


166

Tôi đang cố gắng thực hiện một dự án từ một thư mục làm việc đến một máy chủ (cùng một máy). Sử dụng mã sau:

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

Tôi hy vọng sẽ thấy tất cả các tập tin được sao chép. Tuy nhiên, nó làm phẳng cấu trúc thư mục - tất cả các thư mục được sao chép nhưng mọi tệp được đặt trong thư mục gốc/var/www

Gulp có vẻ như là một công cụ xây dựng tuyệt vời nhưng sao chép các mục nên là một quá trình đơn giản chắc chắn?


9
Đối với bất kỳ người xem mới nào đang đọc câu hỏi này, cần lưu ý rằng câu trả lời được bình chọn cao nhất không có tác dụng giải quyết đặc tả câu hỏi ban đầu của các thư mục không làm phẳng. Nó giải quyết vấn đề mà mọi người đang gặp phải với không phải tất cả các tệp trong một thư mục bị sao chép, vì vậy điều đó rất hữu ích!
M1ke

1
Bằng cách không làm phẳng, bạn có nghĩa là bạn muốn các thư mục 'css', 'js' và 'src' xuất hiện trong /var/www/? Bạn có thể thử{css,js,src}/**/*
Jason Goemaat

Tôi biết rằng mở rộng toàn cầu hoạt động bên trong gulp, nhưng tôi sẽ bối rối nếu điều đó hoạt động khác với từng mục như một dòng riêng lẻ trong danh sách - vì về cơ bản mở rộng toàn cầu chỉ nhằm mở rộng danh sách trước khi thực hiện.
M1ke

Câu trả lời:


318

Các công việc sau đây mà không làm phẳng cấu trúc thư mục:

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

Đây '**/*'là phần quan trọng. Biểu thức đó là một quả cầu là một công cụ chọn tệp mạnh mẽ. Ví dụ: để chỉ sao chép các tệp .js, hãy sử dụng:'input/folder/**/*.js'


2
nghĩ rằng bạn đã quên thêm gulp.dest. Nên là.pipe(gulp.dest('output/folder'));
Matthew Sprankle

3
Làm thế nào để bạn làm điều này với một phần mở rộng tập tin cụ thể?
Chev

1
Bạn có thể chỉnh sửa câu trả lời để cung cấp một ví dụ cho bộ tệp gốc không? Tôi không chắc cách này phù hợp hơn nhưng tôi rất vui khi xem cách nó hoạt động so với {base:"."}phương pháp.
M1ke

2
Điều quan trọng cần lưu ý là basemặc định là "thư mục" như được đưa ra trong câu trả lời này. Nói cách khác, cơ sở bắt đầu nơi mô hình toàn cầu bắt đầu. Điều này đã giúp tôi hiểu nơi tác phẩm của tôi sẽ kết thúc và cũng là lý do tại sao bạn không cần **/*trong gulp.desttham số. Gulp lấy mọi thứ trên toàn cầu và đặt nó vào thư mục Dest với cùng cấu trúc.
Neil Monroe

3
Điều này không trả lời đầy đủ câu hỏi đang được hỏi. Đó là một giải pháp tốt cho cách sao chép chính xác đệ quy, nhưng nó không trả lời cách sửa đổi thư mục cơ sở.
ty1824

173

Hóa ra để sao chép một cấu trúc thư mục hoàn chỉnh gulpcần phải được cung cấp một cơ sở cho gulp.src()phương thức của bạn .

Vì vậy, gulp.src( [ files ], { "base" : "." })có thể được sử dụng trong cấu trúc trên để sao chép tất cả các thư mục đệ quy.

Nếu, giống như tôi, bạn có thể quên điều này thì hãy thử:

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

1
Thêm cấu hình "cwd" để đặt thư mục làm việc hiện tại.
Skarllot

3
Nếu basevẫn còn làm bạn bối rối, hãy xem stackoverflow.com/a/35848322/11912 , một công việc tuyệt vời để giải thích nó.
James Skemp

60

Vì vậy - giải pháp cung cấp một công trình cơ sở cho rằng tất cả các đường dẫn có cùng đường dẫn cơ sở. Nhưng nếu bạn muốn cung cấp các đường dẫn cơ sở khác nhau, điều này vẫn không hoạt động.

Một cách tôi đã giải quyết vấn đề này là bằng cách bắt đầu con đường tương đối. Đối với trường hợp của bạn:

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

Lý do điều này hoạt động là vì Gulp đặt cơ sở là phần cuối của đoạn rõ ràng đầu tiên - phần đầu * khiến nó đặt cơ sở ở cwd (đó là kết quả mà tất cả chúng ta đều muốn!)

Điều này chỉ hoạt động nếu bạn có thể đảm bảo cấu trúc thư mục của mình sẽ không có đường dẫn nhất định có thể khớp hai lần. Ví dụ: nếu bạn có randomjs/cùng cấp độ js, bạn sẽ kết hợp cả hai.

Đây là cách duy nhất mà tôi đã tìm thấy để bao gồm những thứ này như là một phần của hàm gulp.src cấp cao nhất. Tuy nhiên, có thể đơn giản để tạo một plugin / chức năng có thể tách ra từng khối đó để bạn có thể chỉ định thư mục cơ sở cho chúng, tuy nhiên.


Tôi nghĩ rằng phải bắt đầu với nhiều đường dẫn cơ sở có thể vượt ra ngoài phạm vi của câu hỏi. Từ câu hỏi ban đầu của tôi, tôi đã di chuyển các tệp đến một đường dẫn tuyệt đối, nhưng vấn đề vẫn xảy ra, rằng không chỉ định một cơ sở, tất cả các tệp từ tất cả các khối của tôi đã được sao chép vào một thư mục mà không có hệ thống phân cấp hiện có của chúng.
M1ke

2
@ M1ke Đó là sự thật, điểm chính của câu hỏi của bạn không hướng vào các đường dẫn cơ sở khác nhau. Tuy nhiên, bạn đã đề cập However it flattens the dir structure - all directories are copied but every file is placed in the root /var/wwwvà đây thực sự là cách tôi tìm thấy câu hỏi của bạn - Tôi đang tìm kiếm một giải pháp về cách sao chép đệ quy với các đường dẫn cơ sở khác nhau. Về cơ bản, giải pháp này hoạt động cho trường hợp của bạn mà không phải chỉ định cơ sở mặc định, nhưng cũng cho trường hợp đường dẫn đa cơ sở, miễn là bạn có thể đảm bảo rằng ngôi sao hàng đầu không khớp gì :)
ty1824

6
Câu trả lời này là đặc biệt. Nó liên quan cụ thể đến việc sao chép một đường dẫn từ một điểm bắt đầu tùy ý, ví dụ. src có thể là 'assets/subdir/*fonts/*'để sao chép các phông chữ dir.
Wtower

-4

Nếu bạn muốn sao chép toàn bộ nội dung của một thư mục theo cách đệ quy vào một thư mục khác, bạn có thể thực thi lệnh windows sau từ gulp:

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

Các /ytùy chọn ở cuối là để ngăn chặn các thông báo xác nhận ghi đè.

Trong Linux, bạn có thể thực thi lệnh sau từ gulp:

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

bạn có thể sử dụng gulp-exec hoặc plugin gulp-run để thực thi các lệnh hệ thống từ gulp.

Liên kết liên quan:

  1. sử dụng xcopy

  2. gulp-execgulp-run


7
Vấn đề với việc quay trở lại hệ vỏ ở đây là bạn sẽ mất khả năng chạy các lệnh khác trên luồng, chẳng hạn như các công cụ nén hoặc phân tích.
M1ke
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.