Como melhorar a saída com o Browserify no Gulp?

112

Tentei uglificar a saída do Browserify no Gulp, mas não funcionou.

gulpfile.js

var browserify = require('browserify');
var gulp = require('gulp');
var uglify = require('gulp-uglify');
var source = require('vinyl-source-stream');

gulp.task('browserify', function() {
    return browserify('./source/scripts/app.js')
        .bundle()
        .pipe(source('bundle.js'))
        .pipe(uglify()) // ???
        .pipe(gulp.dest('./build/scripts'));
});

Pelo que entendi, não posso fazer isso nas etapas abaixo. Preciso fazer em um tubo para preservar a sequência?

gulp.task('browserify', function() {
    return browserify('./source/scripts/app.js')
        .bundle()
        .pipe(source('bundle.js'))
        .pipe(uglify()) // ???
        .pipe(gulp.dest('./source/scripts'));
});

gulp.task('scripts', function() {
    return grunt.src('./source/scripts/budle.js')
        .pipe(uglify())
        .pipe(gulp.dest('./build/scripts'));
});

gulp.task('default', function(){
    gulp.start('browserify', 'scripts');
});
Nik Terentyev
fonte

Respostas:

186

Você chegou bem perto, exceto por uma coisa:

  • você precisa converter o objeto de arquivo de vinil de streaming fornecido por source()com vinyl-bufferporque gulp-uglify(e a maioria dos plug-ins gulp) funciona em objetos de arquivo de vinil em buffer

Então você teria isso em vez

var browserify = require('browserify');
var gulp = require('gulp');
var uglify = require('gulp-uglify');
var source = require('vinyl-source-stream');
var buffer = require('vinyl-buffer');

gulp.task('browserify', function() {
  return browserify('./source/scripts/app.js')
    .bundle()
    .pipe(source('bundle.js')) // gives streaming vinyl file object
    .pipe(buffer()) // <----- convert from streaming to buffered vinyl file object
    .pipe(uglify()) // now gulp-uglify works 
    .pipe(gulp.dest('./build/scripts'));
});

Ou você pode escolher usar, em vinyl-transformvez disso, o que cuida de streaming e de objetos de arquivo de vinil em buffer para você, como

var gulp = require('gulp');
var browserify = require('browserify');
var transform = require('vinyl-transform');
var uglify = require('gulp-uglify');


gulp.task('build', function () {

  // use `vinyl-transform` to wrap the regular ReadableStream returned by `b.bundle();` with vinyl file object
  // so that we can use it down a vinyl pipeline
  // while taking care of both streaming and buffered vinyl file objects
  var browserified = transform(function(filename) {
    // filename = './source/scripts/app.js' in this case
    return browserify(filename)
      .bundle();
  });

  return gulp.src(['./source/scripts/app.js']) // you can also use glob patterns here to browserify->uglify multiple files
    .pipe(browserified)
    .pipe(uglify())
    .pipe(gulp.dest('./build/scripts'));
});

Ambas as receitas acima resultarão na mesma coisa.

É apenas sobre como você deseja gerenciar seus tubos (conversão entre streams NodeJS regulares e objetos de arquivo de vinil de streaming e objetos de arquivo de vinil em buffer)

Edit: Escrevi um artigo mais longo sobre o uso do gulp + browserify e diferentes abordagens em: https://medium.com/@sogko/gulp-browserify-the-gulp-y-way-bb359b3f9623

Hafiz Ismail
fonte
A solução de transformação de vinil resulta em um pacote broswerified para cada arquivo no glob, em vez de um único pacote para todos os arquivos. @ hafiz-ismail como a abordagem de transformação do vinil pode ser usada para criar um único pacote?
Brian Leathem
@BrianLeathem: cada arquivo do padrão glob será um arquivo de entrada principal separado para o browserify e cada arquivo de entrada resultará em um pacote separado. Se você deseja concatenar todas as saídas do pacote em um único arquivo, pode usá gulp-concat-lo e adicioná-lo ao final do seu pipeline gulp. Isso será o equivalente a executar browserify <options> > single-file.jsno terminal. Deixe-me saber se eu respondi sua pergunta. Felicidades!
Hafiz Ismail
11
Hmm, acho que o segundo exemplo com vinyl-transformnão funciona mais né ?!
Yckart
Com relação à transformação de vinil: github.com/substack/node-browserify/issues/1198
Egon Olieux
Como preservar os avisos de direitos autorais neste cenário?
Pankaj
12

Duas abordagens adicionais, retiradas da página NPM do vinil-source-stream :

Dado:

var source = require('vinyl-source-stream');
var streamify = require('gulp-streamify');
var browserify = require('browserify');
var uglify = require('gulp-uglify');
var gulpify = require('gulpify');
var gulp = require('gulp');

Abordagem 1 usando gulpify (obsoleto)

gulp.task('gulpify', function() {
  gulp.src('index.js')
    .pipe(gulpify())
    .pipe(uglify())
    .pipe(gulp.dest('./bundle.js'));
});

Abordagem 2 usando vinil-source-stream

gulp.task('browserify', function() {
  var bundleStream = browserify('index.js').bundle();

  bundleStream
    .pipe(source('index.js'))
    .pipe(streamify(uglify()))
    .pipe(gulp.dest('./bundle.js'));
});

Um benefício da segunda abordagem é que ele usa a API Browserify diretamente, o que significa que você não precisa esperar que os autores do gulpify atualizem a biblioteca antes que você possa.

Drew Noakes
fonte
"gulpify tornou-se obsoleto em favor do uso de" browserify "diretamente em combinação com o módulo" vinyl-source-stream "ou" gulp-browserify "se você quiser usar um plugin" Fonte: npmjs.org/package/gulpify Observe também que "gulp-browserify" está na lista negra.
ZeeCoder 01 de
@ZeeCoder o que você quer dizer com lista negra?
Giszmo
O segundo foi útil para mim. Funciona como um encanto. :) Tks!
dnvtrn
3

você pode tentar browserify transformar uglifyify .

eihero
fonte
3
Observações importantes, parece que o uglifyify não tem manutenção e está preso no Uglify v1, que está obsoleto.
Evan Carroll
2
O Uglify atualmente usa o Uglify v2. Talvez ele não seja atualizado com tanta frequência, mas isso não parece ser necessário, pois depende apenas do pacote uglify-js.
inta