Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to alias a module with Browserify lib in Gulp?

The Browserify readme describes creating external requires like so: $ browserify -r through -r duplexer -r ./my-file.js:my-module > bundle.js

Then in your page you can do:

<script src="bundle.js"></script>
<script>
  var through = require('through');
  var duplexer = require('duplexer');
  var myModule = require('my-module');
  /* ... */
</script>

This works if you want to do use the command line, but I'd like to use Browserify in a gulpfile. But there seems to be no way to add a name to a module like ./myfile-js:my-module in the example. If there's an option for it, I haven't found it. The only way to require my module in the way that they describe is to do require(3) because Browserify seems to give numbers to the modules, but these numbers change and clearly this is not desirable.

EDIT: My current solution is to do this:

var shell = require('gulp-shell');

gulp.task('browserify', shell.task([
  'browserify -r ./src/bundle.js:bundle > ./build/bundle.js'
]))

This is a workaround and not optimal if I want to take full advantage of the Gulp pipeline. I'd like to know how this can be done without the command line or, if not, why this is only something that can be done via CLI?

like image 470
Ravenstine Avatar asked Apr 14 '16 04:04

Ravenstine


2 Answers

b.require() with expose option.

function bundle () {
  browserify()
  .require("./myfile-js", {expose: "my-module"})
  .require("through")
  .require("duplexer")
  .bundle()
  /* ... */
}

gulp.task("browserify", bundle);

Browserify-Gulp integration

The other answers suggest that vinyl-source-stream is a requirement here, but that's not necessarily true. You haven't illustrated how you're integrating Browserify and Gulp. You only need vinyl-source-stream if you're actually doing some integration between Browserify and Gulp beyond just wrapping a Browserify bundling operation in a Gulp task (which people fairly commonly do), like running a Gulp plugin on the bundled output. For example, you can just do this:

var fs = require("fs");

gulp.task("browserify", function () {
  return browserify(/* ... */)
    /* ... */
    .bundle()
    // But if you're doing something with Gulp here you should use
    // `vinyl-source-stream` and pipe to `gulp.dest()`.
    .pipe(fs.createWriteStream("./bundle.js", "utf8"));
});
like image 88
JMM Avatar answered Nov 03 '22 00:11

JMM


Here are a couple of ways that I can think of to accomplish what you're looking for:

1. Use the .bundle() method:

It seems like the .bundle() method may be what you need. It's pre-built into browserify. Try experimenting with this code. It allows you to use gulp's .pipe() methods.

const browserify = require('browserify')
const gulp = require('gulp')
const source = require('vinyl-source-stream')

gulp.task('browserify', function (cb) {
  browserify('./src/bundle.js')
  .bundle() // <- This traverses the /node_modules/ tree to bundle everything ...
            // into 1 giant stream & eventually a single file.
  .pipe(source('bundle.js')) // Creates the "output source" file name,
                             // rather than being the "input source".
  .pipe(gulp.dest('./build/'))
  return cb()
})

Then you should be able to link this file: ./build/bundle.js to a <script> tag like this: <script src="./build/bundle.js"></script>.

NPM links: vinyl-source-stream, browserify, gulp (You already know about those, but others might not be aware of them yet.)

2. Make a deep linked alias:

If you want to make an alias, which deep links into an external JS class (not a CSS class), you'd have to try using a require() method call like this:

const bundle = require('browserify').bundle

Which is equivalent to:

import {bundle} from "browserify"

Those last 2 lines assume that a JSON object is being returned from the external module, which is being required/included as a dependency. The return object in that external file, should look something like this:

module.exports = {
    "default": SomeMainClass,
    "bundle": someExtraFunctionLikeBundle
}

Potential "Gotchya": If the external dependency doesn't return a JSON object, then the .bundle would return undefined. For example, this would prevent the .bundle in require('browserify').bundle from working:

module.exports = function() {...} // instead of module.exports = {JSON}

Please let me know if you need additional help with Gulp, after experimenting with the 1st code example. (It's a blend of how gulp.task(), browserify(), .bundle() & .pipe() work together, along with your code mixed into it. You should be able to get it to work on your computer.)

like image 41
Clomp Avatar answered Nov 03 '22 01:11

Clomp