Używanie Gulp do łączenia i Uglify plików

124

Próbuję użyć Gulp do:

  1. Weź 3 określone pliki javascript, połącz je, a następnie zapisz wynik do pliku (concat.js)
  2. Weź ten połączony plik i uglify / zminifikuj go, a następnie zapisz wynik w innym pliku (uglify.js)

Na razie mam następujący kod

    var gulp = require('gulp'),
        gp_concat = require('gulp-concat'),
        gp_uglify = require('gulp-uglify');

    gulp.task('js-fef', function(){
        return gulp.src(['file1.js', 'file2.js', 'file3.js'])
            .pipe(gp_concat('concat.js'))
            .pipe(gp_uglify())
            .pipe(gulp.dest('js'));
    });

    gulp.task('default', ['js-fef'], function(){});

Jednak operacja uglify nie działa lub plik nie jest generowany z jakiegoś powodu.

Co muszę zrobić, aby to się stało?

Obinwanne Hill
źródło
3
Zdumiony, że jeszcze tego nie widziałem, więc chciałbym tylko szybko zauważyć, że cel sam w sobie jest nieco sprzeczny z filozofią Gulp. Pisanie plików pośredniczących jest bardziej grubym sposobem pracy. Gulp promuje strumienie, aby poprawić prędkość. Ale jestem pewien, że facet pytający miał swoje powody :).
Bart,
Wiem, że to stary wątek, ale stworzyłem moduł npm do bardzo łatwego wykonywania tego rodzaju pracy przy użyciu pliku yaml. Sprawdź to: github.com/Stnaire/gulp-yaml-packages .
Stnaire

Odpowiedzi:

161

Okazuje się, że gulp-renamenajpierw musiałem użyć, a także wypisać połączony plik przed „uglifikacją”. Oto kod:

var gulp = require('gulp'),
    gp_concat = require('gulp-concat'),
    gp_rename = require('gulp-rename'),
    gp_uglify = require('gulp-uglify');

gulp.task('js-fef', function(){
    return gulp.src(['file1.js', 'file2.js', 'file3.js'])
        .pipe(gp_concat('concat.js'))
        .pipe(gulp.dest('dist'))
        .pipe(gp_rename('uglify.js'))
        .pipe(gp_uglify())
        .pipe(gulp.dest('dist'));
});

gulp.task('default', ['js-fef'], function(){});

Na gruntpoczątku było to trochę zagmatwane, ale teraz ma sens. Mam nadzieję, że pomoże to gulpnoobom.

A jeśli potrzebujesz map źródeł, oto zaktualizowany kod:

var gulp = require('gulp'),
    gp_concat = require('gulp-concat'),
    gp_rename = require('gulp-rename'),
    gp_uglify = require('gulp-uglify'),
    gp_sourcemaps = require('gulp-sourcemaps');

gulp.task('js-fef', function(){
    return gulp.src(['file1.js', 'file2.js', 'file3.js'])
        .pipe(gp_sourcemaps.init())
        .pipe(gp_concat('concat.js'))
        .pipe(gulp.dest('dist'))
        .pipe(gp_rename('uglify.js'))
        .pipe(gp_uglify())
        .pipe(gp_sourcemaps.write('./'))
        .pipe(gulp.dest('dist'));
});

gulp.task('default', ['js-fef'], function(){});

Zobacz gulp-sourcemaps, aby uzyskać więcej informacji na temat opcji i konfiguracji.

Obinwanne Hill
źródło
FYI, brakuje pojedynczego cudzysłowu przed concat.js. Wiersz po oświadczeniu zwrotnym w gulp.taskpowinien wyglądać następująco:.pipe(gp_concat('concat.js'))
Eric Jorgensen
1
Wszystkie pliki są generowane, jednak w debugerze nadal widzę wersję zminimalizowaną. Jaki może być tego powód? Plik mapy ma prawidłową nazwę i można uzyskać do niego dostęp poprzez adres URL.
Meglio,
Będzie, w zależności od przeglądarek, oryginalne źródła znajdują się na innej karcie. Musisz tam umieścić punkt przerwania.
przemcio
4
Nie jest dla mnie jasne, dlaczego musimy zmienić nazwę? Czy to błąd czy?
przemcio
@przemcio W moim przypadku chciałem zapisywać wszystkie pliki na każdym etapie procesu. Jeśli jednak zależy ci tylko na ostatecznym zminimalizowanym pliku, to możesz oczywiście skrócić plik
łykowy
17

Mój plik gulp tworzy ostateczny skompilowany-bundle-min.js, mam nadzieję, że to komuś pomoże.

wprowadź opis obrazu tutaj

//Gulpfile.js

var gulp = require("gulp");
var watch = require("gulp-watch");

var concat = require("gulp-concat");
var rename = require("gulp-rename");
var uglify = require("gulp-uglify");
var del = require("del");
var minifyCSS = require("gulp-minify-css");
var copy = require("gulp-copy");
var bower = require("gulp-bower");
var sourcemaps = require("gulp-sourcemaps");

var path = {
    src: "bower_components/",
    lib: "lib/"
}

var config = {
    jquerysrc: [
        path.src + "jquery/dist/jquery.js",
        path.src + "jquery-validation/dist/jquery.validate.js",
        path.src + "jquery-validation/dist/jquery.validate.unobtrusive.js"
    ],
    jquerybundle: path.lib + "jquery-bundle.js",
    ngsrc: [
        path.src + "angular/angular.js",
         path.src + "angular-route/angular-route.js",
         path.src + "angular-resource/angular-resource.js"
    ],
    ngbundle: path.lib + "ng-bundle.js",

    //JavaScript files that will be combined into a Bootstrap bundle
    bootstrapsrc: [
        path.src + "bootstrap/dist/js/bootstrap.js"
    ],
    bootstrapbundle: path.lib + "bootstrap-bundle.js"
}

// Synchronously delete the output script file(s)
gulp.task("clean-scripts", function (cb) {
    del(["lib","dist"], cb);
});

//Create a jquery bundled file
gulp.task("jquery-bundle", ["clean-scripts", "bower-restore"], function () {
    return gulp.src(config.jquerysrc)
     .pipe(concat("jquery-bundle.js"))
     .pipe(gulp.dest("lib"));
});

//Create a angular bundled file
gulp.task("ng-bundle", ["clean-scripts", "bower-restore"], function () {
    return gulp.src(config.ngsrc)
     .pipe(concat("ng-bundle.js"))
     .pipe(gulp.dest("lib"));
});

//Create a bootstrap bundled file
gulp.task("bootstrap-bundle", ["clean-scripts", "bower-restore"], function     () {
    return gulp.src(config.bootstrapsrc)
     .pipe(concat("bootstrap-bundle.js"))
     .pipe(gulp.dest("lib"));
});


// Combine and the vendor files from bower into bundles (output to the Scripts folder)
gulp.task("bundle-scripts", ["jquery-bundle", "ng-bundle", "bootstrap-bundle"], function () {

});

//Restore all bower packages
gulp.task("bower-restore", function () {
    return bower();
});

//build lib scripts
gulp.task("compile-lib", ["bundle-scripts"], function () {
    return gulp.src("lib/*.js")
        .pipe(sourcemaps.init())
        .pipe(concat("compiled-bundle.js"))
        .pipe(gulp.dest("dist"))
        .pipe(rename("compiled-bundle.min.js"))
        .pipe(uglify())
        .pipe(sourcemaps.write("./"))
        .pipe(gulp.dest("dist"));
});
dynamiclynk
źródło
1
Świetny przykład @wchoward. To było to, czego szukałem, bardzo czysty, prosty projekt.
Faito
10

Rozwiązanie użyciu gulp-uglify, gulp-concata gulp-sourcemaps. To jest z projektu, nad którym pracuję.

gulp.task('scripts', function () {
    return gulp.src(scripts, {base: '.'})
        .pipe(plumber(plumberOptions))
        .pipe(sourcemaps.init({
            loadMaps: false,
            debug: debug,
        }))
        .pipe(gulpif(debug, wrapper({
            header: fileHeader,
        })))
        .pipe(concat('all_the_things.js', {
            newLine:'\n;' // the newline is needed in case the file ends with a line comment, the semi-colon is needed if the last statement wasn't terminated
        }))
        .pipe(uglify({
            output: { // http://lisperator.net/uglifyjs/codegen
                beautify: debug,
                comments: debug ? true : /^!|\b(copyright|license)\b|@(preserve|license|cc_on)\b/i,
            },
            compress: { // http://lisperator.net/uglifyjs/compress, http://davidwalsh.name/compress-uglify
                sequences: !debug,
                booleans: !debug,
                conditionals: !debug,
                hoist_funs: false,
                hoist_vars: debug,
                warnings: debug,
            },
            mangle: !debug,
            outSourceMap: true,
            basePath: 'www',
            sourceRoot: '/'
        }))
        .pipe(sourcemaps.write('.', {
            includeContent: true,
            sourceRoot: '/',
        }))
        .pipe(plumber.stop())
        .pipe(gulp.dest('www/js'))
});

To łączy i kompresuje wszystkie Twoje scriptspliki, umieszcza je w pliku o nazwie all_the_things.js. Plik kończy się specjalną linią

//# sourceMappingURL=all_the_things.js.map

Który mówi przeglądarce, aby szukała tego pliku mapy, który również zapisuje.

mpen
źródło
7
var gulp = require('gulp');
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');

gulp.task('create-vendor', function () {
var files = [
    'bower_components/q/q.js',
    'bower_components/moment/min/moment-with-locales.min.js',
    'node_modules/jstorage/jstorage.min.js'
];

return gulp.src(files)
    .pipe(concat('vendor.js'))
    .pipe(gulp.dest('scripts'))
    .pipe(uglify())
    .pipe(gulp.dest('scripts'));
});

Twoje rozwiązanie nie działa, ponieważ musisz zapisać plik po procesie konkatowania, a następnie uglifikować i zapisać ponownie. Nie musisz zmieniać nazwy pliku między concat a uglify.

Milos
źródło
Powiedziałbym, że to prerogatywa programisty, aby decydować, co robią, a czego nie potrzebują, gdy używają łyka. W moim przypadku chciałem zmieniać nazwy plików na każdym kroku. Inni wolą inaczej.
Obinwanne Hill
1
Oczywiście możesz zdecydować, która opcja jest dla Ciebie najlepsza. Zrozumiałem, że odpowiedź poniżej mówi, że musisz zmienić nazwę pliku, powiedziałem tylko, że nie potrzebujesz (nie jest to obowiązkowe), przepraszam, jeśli zrobiłem trochę zamieszania.
Milos
4

10 czerwca 2015 r .: Nota autora gulp-uglifyjs:

DEPRECATED: Ta wtyczka została umieszczona na czarnej liście, ponieważ polega na Uglify do konkatowania plików zamiast używania gulp-concat, co łamie paradygmat „Powinien zrobić jedną rzecz”. Kiedy tworzyłem tę wtyczkę, nie było sposobu, aby mapy źródeł działały z łykiem, jednak teraz jest wtyczka gulp-sourcemaps, która osiąga ten sam cel. gulp-uglifyjs nadal działa świetnie i daje bardzo szczegółową kontrolę nad wykonaniem Uglify. Po prostu daję ci znać, że istnieją teraz inne opcje.


18 lutego 2015 r .: gulp-uglify i gulp-concatoba działają dobrze z gulp-sourcemapsteraz. Po prostu upewnij się, że ustawiłeś newLinepoprawnie opcję gulp-concat; Polecam \n;.


Oryginalna odpowiedź (grudzień 2014 r.): Zamiast tego użyj gulp-uglifyjs . gulp-concatniekoniecznie jest bezpieczne; musi poprawnie obsługiwać końcowe średniki. gulp-uglifyrównież nie obsługuje map źródłowych. Oto fragment projektu, nad którym pracuję:

gulp.task('scripts', function () {
    gulp.src(scripts)
        .pipe(plumber())
        .pipe(uglify('all_the_things.js',{
            output: {
                beautify: false
            },
            outSourceMap: true,
            basePath: 'www',
            sourceRoot: '/'
        }))
        .pipe(plumber.stop())
        .pipe(gulp.dest('www/js'))
});
mpen
źródło
Co? gulp-uglify zdecydowanie obsługuje mapy źródłowe: github.com/floridoo/gulp-sourcemaps/wiki/ ...
Mister Oh
1
@MisterOh Nie jestem pewien, czy tak było w momencie pisania, a jeśli tak, być może gulp-concatnie ( gulp-uglifynie pozwoli ci zminifikować wielu plików, więc musisz najpierw połączyć). Ponadto gulp-concatużywa \r\ndomyślnie, co może powodować problemy, jeśli pliki JS nie zostaną poprawnie zakończone. Ale tak, teraz, gdy jest wsparcie, prawdopodobnie lepiej wybrać tę trasę, ponieważ jest bardziej elastyczna.
mpen
@Mark - Byłoby wdzięczne, gdybyś opublikował rozwiązanie z gulp-sourcemaps, które działa zgodnie z odpowiedzią Obinwanne. Nie wydaje mi się, żeby to działało.
NightOwl888
@ NightOwl888 okay Właściwie to nie tworzy wbudowanych map źródeł, jeśli o to prosiłeś; to wciąż oddzielny plik.
mpen
gulp-uglifyjs jest teraz również depekowany. Już samo użycie wtyczki gulp-uglify powinno wystarczyć. Zobacz inne odpowiedzi, aby uzyskać aktualne rozwiązanie.
Neil Monroe
0

używamy poniższej konfiguracji, aby zrobić coś podobnego

    var gulp = require('gulp'),
    async = require("async"),
    less = require('gulp-less'),
    minifyCSS = require('gulp-minify-css'),
    uglify = require('gulp-uglify'),
    concat = require('gulp-concat'),
    gulpDS = require("./gulpDS"),
    del = require('del');

// CSS & Less
var jsarr = [gulpDS.jsbundle.mobile, gulpDS.jsbundle.desktop, gulpDS.jsbundle.common];
var cssarr = [gulpDS.cssbundle];

var generateJS = function() {

    jsarr.forEach(function(gulpDSObject) {
        async.map(Object.keys(gulpDSObject), function(key) {
            var val = gulpDSObject[key]
            execGulp(val, key);
        });

    })
}

var generateCSS = function() {
    cssarr.forEach(function(gulpDSObject) {
        async.map(Object.keys(gulpDSObject), function(key) {
            var val = gulpDSObject[key];
            execCSSGulp(val, key);
        })
    })
}

var execGulp = function(arrayOfItems, dest) {
    var destSplit = dest.split("/");
    var file = destSplit.pop();
    del.sync([dest])
    gulp.src(arrayOfItems)
        .pipe(concat(file))
        .pipe(uglify())
        .pipe(gulp.dest(destSplit.join("/")));
}

var execCSSGulp = function(arrayOfItems, dest) {
    var destSplit = dest.split("/");
    var file = destSplit.pop();
    del.sync([dest])
    gulp.src(arrayOfItems)
        .pipe(less())
        .pipe(concat(file))
        .pipe(minifyCSS())
        .pipe(gulp.dest(destSplit.join("/")));
}

gulp.task('css', generateCSS);
gulp.task('js', generateJS);

gulp.task('default', ['css', 'js']);

przykładowy plik GulpDS znajduje się poniżej:

{

    jsbundle: {
        "mobile": {
            "public/javascripts/sample.min.js": ["public/javascripts/a.js", "public/javascripts/mobile/b.js"]
           },
        "desktop": {
            'public/javascripts/sample1.js': ["public/javascripts/c.js", "public/javascripts/d.js"]},
        "common": {
            'public/javascripts/responsive/sample2.js': ['public/javascripts/n.js']
           }
    },
    cssbundle: {
        "public/stylesheets/a.css": "public/stylesheets/less/a.less",
        }
}
dinesh
źródło