Использование Gulp для объединения и изменения файлов


124

Я пытаюсь использовать Gulp для:

  1. Возьмите 3 конкретных файла javascript, объедините их, затем сохраните результат в файл (concat.js)
  2. Возьмите этот объединенный файл и уменьшите / уменьшите его, затем сохраните результат в другом файле (uglify.js).

Пока у меня есть следующий код

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

Однако операция uglify не работает, или файл по какой-то причине не создается.

Что мне нужно сделать, чтобы это произошло?


3
Удивлен, что еще не видел этого, поэтому я просто хотел бы быстро заметить, что цель сама по себе несколько противоречит философии Gulp. Запись промежуточных файлов - это больше способ работы Grunt. Gulp продвигает потоки для повышения скорости. Но я уверен, что у спрашивающего были свои причины :).
Барт

Я знаю, что это старый поток, но я сделал модуль npm, чтобы очень легко выполнять такую ​​работу, используя файл yaml. Проверьте это: github.com/Stnaire/gulp-yaml-packages .
Stnaire

Ответы:


161

Оказывается, мне нужно было gulp-renameсначала использовать, а также вывести объединенный файл перед «uglification». Вот код:

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

Исходя из gruntэтого было немного запутанным на первый , но это имеет смысл сейчас. Надеюсь, это поможет gulpновичкам.

И, если вам нужны исходные карты, вот обновленный код:

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

См. Gulp-sourcemaps для получения дополнительной информации о параметрах и настройке.


К вашему сведению, вам не хватает одной кавычки перед concat.js. Строка после вашего возвращаемого заявления gulp.taskдолжна быть такой:.pipe(gp_concat('concat.js'))
Эрик Йоргенсен

1
Все файлы генерируются, однако в отладчике я все еще вижу уменьшенную версию. В чем может быть причина? Файл карты назван правильно и доступен по его URL-адресу.
Meglio

Это будет, в зависимости от браузеров, исходные источники находятся на разных вкладках. Вам нужно поставить точку останова.
przemcio 05

4
Мне непонятно, зачем вообще переименовывать? Это ошибка или?
przemcio 05

@przemcio В моем случае мне нужно было записывать все файлы на каждом этапе процесса. Однако, если все, что вас волнует, это окончательный минифицированный файл, вы, конечно, можете еще больше сократить файл
gulp

17

Мой файл gulp создает окончательный compiled-bundle-min.js, надеюсь, это кому-то поможет.

введите описание изображения здесь

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

1
Отличный пример @wchoward, это было именно то, что я искал, очень чистый, простой дизайн.
Faito

10

Решение с использованием gulp-uglify, gulp-concatи gulp-sourcemaps. Это из проекта, над которым я работаю.

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

Это объединяет и сжимает все ваши scriptsфайлы, помещает их в файл с именем all_the_things.js. Файл будет заканчиваться специальной строкой

//# sourceMappingURL=all_the_things.js.map

Это говорит вашему браузеру искать этот файл карты, который он также записывает.


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

Ваше решение не работает, потому что вам нужно сохранить файл после процесса concat, а затем удалить его и снова сохранить. Вам не нужно переименовывать файл между concat и uglify.


Я бы сказал, что это прерогатива разработчика решать, что им делать, а что не нужно при использовании gulp. В моем случае я хотел переименовывать файлы на каждом этапе. Другие могут предпочесть иное.
Обинванн Хилл

1
Конечно, вы сами можете решить, какой вариант вам подходит. Я понял, что в приведенном ниже ответе говорится, что вам нужно переименовать файл, я просто сказал, что вам это не нужно (это не обязательно), извините, если я немного запутался.
Milos

4

10 июня 2015 г .: Примечание автора gulp-uglifyjs:

УСТАРЕВШИЙ: этот плагин был внесен в черный список, поскольку он полагается на Uglify для объединения файлов вместо использования gulp-concat, что нарушает парадигму «Он должен делать одно». Когда я создавал этот плагин, не было возможности заставить исходные карты работать с gulp, однако теперь есть плагин gulp-sourcemaps, который достигает той же цели. gulp-uglifyjs по-прежнему отлично работает и дает очень детальный контроль над выполнением Uglify, я просто предупреждаю вас, что теперь существуют другие варианты.


18 февраля 2015: gulp-uglify и gulp-concatоба прекрасно работают с gulp-sourcemapsсейчас. Просто убедитесь, что правильно настроили newLineпараметр для gulp-concat; Рекомендую \n;.


Исходный ответ (декабрь 2014 г.): используйте вместо этого gulp-uglifyjs . gulp-concatне обязательно безопасно; ему необходимо правильно обрабатывать завершающие точки с запятой. gulp-uglifyтакже не поддерживает исходные карты. Вот отрывок из проекта, над которым я работаю:

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

А? gulp-uglify определенно поддерживает исходные карты: github.com/floridoo/gulp-sourcemaps/wiki/…
Мистер О,

1
@MisterOh Не уверен, что это было на момент написания, или, если это так, возможно gulp-concat, нет ( gulp-uglifyне позволит вам минимизировать несколько файлов, поэтому вам нужно сначала объединить). Кроме того , gulp-concatиспользует \r\nпо умолчанию, что может вызвать проблемы , если файлы JS не завершаются должным образом. Но да, теперь, когда есть поддержка, вероятно, лучше пойти по этому пути, поскольку он более гибкий.
mpen

@Mark - был бы признателен, если бы вы разместили решение с gulp-sourcemaps, которое работает в соответствии с ответом Обинванна. Кажется, я не могу заставить его работать.
NightOwl888 02

@ NightOwl888 хорошо На самом деле, это не создает встроенных исходных карт, если вы об этом спрашивали; это все еще отдельный файл.
mpen 02

gulp-uglifyjs теперь также определен. Теперь достаточно просто использовать плагин gulp-uglify. См. Другие ответы для получения актуального решения.
Нил Монро

0

мы используем конфигурацию ниже, чтобы сделать что-то подобное

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

образец файла GulpDS ниже:

{

    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",
        }
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.