
Loading…
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
So how does one set up a gulp task that concludes in a browserify step?
@awmartin I believe vinyl-source-stream covers that.
Thanks!
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?
@sbrekken I think you are looking for https://github.com/hughsk/vinyl-map probably.
@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.
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'))
})
@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.
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.
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'))
})
So, is it will be a refactored gulp-browserify? It looks like just simplified, but task.
Or I misunderstand smth? =)
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.
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
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.
Thoughts here: gulpjs/gulp#369
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']
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.
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
@greypants Epic post. Thanks so much for sharing!
![]()
@greypants Wow that needs to make its way back to the browserify docs.
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/'));
});
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/'));
});
| Commit has since been removed from the repository and is no longer available. |
@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)
Move discussion to gulpjs/gulp#369
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)
;
});
"hey everybody, remember the title of this thread?"
Think you replied to the wrong thread there buddy.
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.
@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.
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.
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 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
@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.
why is gulp-browserify blacklisted?
|
|
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
|
@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.
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?
@latviancoder Here's how I'm doing it:
https://github.com/greypants/gulp-starter/blob/master/gulp/tasks/browserify.js#L43
https://github.com/greypants/gulp-starter/blob/master/gulp/util/handleErrors.js
The important bit is to emit the end event so the task doesn't hang.
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.
No description provided.