I need to call b.bundle() and get the entire output synchronously. How do I do this?
This isn't possible with browserify. Why do you want to do that?
Ah, that's sad. I'm writing an express view engine. During its initialisation, and before the server goes live, I want to browserify and cache the bundles. A callback would complicate the process of initialising the engine, but I guess it's unavoidable.
You should probably change your code to use a callback.
But, if you really really need to it to be synchronous, you can try calling out to the browserify command line program using child_process.execSync in node 0.11. You can use exec-sync if you need to support 0.10 too.
I'm really surprised that this is not a more common issue. For example, I've got a git pre-commit hook which generates versioned JS and CSS files and then adds them to the commit. Now, for this to work everything needs to complete before the hook script returns, which of course is not going to be the case with an async browserify bundle.
Unless I'm missing something that sounds like a reasonable workflow. Is there really a reason why a synchronous bundle function would not be exposed?
@doesdev All of browserify is implemented with Node.js streams. These streams are asynchronous, and there's no switch for browserify to flip that can make them asynchronous.
However, it's a moot point for your use case. The shell script that's running for your git commit hook waits for the process to exit before continuing onto the next instruction. By default, Node.js waits for asynchronous tasks to finish before exiting.
Yeah, my bad ;) Thanks for the reply and clarification.
@feross Bundling from the Browserify CLI doesn't cut it for me. I use the node API for many sequential in-memory build steps. The CLI doesn't allow you to read from streams. Am I in the dark on this issue? Or are there any other plausible ways to synchronously bundle which I've missed?
if you really really really __really__ need to bundle synchronously you can put your code stuff in a separate script and use the execSync way on that. (eg execSync('node ./my-bundler-script')) you may also be able to use something like deasync which is a native c++ extension that blocks execution until some async condition is met.
if you're writing a server you should 100% absolutely never do this and instead rewrite things to be async. if you're writing something like a cli tool, you could get away with doing this if there really is no other way.
Thanks for the suggestions. It's a build script, not server software. A quick additional question. Wouldn't a generator suffice for this? The below (coffeeScript) code does not work, it only returns a readable object, not the buffer with compiled code. If I access buf from inside the callback with e.g. a console.log statement it will show the compiled code鈥攁s expected.
b = browserify stream, basedir: process.cwd()
bundleSync = do -> yield b.bundle (err, buf) -> buf.toString()
with async functions in JS you can do something like:
var promisify = require('util').promisify
async function build () {
var b = browserify(...)
var doBundle = promisify(b.bundle.bind(b))
var buf = await doBundle()
console.log(buf)
}
if you use some generator promise thing like co you can do the same with generators. note that that still bundles asynchronously, so doing it that way is quite nice!
Most helpful comment
with async functions in JS you can do something like:
if you use some generator promise thing like co you can do the same with generators. note that that still bundles asynchronously, so doing it that way is quite nice!