Usando Gulp para Concatenar y Uglify archivos

124

Estoy tratando de usar Gulp para:

  1. Tome 3 archivos javascript específicos, concatenelos, luego guarde el resultado en un archivo (concat.js)
  2. Tome este archivo concatenado y uglify / minify, luego guarde el resultado en otro archivo (uglify.js)

Tengo el siguiente código hasta ahora

    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(){});

Sin embargo, la operación uglify no parece estar funcionando, o el archivo no se genera por alguna razón.

¿Qué necesito hacer para que esto suceda?

Obinwanne Hill
fuente
3
Sorprendido de no verlo todavía, así que me gustaría comentar rápidamente que el objetivo en sí mismo va en contra de la filosofía de Gulp. Escribir archivos intermedios es más la forma de trabajar de Grunt. Gulp promueve corrientes para mejorar la velocidad. Pero estoy seguro de que el tipo que preguntaba tenía sus razones :).
Bart
Sé que es un hilo antiguo, pero he creado un módulo npm para hacer este tipo de trabajo muy fácilmente usando un archivo yaml. Compruébalo: github.com/Stnaire/gulp-yaml-packages .
Stnaire

Respuestas:

161

Resulta que necesitaba usar gulp-renamey también generar el archivo concatenado primero antes de 'uglification'. Aquí está el código:

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(){});

Al gruntprincipio fue un poco confuso al principio, pero ahora tiene sentido. Espero que ayude a los gulpnovatos.

Y, si necesita mapas fuente, aquí está el código actualizado:

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(){});

Vea gulp-sourcemaps para más información sobre opciones y configuración.

Obinwanne Hill
fuente
Para su información, le falta una comilla simple antes de concat.js. La línea después de su declaración de devolución gulp.taskdebe ser:.pipe(gp_concat('concat.js'))
Eric Jorgensen
1
Todos los archivos se generan, sin embargo, en el depurador todavía veo la versión minificada. cual puede ser la razon? El archivo de mapa se nombra correctamente y se puede acceder por su URL.
Meglio
Dependerá de los navegadores, las fuentes originales están en una pestaña diferente. Necesitas poner un punto de quiebre allí.
przemcio
44
No está claro para mí por qué debemos cambiar el nombre. ¿Es un error o?
przemcio
@przemcio En mi caso, quería un registro de todos los archivos en cada paso del proceso. Sin embargo, si todo lo que le importa es el archivo minificado final, entonces, por supuesto, puede acortar aún más el archivo de trago
Obinwanne Hill el
17

Mi archivo gulp produce un compilado final de paquete-min.js, espero que esto ayude a alguien.

ingrese la descripción de la imagen aquí

//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
fuente
1
Gran ejemplo @wchoward, era justo lo que estaba buscando, diseño sencillo y muy limpio.
Faito
10

Solución usando gulp-uglify, gulp-concaty gulp-sourcemaps. Esto es de un proyecto en el que estoy trabajando.

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'))
});

Esto combina y comprime todos sus scripts, los pone en un archivo llamado all_the_things.js. El archivo terminará con una línea especial.

//# sourceMappingURL=all_the_things.js.map

Lo que le dice a su navegador que busque ese archivo de mapa, que también escribe.

mpen
fuente
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'));
});

Su solución no funciona porque necesita guardar el archivo después del proceso de concat y luego uglify y guardar nuevamente. No es necesario cambiar el nombre del archivo entre concat y uglify.

Milos
fuente
Diría que es prerrogativa del desarrollador decidir qué hacer y qué no necesita cuando usa gulp. En mi caso, quería cambiar el nombre de los archivos en cada paso. Otros pueden preferir lo contrario.
Obinwanne Hill
1
Por supuesto, puede decidir cuál es la mejor opción para usted. Comprendí que la respuesta a continuación dice que debe cambiar el nombre del archivo, solo dije que no lo necesita (no es obligatorio), lo siento si hice alguna confusión.
Milos
4

10 de junio de 2015: Nota del autor de gulp-uglifyjs:

DEPRECATED: Este complemento ha sido incluido en la lista negra ya que se basa en Uglify para capturar los archivos en lugar de usar gulp-concat, lo que rompe el paradigma "Debería hacer una cosa". Cuando creé este complemento, no había forma de hacer que los mapas fuente funcionaran con gulp, sin embargo, ahora hay un complemento gulp-sourcemaps que logra el mismo objetivo. gulp-uglifyjs todavía funciona muy bien y brinda un control muy granular sobre la ejecución de Uglify, solo les estoy dando una advertencia de que ahora existen otras opciones.


18 de febrero de 2015: gulp-uglify y gulp-concatambos funcionan bien gulp-sourcemapsahora. Solo asegúrese de configurar la newLineopción correctamente para gulp-concat; Recomiendo \n;.


Respuesta original (diciembre de 2014): use gulp-uglifyjs en su lugar. gulp-concatno es necesariamente seguro; necesita manejar los puntos y comas finales correctamente. gulp-uglifyTampoco admite mapas de origen. Aquí hay un fragmento de un proyecto en el que estoy trabajando:

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
fuente
¿Eh? gulp-uglify definitivamente admite mapas fuente: github.com/floridoo/gulp-sourcemaps/wiki/…
Señor Oh
1
@MisterOh No estoy seguro de que lo hiciera al momento de escribir, o si lo hizo, tal vez gulp-concatno lo hizo ( gulp-uglifyno le permitirá minificar múltiples archivos, por lo que primero debe concat). Además, gulp-concatutiliza un \r\nvalor predeterminado, que podría causar problemas si sus archivos JS no terminan correctamente. Pero sí, ahora que hay soporte, probablemente sea mejor seguir esa ruta, ya que es más flexible.
mpen
@ Mark: agradecería que publicara la solución con gulp-sourcemaps que funciona en línea con la respuesta de Obinwanne. Parece que no puedo hacerlo funcionar.
NightOwl888
@ NightOwl888 está bien En realidad, eso no produce mapas fuente en línea si eso es lo que estabas preguntando; Todavía es un archivo separado.
mpen
gulp-uglifyjs también está ahora dependiente. Solo usar el complemento gulp-uglify debería ser suficiente ahora. Vea otras respuestas para una solución actualizada.
Neil Monroe
0

estamos usando la siguiente configuración para hacer algo similar

    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']);

El archivo GulpDS de muestra está a continuación:

{

    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
fuente