budo icon indicating copy to clipboard operation
budo copied to clipboard

The right way to pass `external` dependency

Open kolya-ay opened this issue 7 years ago • 6 comments

It seems that browserify doesn't allow to pass some options through its opts object. How can I accomplish browserify('./src').external('./vendor') with budo?

kolya-ay avatar Mar 08 '17 18:03 kolya-ay

Can you pass the command line flags to browserify via -- combined with -r/-x, e.g. budo index.js -- -t sometransform -x somedir?

rreusser avatar Mar 08 '17 20:03 rreusser

@kolya-ay I ran into the same problem. I was able to define external by defining an ad-hoc plugin...

budo({
  browserify: {
    plugin: [
      [ bundler => bundler.external('./vendor') ],
      // ...
    ],
    // ...
  },
  // ...
})

This works fine for me, but isn't very intuitive, and doesn't seem like the "right" way to do it.

@mattdesl What do you think about a new opt, named configureBundler or something similar?

The code from above would become:

budo({
  configureBundler: bundler => bundler.external('./vendor')
  // ...
})

Then the new option could be put in the documentation and anyone needing to configure external (or another one of the configurations that can't be passed in through the browserify opts object) will easily know what to do.

mattbrunetti avatar Mar 08 '17 20:03 mattbrunetti

@mattbrunetti Wow! Thank you, nice workaround!

May be instead of adding any special options, allow budo (optionally) to accept Browserify instance. E.g.

b = browserify('src', { transoform: babelify });
b.external('./vendor')
budo({ browserify: b })

Looks doable

kolya-ay avatar Mar 08 '17 20:03 kolya-ay

@kolya-ay — passing a bundler might seem great but it introduces a lot of room for errors. It would actually have to be written like this for it to work as expected:

b = browserify('src', {
  transform: babelify,
  cache: {},
  packageCache: {},
  debug: true
});
b.external('./vendor')
budo({ browserify: b })

Allowing any bundler to be passed would generally add a lot of complexity to budo and additional API surface area & considerations.

@mattbrunetti — If there's a specific case where configureBundler would be superior to plugin I'd be open to adding a new feature, but I'd like to keep the API surface area small if we can help it. :smile: The purpose of browserify plugins is to configure the bundler, so it should work well for most cases.

Here's another example, minimizing the bundle size of the slug package:

// dev.js
require('budo').cli(process.argv.slice(2), {
  browserify: {
    plugin: bundler => bundler.ignore('unicode/category/So')
  }
})

Then, you can use the script like regular budo CLI:

node dev.js src/index.js:bundle.js --live -- -t babelify

It might be great to add this to the docs somewhere.

mattdesl avatar Mar 09 '17 03:03 mattdesl

@mattdesl, yes I see now. It looks like the browserify incoherence anyway.

I prefer not to have configureBundler as a big fan of the smallest possible APIs. Even browserifyArgs looks like confusing redundancy for my taste (not for budo.cli though).

Should I close this or keep it as "update the docs" reminder? Can't help here due my poor English..

kolya-ay avatar Mar 12 '17 18:03 kolya-ay

Thanks for the workaround, @mattbrunetti! The budo API doesn't accept a stream as an entry point, so I'm currently passing the path to an empty file as an entry point, then using browserify.add via a plugin to pass it a stream of generated code. Feels like a hack and not unlikely there's a better way, but opens the door to lots of creative uses!

rreusser avatar Apr 05 '17 15:04 rreusser