Sử dụng Gulp để nối các tệp và Uglify


124

Tôi đang cố gắng sử dụng Gulp để:

  1. Lấy 3 tệp javascript cụ thể, nối chúng, sau đó lưu kết quả vào một tệp (concat.js)
  2. Lấy tệp được nối này và uglify / minify nó, sau đó lưu kết quả vào một tệp khác (uglify.js)

Tôi có mã sau đây cho đến nay

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

Tuy nhiên, hoạt động uglify dường như không hoạt động hoặc vì lý do nào đó tệp không được tạo.

Tôi cần làm gì để thực hiện điều này?


3
Kinh ngạc khi chưa thấy nó, vì vậy tôi chỉ muốn nhanh chóng nhận xét rằng mục tiêu tự nó phần nào đi ngược lại triết lý của Gulp. Viết các tập tin trung gian là cách làm việc của Grunt. Gulp thúc đẩy các luồng để cải thiện tốc độ. Nhưng tôi chắc rằng anh chàng hỏi có lý do của mình :).
Bart

Tôi biết đó là một chủ đề cũ, nhưng tôi đã tạo ra một mô-đun npm để thực hiện loại công việc này rất dễ dàng bằng cách sử dụng tệp yaml. Hãy xem thử: github.com/Stnaire/gulp-yaml-packages .
Stnaire

Câu trả lời:


161

Hóa ra tôi cần phải sử dụng gulp-renamevà cũng xuất ra tệp được nối trước tiên trước khi 'làm mờ'. Đây là mã:

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

Đến từ gruntnó có một chút khó hiểu lúc đầu nhưng bây giờ nó có ý nghĩa. Tôi hy vọng nó sẽ giúp các gulpnoobs.

Và, nếu bạn cần sourcemaps, đây là mã được cập nhật:

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

Xem gulp-sourcemaps để biết thêm về các tùy chọn và cấu hình.


FYI, bạn đang thiếu một dấu ngoặc kép trước concat.js. Dòng sau tuyên bố trở lại của bạn gulp.taskphải là:.pipe(gp_concat('concat.js'))
Eric Jorgensen

1
Tất cả các tệp được tạo, tuy nhiên, trong trình gỡ lỗi tôi vẫn thấy phiên bản rút gọn. Nguyên nhân có thể là gì? Tệp bản đồ được đặt tên chính xác và có thể được truy cập bằng URL của nó.
Meglio

Nó sẽ, tùy thuộc vào trình duyệt, các nguồn ban đầu nằm trên các tab khác nhau. Bạn cần đặt điểm dừng ở đó.
przemcio

4
Không rõ ràng cho tôi tại sao chúng ta cần phải đổi tên? Nó là một lỗi hay?
przemcio

@przemcio Trong trường hợp của tôi, tôi muốn có một bản ghi của tất cả các tệp ở mỗi bước trong quy trình. Tuy nhiên, nếu tất cả những gì bạn quan tâm là tệp rút gọn cuối cùng, thì dĩ nhiên bạn có thể rút ngắn tệp gulp hơn nữa
Obinwanne Hill

17

Tệp gulp của tôi tạo ra một gói-min.js được biên dịch cuối cùng, hy vọng điều này sẽ giúp được ai đó.

nhập mô tả hình ảnh ở đây

//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
Ví dụ tuyệt vời @wchoward, đó chỉ là những gì tôi đang tìm kiếm, thiết kế đơn giản rất sạch sẽ.
Faito

10

Giải pháp sử dụng gulp-uglify, gulp-concatgulp-sourcemaps. Đây là từ một dự án tôi đang làm việc.

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

Điều này kết hợp và nén tất cả của bạn scripts, đặt chúng vào một tệp được gọi all_the_things.js. Các tập tin sẽ kết thúc với một dòng đặc biệt

//# sourceMappingURL=all_the_things.js.map

Điều này cho biết trình duyệt của bạn tìm tệp bản đồ đó, nó cũng ghi ra.


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

Giải pháp của bạn không hoạt động vì bạn cần lưu tệp sau quá trình concat và sau đó làm xấu đi và lưu lại. Bạn không cần phải đổi tên tập tin giữa concat và uglify.


Tôi muốn nói rằng đó là đặc quyền của nhà phát triển để quyết định những gì họ làm và không cần khi sử dụng gulp. Trong trường hợp của tôi, tôi muốn đổi tên các tệp ở mỗi bước. Những người khác có thể thích khác.
Đồi Obinwanne

1
Tất nhiên, bạn có thể quyết định đâu là lựa chọn tốt nhất cho bạn. Tôi hiểu, câu trả lời dưới đây nói rằng bạn cần đổi tên tập tin, tôi chỉ nói rằng bạn không cần (nó không bắt buộc), xin lỗi nếu tôi đã làm cho một số nhầm lẫn.
Milos

4

Ngày 10 tháng 6 năm 2015: Lưu ý từ tác giả của gulp-uglifyjs:

ĐỔI: Plugin này đã được đưa vào danh sách đen vì nó dựa vào Uglify để nối các tệp thay vì sử dụng gulp-concat, phá vỡ mô hình "Nó nên làm một việc". Khi tôi tạo plugin này, không có cách nào để bản đồ nguồn hoạt động với gulp, tuy nhiên bây giờ có một plugin gulp-sourcemaps đạt được mục tiêu tương tự. gulp-uglifyjs vẫn hoạt động tuyệt vời và cung cấp quyền kiểm soát rất chi tiết đối với việc thực thi Uglify, tôi chỉ cho bạn biết rằng các tùy chọn khác hiện đang tồn tại.


Ngày 18 tháng 2 năm 2015: gulp-uglifygulp-concatcả hai đều làm việc tốt với gulp-sourcemapsbây giờ. Chỉ cần đảm bảo đặt newLinetùy chọn chính xác cho gulp-concat; Tôi đề nghị \n;.


Câu trả lời gốc (Tháng 12 năm 2014): Sử dụng gulp-uglifyjs thay thế. gulp-concatkhông nhất thiết phải an toàn; nó cần phải xử lý dấu chấm phẩy một cách chính xác. gulp-uglifycũng không hỗ trợ bản đồ nguồn. Đây là đoạn trích từ một dự án tôi đang thực hiện:

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

Huh? gulp-uglify chắc chắn hỗ trợ bản đồ nguồn: github.com/floridoo/gulp-sourcemaps/wiki/ Kẻ
Mister Oh

1
@MisterOh Không chắc chắn nó đã được thực hiện tại thời điểm viết hoặc nếu có, có lẽ là gulp-concatkhông ( gulp-uglifysẽ không cho phép bạn thu nhỏ nhiều tệp để bạn phải ghép trước). Ngoài ra, gulp-concatsử dụng \r\ntheo mặc định, điều này có thể gây ra sự cố nếu các tệp JS của bạn không chấm dứt đúng cách. Nhưng vâng, bây giờ có hỗ trợ, có lẽ tốt hơn là đi theo con đường đó vì nó linh hoạt hơn.
mở

@Mark - Sẽ đánh giá cao nếu bạn đăng giải pháp với gulp-sourcemaps hoạt động nội tuyến với câu trả lời của Obinwanne. Tôi dường như không thể làm cho nó hoạt động.
NightOwl888

@ NightOwl888 không sao Trên thực tế, điều đó không tạo ra các nguồn gốc nội tuyến nếu đó là những gì bạn đang hỏi; nó vẫn là một tập tin riêng biệt
mở cửa

gulp-uglifyjs hiện cũng bị tước quyền. Chỉ cần sử dụng plugin gulp-uglify là đủ. Xem các câu trả lời khác cho một giải pháp cập nhật.
Neil Monroe

0

chúng tôi đang sử dụng cấu hình dưới đây để làm một cái gì đó tương tự

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

tệp GulpDS mẫu bên dưới:

{

    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",
        }
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.