Remove plugin gulp-browserify from the blacklist #47

Closed
deepak1556 opened this Issue Mar 13, 2014 · 49 comments

Projects

None yet
@deepak1556

No description provided.

@phated
Member
phated commented Mar 13, 2014

Browserify should be used as a standalone module. It returns a stream and figures out your dependency graph. If you need vinyl objects, use browserify + vinyl-source-stream

@phated phated closed this Mar 13, 2014
@awmartin

So how does one set up a gulp task that concludes in a browserify step?

@phated
Member
phated commented Mar 13, 2014

@awmartin I believe vinyl-source-stream covers that.

@awmartin

Thanks!

@VFK VFK added a commit to VFK/tic-tac-toe-online that referenced this issue Mar 17, 2014
@VFK VFK Use Browserify directly f62ed46
@simenbrekken

In the example given with vinyl-source-stream it only handles a single entry point, one of the conveniences with gulp-browserify was bundling multiple entry points (such as tests) into a single bundle using gulp-concat. Is there an alternative way of doing this without manually having to call browserify.add on each file manually?

@phated
Member
phated commented Mar 17, 2014

@sbrekken I think you are looking for https://github.com/hughsk/vinyl-map probably.

@simenbrekken

@phated Doesn't look like vinyl-map works when you pass read: false to gulp.src through. To avoid having to set the baseDir parameter of browserify when adding streams I'd like to pass only the filename to browserify.require

@eightyfive

@sbrekken Did you succeed in making browserify & vinyl-map work together?

I'm struggling on what to return from the mapper function... (returning output obviously doesn't work.. Following code is just for illustration purpose):

  var bundleApp = map(function (contents, filename) {

    var output;

    var bStream = browserify(filename).bundle(function (err, src) {
      output = src;
    });

    return output;

    // -- OR --

    return bStream.__toStringSomeHow__()...
  });

  gulp.src(['./js/apps/home.js', './js/apps/property.js'])
    .pipe(bundleApp)
    .pipe(gulp.dest('./dist'));

I cannot figure out how to wire everything together. The main problem is that the Stream API is async... So how would I be able to grab the bStream content before data event is emitted??

Any help would be much appreciated.

@simenbrekken

I pretty much gave up on it, I'm using the following abomination at the moment:

gulp.task('scripts-test', function() {
  var source = require('vinyl-source-stream'),
      glob = require('glob'),
      browserify = require('browserify')

  var bundler = browserify({
    basedir: './src/scripts'
  })

  glob.sync('*.js', {cwd: bundler._basedir}).forEach(function(file) {
    bundler.require('./' + file.split('.')[0])
  })

  bundler
    .bundle()
    .pipe(source('client.js'))
    .pipe(gulp.dest('test/browser'))
})
@eightyfive

@sbrekken Here is mine (abomination!):

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

  var apps = ['home', 'property'];

  for (var i=0,l=apps.length; i<l; i++) {
    _bundleApp(apps[i]);
  }

  function _bundleApp(appname) {

    browserify('./js/apps/'+appname+'.js')
      .bundle()
      .pipe(source(appname+'.js'))
      .pipe(gulp.dest('./dist'));
  }
});

EDIT
What I want to achieve doesn't make sense:

Bundle the files and their dependencies into a single javascript file.

Source: browserify docs

What you're doing is not what I'm trying to achieve, I'm looking for a way to input multiple entries in browserify and pipe them into gulp, so I get the corresponding output files (bundles) in ./dist.

Basically I would need vinyl-source-stream to support the creation of multiple source streams.. But I don't know if that's possible (or even if that makes sense):

// Ignore this code, doesn't make sense
browserify(['./home', './property'], {basedir: './js/apps'})
    .bundle()
    .pipe(source(['home.js', 'property.js']))
    .pipe(gulp.dest('./dist'));

Hey, thanks for your time.

@BigAB
BigAB commented Mar 18, 2014

Just hoping to help here, maybe no one else is having trouble but this works for me:

I want all of app.js and subsequent required modules bundled into one bundle.js file so...

gulpfile.js

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

gulp.task('watch', function(){
    gulp.watch(["./js/**/*.js", "!./js/bundle.js"], ["browserify"]);
});

gulp.task('browserify', function() {
    var bundleStream = browserify('./js/app.js').bundle().pipe(source('bundle.js'));
    return bundleStream.pipe(gulp.dest('./js'));
});

Which is pretty much exactly what was linked to way up in the first comment ( vinyl-source-stream ), but I found that slightly confusing, thinking that only one file index.js was being modified. Maybe this will help someone undersatnd what's going on a little better.

@simenbrekken

@BigAB Yeah, the duplicate input/output filename is a bit confusing, also it's a bit strange that the statement source('index.js') is really setting the output filename.

@simenbrekken

I managed to get this working today and it isn't half bad actually:

function bundle(debug) {
  var through = require('through2'),
      browserify = require('browserify')

  return through.obj(function(file, encoding, callback) {
    var bundle = browserify()
      .require(file, { entry: file.path })
      .bundle({ debug: debug })

    file.contents = bundle

    this.push(file)

    callback()
  })
}

gulp.task('scripts', function() {
  var rename = require('gulp-rename')

  return gulp.src('src/scripts/index.js')
    .pipe(bundle(true))
    .pipe(rename('client.js'))
    .pipe(gulp.dest('build'))
})
@simenbrekken simenbrekken referenced this issue in hughsk/vinyl-map Mar 19, 2014
Open

Working example with Browserify #5

@eightyfive

@sbrekken Epic. I will try that soon. I'm slowly but surely wrapping my head around the whole concept of transform streams. This piece of code helps getting closer. Thanks.

@gobwas
gobwas commented Mar 21, 2014

So, is it will be a refactored gulp-browserify? It looks like just simplified, but task.
Or I misunderstand smth? =)

@daveespionage daveespionage referenced this issue in fbrctr/fabricator Mar 21, 2014
Closed

gulp-browserify has been blacklisted #35

@simenbrekken

Error handlig is still an issue with my approach, I've yet to come up with something that gracefully handles and outputs compilation errors without stopping the stream.

@contra
Member
contra commented Mar 22, 2014

Having just used browserify with gulp extensively I can say this: If somebody were to do a browserify plugin correctly, it would fit into the gulp paradigm not as a transform plugin but as a producer (replacement for gulp.src, for example) at the top of the chain

@jimthedev

I am looking for a similar solution but using parcelify (which bundles sass or css as well) instead of browserify. It seems that making a gulp plugin for it would be useless since it would suffer from the same problems as gulp-browserify. I do agree with @Contra that a provider seems like the more reasonable place for this to live.

@contra
Member
contra commented Mar 23, 2014

Thoughts here: gulpjs/gulp#369

@meleyal
meleyal commented Mar 25, 2014

FWIW, this is the best way I could find to run browserify via gulp whilst also getting decent error reporting:

gulp = require 'gulp'
shell = require 'gulp-shell'
livereload = require 'gulp-livereload'

watchify = "watchify
  app/initialize.coffee
  --outfile app/bundle.js
  --extension='.coffee'
  --transform coffeeify
  --debug"

gulp.task 'watch', shell.task(watchify)

gulp.task 'reload', ->
  server = livereload()
  gulp.watch './app/bundle.js'
    .on 'change', (file) -> server.changed file.path

gulp.task 'default', ['watch', 'reload']

https://gist.github.com/meleyal/9766072

@deepak1556 deepak1556 referenced this issue in deepak1556/gulp-browserify Mar 25, 2014
Closed

Cache dependencies, and only rebuild changed files. #67

@contra
Member
contra commented Mar 25, 2014

@meleyal Have you looked at the watchify recipe? Using the watchify node module would probably be easier than shelling out

@deepak1556 deepak1556 referenced this issue in deepak1556/gulp-browserify Mar 27, 2014
Open

Support for aliasMapping #46

@robrichard

What is the recommended way of using gulp to create multiple bundles from multiple entry files with watching? If you use watchify directly as in the recipe, you need to create a separate task that builds without watching. This means both a watching and non-watching task is needed for all tasks that depend on your browserify bundle.

The blacklisted gulp-browserify plugin does get around this, because you can set up gulp-watch to run it when your source files have changed. I am working on a fork (deepak1556/gulp-browserify#67) that will cache dependencies and only rebuild a bundle when a dependent file has been changed.

@greypants

I cover using Gulp with Browserify straight up (the without gulp-browserify) here: http://viget.com/extend/gulp-browserify-starter-faq

@meleyal @sbrekken coffee watching, compiling, and error reporting included. Code example (gulp task) in the referenced starter repo:
https://github.com/greypants/gulp-starter/blob/master/gulp/tasks/browserify.js

As previously stated, vinyl-source-stream is the glue you need to properly connect Browserify to Gulp: https://github.com/hughsk/vinyl-source-stream

@eightyfive

@greypants Epic post. Thanks so much for sharing!

@greypants

👍

@jimthedev

@greypants Wow that needs to make its way back to the browserify docs.

@akbr
akbr commented Apr 14, 2014

Re: error handling without disturbing a watch task, this worked for me:

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

gulp.task("app", function () {
  var b = browserify({entries:"./app.js"});

  return b.bundle()
    .on('error', function (err) {
      console.log(err.toString());
      this.emit("end");
    })
    .pipe(source("app.js"))
    .pipe(gulp.dest('./build/'));
});
@weilu
weilu commented Apr 21, 2014

Re: multiple test files:

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

gulp.task('tests', function(){
  var bundler = browserify()
  glob.sync("./app/@(pages|widgets|lib)/*/test/*").forEach(function(file){
    bundler.add(file)
  })
  bundler
    .transform('ractify')
    .bundle()
    .on('error', function (err) {
      console.log(err.toString());
      this.emit("end");
    })
    .pipe(source('./index.js'))
    .pipe(gulp.dest('./build/assets/js/tests/'));
});
@weilu weilu added a commit to hivewallet/hive-js that referenced this issue Apr 22, 2014
@weilu weilu replace gulp-browserify with browserify 421fe29
@TimothyKrell TimothyKrell referenced this issue in deepak1556/gulp-browserify Apr 29, 2014
Open

Trouble with external (multiple bundles) #55

@blackbing

@8y5 , @sbrekken :
I also need to use vinyl-map to set mutiple entries of browserify, here is my solution. I think it could pipe all the stuff in map function. But I am still looking forward hughsk/vinyl-map#5 if there is a better way to do it.

gulp.task "browserify", ()->
  appRoot = "#{__dirname}/"
  bundleApp = map( (contents, filename)->

    fname = filename.replace(appRoot, '')
    fname = fname.substring(fname.lastIndexOf('/')+1, fname.lastIndexOf('.'))
    if aim is 'dev'
      browserify(
        entries: [filename]
        extensions: ['.coffee', '.hbs']
      )
      .bundle({debug: true})
      .on('error', $.util.log )
      .pipe(source("#{fname}.js"))
      .pipe( $.streamify($.uglify(outSourceMap: true)))
      .pipe gulp.dest( "dist/scripts/")

  gulp.src('app/scripts/*.coffee')
    .pipe(bundleApp)
@contra
Member
contra commented May 2, 2014

Move discussion to gulpjs/gulp#369

@hakobera hakobera referenced this issue in hakobera/influga May 24, 2014
Closed

Use browserify directory #10

@shenanigans

hey everybody, remember the title of this thread? 'Cause this right here works perfectly...

var gulp = require ('gulp');
var gutil = require ('gulp-util');
var plumber = require('gulp-plumber');
var browserify = require('gulp-browserify');

gulp.task ('browserify', function(){
    gulp.src ('./browserindex.js')
      .pipe (plumber())
      .pipe (browserify())
      .pipe (gulp.dest ('static/dist'))
      .on ('error', gutil.log)
      ;
});
@enrichit

"hey everybody, remember the title of this thread?"

Think you replied to the wrong thread there buddy.

@peterbraden

It seems a little over-zealous to 'blacklist' a module that provides the right level of abstraction for many uses over some perceived issue with keeping up to date with browserify.

This is node, small modules are good - even if all this module does is implement the best practises from this thread, then it has value.

Most people just want to pipe their source to a module, not try and figure out the best way to use vinyl objects with browserify.

@phated
Member
phated commented Jun 24, 2014

@peterbraden it is blacklisted because it breaks the gulp plugin guidelines by creating another module when the original is usable in a standalone module. Gulp 4 will make it even easier to use browserify + fs.createWriteStream in a task, forgoing a vinyl stream all together.

@marlun
marlun commented Jun 25, 2014

@phated Can I read more about Gulp 4 somewhere?

@apfelbox
apfelbox commented Jul 3, 2014

I finally got a version working, compiling a complete directory of files.
It is certainly not the most performant solution, but at least it works.
Let's see for how long - until I encounter the next weird issue...
https://gist.github.com/apfelbox/b2d5ee9fe32e5b42adb2

Of course it would be really nice to create a browserify-plugin, which just implements an own gulp.src, something along the line of:

var browserifyGulp = require("gulp-browserify-src");

gulp.task("sth",
  function ()
  {
    return browserifyGulp.src("in/js/*.js")
      .pipe(uglify())
      // just your regular gulp-stuff 
  }
);

Of course there already is a way, but it is a) quite complicated, b) a lot of code for the actual gulp user and c) not really (well) documented.


edit: error handling doesn't work and I don't seem to get, how it can be correctly implemented, without killing the watch task. Any ideas?

edit 2: by using domains you can catch all errors, even the asynchronous ones. I updated my code. Seems to work now.

Funny thing though: the error is still reported by plumber, just not catched.

@contra
Member
contra commented Jul 4, 2014

If somebody wants to wrap the process of a browserify stream -> a gulp stream I would take a PR for a recipe.

browiserfyStuff.pipe(browserifyToGulp()).pipe(gulpPlugin())
@phated
Member
phated commented Jul 4, 2014

@contra isn't that vinyl-source-stream?

@contra
Member
contra commented Jul 5, 2014

@phated vinyl-source-stream + vinyl-buffer + error management since browserify has some interesting things going on. this is way too complex for any normal user to have to understand what vinyl is and implement their own everything. if you think requiring in 4 modules just to get browserify to work with gulp is fine you might want to check out task.js

@phated
Member
phated commented Jul 5, 2014

@contra everyone keeps complaining about error management, but I have been using watchify for 3 months inside a gulp task and it has yet to actually crash my process, while gulp-less crashes it on any error. So I think the error problems are with vinyl streams. Also, I have yet to find a situation that needed gulp plugins, as pretty much everything has a browserify transform, you can even configure them in your package.json if you want to keep your gulpfile DRY.

@robwierzbowski robwierzbowski referenced this issue in sindresorhus/gulp-ruby-sass Jul 12, 2014
Closed

Make loadPath relative to gulpfile cwd #80

@adam-lynch

@contra @phated, isn't there a possible use case where someone needs to use browserify in the middle of a pipeline?

@chmontgomery chmontgomery referenced this issue in dowjones/gulp-bundle-assets Aug 4, 2014
Closed

Documentation on using alongside browserify #15

@connor11528

why is gulp-browserify blacklisted?

@rjmackay rjmackay added a commit to ushahidi/platform-client that referenced this issue Aug 13, 2014
@rjmackay rjmackay Add AngularJS to client, with Browserify setup, refs T604
Summary:
- add ng, browserify, and brfs for single file packaging
- automatically install bower dependencies with npm
- make `www/` the build directory, ignore compiled css and js
- configure package.json for browserify builds
- update gulp setup to copy font-awesome fonts into build
- add `app/` directory for js and views

Test Plan:
```
npm install
npm run build
```

Load client in browser, click any post title to go to (stub) detail page, click home to go back.

Todos:

- rebuild `www/js/app.js` actions with Angular
- reconfigure docker nginx server for pushState support
- include `.htaccess` instructions in README for pushState support
- integrate browserify build with gulp watch (see gulpjs/plugins#47)
- figure out why watchify is not working

Reviewers: shadowhand, seth

Reviewed By: seth

Subscribers: eyedol, bodacea, digitalafrican, srutto, dkobia

Differential Revision: https://phabricator.ushahidi.com/D269
b38212b
@greypants

@jasonshark because Browserify can be used directly.

A basic browserify task would look something like this:

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

gulp.task('browserify', function(){
    return browserify({
            entries: ['./src/javascript/app.coffee']
        })
        .bundle()
        .pipe(source('app.js'))
        .pipe(gulp.dest('./build/'));
});

Read through the comments for details, and https://github.com/greypants/gulp-starter if you want more examples.

@sogko sogko referenced this issue in deepak1556/gulp-browserify Aug 16, 2014
Open

Exclude files from node_modules #76

@latviancoder

So I've read all the comments and still don't understand how to do error management properly. Plumber isn't working any more.

Here is what I am trying now, but it's not working properly.

gulp.task('scripts', function() {
    var b = browserify('./static/scripts/app.js')
        .add(es6ify.runtime)
        .transform(hbsfy)
        .transform(es6ify.configure(/^(?!.*node_modules)+.+\.js$/));

    return b.bundle()
        .on('error', function(err) {
            console.log(err.message);
        })
        .pipe(source('app.js'))
        .pipe(streamify(concat('build.js')))
        .pipe(gulp.dest('./static/build/js'))
        .pipe(livereload());
});

This example doesn't catch errors in handlebars templates. Gulp craches and I have to restart it manually. It catches errors in javascript, but livereload stops working and I still have to restart it again.

So how do you do error management without plumber now?

@UnquietCode

I don't know why this is blacklisted, it's literally the only voodoo which worked for me. Gulp+Bower+browserify+cofeeify+debowerify are not the happiest bunch when put together.

@tjwebb
tjwebb commented Dec 6, 2014

The module works for me, so what does blacklisting mean and why should I care? (this is not sarcasm; if I should care, then I will, but I am currently ignorant of what's going on)

@M-Pixel
M-Pixel commented Dec 24, 2014

I find it pretty upsetting that this was blacklisted. I've read that the blacklisting was probably the reason maintenance ceased.

The "node way" is to have many small modules, each of which does one job well. Well, gulp-browserify's one job that it did well was making browserify/gulp integration brainlessly simple. I'm supposed to spend my time making this website, not making libraries vinyl-compatible ("re-inventing the wheel").

I tried using the "proper" way, but none of the examples I could find in a day's worth of searching show Browserify taking in a stream from another Gulp plugin. They all start out with Browserify, then move on to uglify, then call it a day. I've failed to find any way to get Browserify to take in a stream apart from using this shunned gulp-browserify module, which worked flawlessly.

Unfortunately, my solution is a "time bomb," because eventually this deprecated package is going to cause issues. I really hope someone picks it back up again (heck, I would if I got the chance, but that's not happening for another six months).

Edit: Just read up on the blacklisting guidelines. It seems like it's not as serious as I thought. It's just too bad that deepak1566 wasn't given a chance to make his plugin conform to Gulp's author's ideals by slimming it down (see Fidian's comments here)

@contra
Member
contra commented Dec 24, 2014

@theqwertman Not given a chance? The whole reason this thing exists is to improve the libraries. If the plugin author gave a half a shit they could so easily fix the plugin and be taken off the blacklist. This isn't some irreversible hellban list that an evil dictator came up with - It's a way to encourage people to write good things, not duplicate eachothers work, and generally be good citizens of the ecosystem. gulp-browserify broke basically every rule, refused help (multiple PRs were sent to fix the library, all declined), and was just not being a good citizen.

I've said this so many times before but I will say it again if it got lost in this excessively long thread:

gulp-browserify was blackisted for being bad, not for philosophical reasons. Please stop posting that there should be a browserify plugin. I understand, I don't have time to write one, hopefully somebody will write a decent one soon to end this madness.

I'm going to lock this thread because it keeps popping up with the same +1 crap. If somebody convinces the people at gulp-browserify to fix the plugin or relinquish the name to a more worthy maintainer, please open a new issue to remove it from the blacklist when it is published.

@contra contra locked and limited conversation to collaborators Dec 24, 2014
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.