Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Gulp to Concatenate and Uglify files

Tags:

gulp

It turns out that I needed to use gulp-rename and also output the concatenated file first before 'uglification'. Here's the code:

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

Coming from grunt it was a little confusing at first but it makes sense now. I hope it helps the gulp noobs.

And, if you need sourcemaps, here's the updated code:

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

See gulp-sourcemaps for more on options and configuration.


My gulp file produces a final compiled-bundle-min.js, hope this helps someone.

enter image description here

//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"));
});

Solution using gulp-uglify, gulp-concat and gulp-sourcemaps. This is from a project I'm working on.

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

This combines and compresses all your scripts, puts them into a file called all_the_things.js. The file will end with a special line

//# sourceMappingURL=all_the_things.js.map

Which tells your browser to look for that map file, which it also writes out.


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

Your solution does not work because you need to save file after concat process and then uglify and save again. You do not need to rename file between concat and uglify.


Jun 10 2015: Note from the author of gulp-uglifyjs:

DEPRECATED: This plugin has been blacklisted as it relies on Uglify to concat the files instead of using gulp-concat, which breaks the "It should do one thing" paradigm. When I created this plugin, there was no way to get source maps to work with gulp, however now there is a gulp-sourcemaps plugin that achieves the same goal. gulp-uglifyjs still works great and gives very granular control over the Uglify execution, I'm just giving you a heads up that other options now exist.


Feb 18 2015: gulp-uglify and gulp-concat both work nicely with gulp-sourcemaps now. Just make sure to set the newLine option correctly for gulp-concat; I recommend \n;.


Original Answer (Dec 2014): Use gulp-uglifyjs instead. gulp-concat isn't necessarily safe; it needs to handle trailing semi-colons correctly. gulp-uglify also doesn't support source maps. Here's a snippet from a project I'm working on:

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