Skip to content

Instantly share code, notes, and snippets.

@grncdr
Last active January 1, 2016 06:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save grncdr/8107660 to your computer and use it in GitHub Desktop.
Save grncdr/8107660 to your computer and use it in GitHub Desktop.
weirdness with browserify + concat-stream & bops

I have some code that uses concat-stream here. It's collecting some javascript from the README and evaling it. The eval currently fails with a syntax error when I use covert test.js, but not when I use node test.js.

covert pipes test.js through browserify and into node. There's some other stuff in between for the actual coverage collection but it's not relevant for this discussion. So we'll simplify things to this:

$ browserify test.js | node
TAP version 13
# README examples

[stdin]:3069
        throw err
              ^
SyntaxError: Unexpected token .
    at evalScope ([stdin]:4454:14)

The SyntaxError is because code on line 13 is an array, so the toString is joining everything with ',' characters.

Why is concat-stream giving me back an array instead of a Buffer?

Looking at ConcatStream.prototype.getBody we see that it's does a bunch of checks for "what to do with the data I have in this.body". One of those things is checking whether the first element in this.body is a buffer with bops.is. Which brings us to the root of the issue:

// bops/typedarray/is.js
module.exports = function(buffer) {
  return buffer instanceof Uint8Array;
}

Because the code has been browserified, we get the browser version of bops.is. But since we're running in a non-browser environment, the buffers being checked are node Buffer instances.

What to do about it?

At first I thought that bops.is should check for the definedness of Buffer (e.g. typeof Buffer == 'undefined') and use that to do an additional check:

module.exports = function(buffer) {
  return buffer instanceof Uint8Array || (typeof Buffer != 'undefined' && buffer instanceof Buffer);
}

However, adding that would cause the browserify Buffer implementation to be bundled, which is what using bops is avoiding in the first place. Maybe browserify could detect typeof X == 'undefined' checks and avoid bringing in node-specific globals for those?

For my specific use case, I'm going to ensure that markdown-code-blocks is pushing strings instead of Buffers so that ConcatStream.prototype.getBody doesn't do the bops.is check, but it's still an edge-case that might be worth handling.

Update

markdown-code-blocks was emitting strings, but because I wasn't setting objectMode with through2 they were being converted back into buffers. I am not a fan of the whole objectMode interface...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment