使用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促进溪流以提高速度。但是我敢肯定,问的那个人有他的理由:)。
巴特2015年

我知道这是一个旧线程,但是我制作了一个npm模块来使用yaml文件非常轻松地完成这种工作。检查出来:github.com/Stnaire/gulp-yaml-packages
Stnaire '16

Answers:


161

事实证明,我需要gulp-rename在“丑化”之前先使用并输出连接的文件。这是代码:

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'))
Eric Jorgensen 2014年

1
所有文件都生成了,但是,在调试器中我仍然看到缩小的版本。可能是什么原因?映射文件的命名正确,可以通过其URL访问。
Meglio

取决于浏览器,原始源位于不同的选项卡上。您需要在此处放置断点。
przemcio '16

4
我不清楚为什么我们需要重新命名?是错误还是?
przemcio'1

@przemcio以我为例,我想要记录过程中每一步的所有文件。但是,如果您只关心最终的缩小文件,那么您当然可以进一步缩短
gulp

17

我的gulp文件会生成最终的build-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-uglifygulp-concatgulp-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和uglify之间重命名文件。


我想说的是,开发人员有权决定使用gulp时需要做什么和不需要什么。就我而言,我想在每个步骤中重命名文件。其他人可能会更喜欢。
Obinwanne Hill

1
当然,您可以决定什么是最适合您的选择。我了解,下面的回答说您需要重命名文件,我只是说您不需要(不是必须的),如果引起了某些混淆,对不起。
米洛斯

4

2015年6月10日:作者的注释gulp-uglifyjs

不推荐使用:此插件已被列入黑名单,因为它依靠Uglify来合并文件,而不是使用gulp-concat,这打破了“它应该做一件事”的范式。当我创建此插件时,无法使源地图与gulp一起使用,但是现在有一个gulp-sourcemaps插件可以实现相同的目标。gulp-uglifyjs仍然可以很好地工作,并且可以非常精细地控制Uglify的执行,我只是想提醒您现在存在其他选项。


2015年2月18日: gulp-uglifygulp-concat与工作都很好gulp-sourcemaps了。只要确保为newLine正确设置选项gulp-concat; 我推荐\n;


原始答案(2014年12月):改用gulp-uglifyjsgulp-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'))
});


1
@MisterOh不确定在撰写本文时是否这样做,或者是否这样做gulp-concatgulp-uglify不会让您缩小多个文件,因此必须先合并)。另外,默认情况下gulp-concat使用\r\n,如果您的JS文件未正确终止,则可能会导致问题。但是,是的,现在有了支持,走这条路线可能会更好,因为它更灵活。
mpen 2015年

@Mark-如果您将使用与Obinwanne的答案一致的gulp-sourcemaps发布解决方案,将不胜感激。我似乎无法正常工作。
NightOwl888 2015年

@ NightOwl888 好的,实际上,如果您要的是那样,它不会生成内联源地图;它仍然是一个单独的文件。
mpen 2015年

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",
        }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.