Usando Gulp para concatenar e atualizar arquivos

124

Estou tentando usar o Gulp para:

  1. Pegue 3 arquivos javascript específicos, concatene-os e salve o resultado em um arquivo (concat.js)
  2. Pegue esse arquivo concatenado e faça o uglify / minify, depois salve o resultado em outro arquivo (uglify.js)

Eu tenho o seguinte código até agora

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

No entanto, a operação uglify parece não estar funcionando ou o arquivo não é gerado por algum motivo.

O que preciso fazer para que isso aconteça?

Obinwanne Hill
fonte
3
Espantado por não vê-lo ainda, então gostaria de comentar rapidamente que o objetivo em si é um pouco contrário à filosofia da Gulp. A gravação de arquivos intermediários é mais a maneira de trabalhar do Grunt. Gulp promove fluxos para melhorar a velocidade. Mas tenho certeza que o cara que perguntava tinha suas razões :).
Bart
Eu sei que é um thread antigo, mas criei um módulo npm para fazer esse tipo de trabalho com muita facilidade usando um arquivo yaml. Confira: github.com/Stnaire/gulp-yaml-packages .
Stnaire

Respostas:

161

Acontece que eu precisava usar gulp-renamee também gerar o arquivo concatenado antes da 'uglificação'. Aqui está o 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(){});

Vir gruntdisso foi um pouco confuso no começo, mas agora faz sentido. Espero que ajude os gulpnoobs.

E, se você precisar de mapas de origem, aqui está o código atualizado:

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

Veja gulp-sourcemaps para mais informações sobre opções e configuração.

Obinwanne Hill
fonte
Para sua informação, faltam aspas simples antes de concat.js. A linha após a declaração de retorno gulp.taskdeve ser:.pipe(gp_concat('concat.js'))
Eric Jorgensen
1
Todos os arquivos são gerados, no entanto, no depurador, ainda vejo a versão minificada. Qual pode ser a razão? O arquivo de mapa é nomeado corretamente e pode ser acessado por sua URL.
Meglio
Depende dos navegadores, as fontes originais estão em guias diferentes. Você precisa colocar o ponto de interrupção lá.
przemcio 5/01/16
4
Não está claro para mim por que precisamos renomear? É um bug ou?
Przemcio 5/01/16
@przemcio No meu caso, eu queria um registro de todos os arquivos em cada etapa do processo. No entanto, se tudo o que interessa é o arquivo minified final, então você pode, naturalmente encurtar o arquivo gole ainda mais
Obinwanne Colina
17

Meu arquivo gulp produz um compilado-pacote-min.js final, espero que isso ajude alguém.

insira a descrição da imagem aqui

//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
fonte
1
Grande exemplo @ wchoward, era exatamente o que eu estava procurando, design simples e muito limpo.
Faito 3/16
10

Solução usando gulp-uglify, gulp-concate gulp-sourcemaps. Isso é de um projeto no qual estou trabalhando.

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

Isso combina e compacta todos os seus scriptsarquivos e os coloca em um arquivo chamado all_the_things.js. O arquivo terminará com uma linha especial

//# sourceMappingURL=all_the_things.js.map

O que instrui o navegador a procurar esse arquivo de mapa, que também é gravado.

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

Sua solução não funciona porque você precisa salvar o arquivo após o processo de concat, uglificar e salvar novamente. Você não precisa renomear o arquivo entre concat e uglify.

Milos
fonte
Eu diria que é uma prerrogativa do desenvolvedor decidir o que eles fazem e não precisam ao usar o gulp. No meu caso, eu queria renomear os arquivos em cada etapa. Outros podem preferir o contrário.
Obinwanne Colina
1
Obviamente, você pode decidir qual é a melhor opção para você. Eu entendi, essa resposta abaixo diz que você precisa renomear o arquivo, eu apenas disse que você não precisa (não é obrigatório), desculpe se eu fiz alguma confusão.
Milos
4

10/06/2015: Nota do autor de gulp-uglifyjs:

DEPRECADO: Este plug-in foi colocado na lista negra, pois conta com o Uglify para concatar os arquivos em vez de usar o gulp-concat, o que quebra o paradigma "Deve fazer uma coisa". Quando criei este plugin, não havia como fazer com que os mapas de código-fonte funcionassem com o gulp, no entanto, agora existe um plug-in do gulp-sourcemaps que atinge o mesmo objetivo. O gulp-uglifyjs ainda funciona muito bem e oferece controle muito granular sobre a execução do Uglify, só estou avisando que outras opções existem agora.


18 de fevereiro de 2015: gulp-uglify e gulp-concatambos funcionam bem gulp-sourcemapsagora. Apenas certifique-se de definir a newLineopção corretamente para gulp-concat; Eu recomendo \n;.


Resposta original (dez de 2014): Use gulp-uglifyjs . gulp-concatnão é necessariamente seguro; ele precisa lidar com ponto e vírgula à direita corretamente. gulp-uglifytambém não suporta mapas de origem. Aqui está um trecho de um projeto no qual estou trabalhando:

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
fonte
Hã? O gulp-uglify definitivamente suporta mapas de origem: github.com/floridoo/gulp-sourcemaps/wiki/…
Mister Oh
1
@MisterOh Não tenho certeza de que ocorreu no momento da escrita, ou se foi, talvez gulp-concatnão ( gulp-uglifynão permitirá que você reduza vários arquivos para que você precise concatenar primeiro). Além disso, gulp-concatusa um \r\npor padrão, o que poderia causar problemas se os arquivos JS não terminarem corretamente. Mas sim, agora que há suporte, provavelmente é melhor seguir esse caminho, pois é mais flexível.
MPEN
@ Mark - Gostaria que você publicasse a solução com gulp-sourcemaps que funcione de acordo com a resposta de Obinwanne. Não consigo fazê-lo funcionar.
precisa
@ NightOwl888 ok Na verdade, isso não produz mapas de fontes embutidos, se é o que você estava perguntando; ainda é um arquivo separado.
MPEN
O gulp-uglifyjs também é exibido agora. Agora, basta usar o plugin gulp-uglify. Veja outras respostas para obter uma solução atualizada.
Neil Monroe
0

estamos usando a configuração abaixo para fazer algo semelhante

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

O arquivo GulpDS de amostra está abaixo:

{

    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
fonte