Zmodyfikuj plik w miejscu (to samo miejsce docelowe) za pomocą Gulp.js i wzoru globbingu

99

Mam zadanie typu gulp, które próbuje przekonwertować pliki .scss na pliki .css (używając gulp-ruby-sass), a następnie umieścić wynikowy plik .css w tym samym miejscu, w którym znalazł oryginalny plik. Problem polega na tym, że ponieważ używam wzorca globalnego, niekoniecznie wiem, gdzie jest przechowywany oryginalny plik.

W poniższym kodzie próbuję użyć gulp-tap, aby uzyskać dostęp do strumienia i znaleźć ścieżkę do pliku bieżącego pliku, z którego został odczytany strumień:

gulp.task('convertSass', function() {
    var fileLocation = "";
    gulp.src("sass/**/*.scss")
        .pipe(sass())
        .pipe(tap(function(file,t){
            fileLocation = path.dirname(file.path);
            console.log(fileLocation);
        }))
        .pipe(gulp.dest(fileLocation));
});

Na podstawie wyniku działania console.log(fileLocation)tego kodu wydaje się, że powinien działać dobrze. Jednak wynikowe pliki CSS wydają się być umieszczone o jeden katalog wyżej, niż się spodziewam. Gdzie powinno być project/sass/partials, wynikowa ścieżka do pliku to po prostu project/partials.

Jeśli istnieje znacznie prostszy sposób na zrobienie tego, na pewno doceniłbym to rozwiązanie jeszcze bardziej. Dzięki!

Dan-Nolan
źródło

Odpowiedzi:

155

Jak podejrzewasz, zbytnio to komplikujesz. Miejsce docelowe nie musi być dynamiczne, ponieważ ścieżka globalna jest również używana do dest. Po prostu potokuj do tego samego katalogu podstawowego, z którego globujesz src, w tym przypadku „sass”:

gulp.src("sass/**/*.scss")
  .pipe(sass())
  .pipe(gulp.dest("sass"));

Jeśli twoje pliki nie mają wspólnej bazy i musisz przekazać tablicę ścieżek, to już nie wystarczy. W takim przypadku chciałbyś określić opcję podstawową.

var paths = [
  "sass/**/*.scss", 
  "vendor/sass/**/*.scss"
];
gulp.src(paths, {base: "./"})
  .pipe(sass())
  .pipe(gulp.dest("./"));
numery1311407
źródło
Ach, super. Dziękuję Ci. Czy istnieje również łatwy sposób na użycie globu dla źródła, ale po prostu umieść wszystko prosto w sassfolderze?
Dan-Nolan
2
To nie zadziałało dla mnie. Musiałem zrobić gulp.src("dist/**/*")...gulp.dest("./")
fajne grifty
@ Dan-Nolan jednym ze sposobów spłaszczenia struktury folderów wydaje się być użycie zmiany nazwy gulp , zobacz to pytanie
numery1311407
@niftygrifty Według docs to powinien pracować w normalnej sytuacji. Pliki są zapisywane na swojej drodze dopasowywania globbed przeciwko obliczonej względnej podstawy , w tym przypadku sass. Być może wtyczka Sassa już modyfikuje ścieżki?
numery1311407
1
Ale czy to nie zapisuje pliku w / sass, a nie w odpowiednim podkatalogu, takim jak / sass / any / gdzie? Jak mogę zapisać pliki w ścieżce globbed?
Mark
68

Jest to prostsze niż wskazywały liczby 1311407. Nie musisz w ogóle określać folderu docelowego, po prostu użyj .. Upewnij się również, że ustawiłeś katalog podstawowy.

gulp.src("sass/**/*.scss", { base: "./" })
    .pipe(sass())
    .pipe(gulp.dest("."));
NightOwl888
źródło
8
To jest właściwa odpowiedź. Jeśli próbujesz zachować strukturę docelową (tj. Nie spłaszczyć struktury), musisz wskazać katalog podstawowy w gulp.src.
Gui Ambros,
2
Kiedy próbuję tego, pliki są zapisywane w „/”, a nie w ścieżce globbed.
Mark
1
To, co mówi @GuiAmbros, nie jest prawdą, przynajmniej nie zgodnie z dokumentacją . Podstawa jest domyślnie obliczana jako wszystko przed ścieżką globbed. W mojej odpowiedzi podstawa byłaby obliczona jako ./sass, ale pytanie określa, że ​​wyjście zachowuje sasskatalog, dlatego jest powtarzane w dest. Ta odpowiedź daje ten sam wynik przy użyciu opcji podstawowej, ale żadne podejście nie jest błędne.
numery1311407
Warto również zauważyć, że sytuacja OP prawdopodobnie nie jest tak powszechna, przynajmniej w przypadku przetwarzania CSS, ponieważ zazwyczaj spodziewasz się eksportu do csskatalogu lub podobnego, a nie z sassdo sass. W takich przypadkach przyjęta odpowiedź jest w rzeczywistości prostsza niż ta alternatywa.
numery1311407
30
gulp.src("sass/**/*.scss")
  .pipe(sass())
  .pipe(gulp.dest(function(file) {
    return file.base;
  }));

Pierwotna odpowiedź podana tutaj: https://stackoverflow.com/a/29817916/3834540 .

Wiem, że ten wątek jest stary, ale nadal pojawia się jako pierwszy wynik w Google, więc pomyślałem, że równie dobrze mogę zamieścić tutaj link.

bobbarebygg
źródło
Ten wątek jest stary, ale odpowiedzi są nadal poprawne, chociaż przypuszczam, że ta metoda jest nieco bardziej SUCHA (jeśli nieco mniej wydajna). Powiązane pytanie w rzeczywistości dotyczyło destnieprawidłowego używania . Upewnić się, że podane rozwiązania działają, ale robi to dobrze za pierwszym razem, po prostu zastępując dest('./')z dest('./images')musiałaby osiągnąć ten sam rezultat.
numery1311407
Powodem, dla którego inne rozwiązanie nie działało, było to, że miałem tablicę wewnątrz gulp.src (), np. Gulp.src (['sass / **', 'common / sass / **']) i kiedy szukałem odpowiedź, to był post, który znalazłem. Prawdopodobnie powinienem był to
wyjaśnić
Ma sens. W twoim przypadku problem polega na tym, że nie ma wspólnej podstawy do obliczenia łyka. Twoje rozwiązanie działa, ale rozwiązanie podane przez @ NightOwl888 dotyczące określenia bazy również zadziałałoby. Aktualizacja zaakceptowanej odpowiedzi w celu uwzględnienia przypadku braku wspólnej podstawy.
numery1311407
To powinna być akceptowana odpowiedź! Nie inne, które są specyficzne tylko dla jednego pliku lub ścieżki podstawowej.
MrCroft
0

To było bardzo pomocne!

gulp.task("default", function(){

    //sass
    gulp.watch([srcPath + '.scss', '!'+ srcPath +'min.scss']).on("change", function(file) {
         console.log("Compiling SASS File: " + file.path)
         return gulp.src(file.path, { base: "./" })
        .pipe(sass({style: 'compressed'}))
        .pipe(rename({suffix: '.min'}))
        .pipe(sourcemaps.init())
        .pipe(autoprefixer({
            browsers: ['last 2 versions'],
            cascade: false
        }))
        .pipe(sourcemaps.write('./'))         
        .pipe(gulp.dest(".")); 
    });

    //scripts
    gulp.watch([srcPath + '.js','!'+ srcPath + 'min.js']).on("change", function(file) {
        console.log("Compiling JS File: " + file.path)
        gulp.src(file.path, { base: "./" })
        .pipe(uglify())
        .pipe(rename({suffix: '.min'}))       
        .pipe(gulp.dest(".")); 
    });
})
mftohfa
źródło