Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to expose 'require' to the browser when using browserify from within gulp?

When I have a file x.js that looks like this:

x.js

module.exports = function (n) { return n * 111 }

and I run browserify from the command line like so:

browserify -r ./x.js > bundle.js

I get an output file that looks like this (roughly):

require=(function e(t,n,r){function ......
./App.jsx":[function(require,module,exports){
module.exports=require('0+DPR/');
},{}]},{},[])

Then in my browser code I can do this:

<html>
  <head>
    <title>React server rendering example</title>
    <script src="static/bundle.js"></script>
  </head>
  <body>
    Welcome to the React server rendering example. Here is a server-rendered React component:
    <div id="53a442ff8b39d"></div><script>
    var x = require('./x.js');
    console.log(x(3))
</script>  </body>
</html>

I actually have two questions:

1) This doesn't quite work in the browser I get the error: "Uncaught Error: Cannot find module './x.js'". Why is that happening?

2) I actually want to run this in gulp using vinyl-source-stream. I've tried doing something like this in my gulpfile but it doesn't work. Any ideas? I get the error 'require is not defined'

var   gulp = require('gulp'),
  browserify = require('browserify'),
  source = require('vinyl-source-stream');

var b = browserify({
    entries: ['./x.js'],
  });
   b.bundle({debug: false})
   .pipe(source('bundle.js'))
   .pipe(gulp.dest('./build'));
like image 557
asolberg Avatar asked Jun 20 '14 14:06

asolberg


2 Answers

Update: You can reference an alias in your -r switch

Try: browserify -r ./x.js:my-module > bundle.js

And in your page: var x = require('my-module');

NOTE: if you used an -r switch on a node module like fs or through, you don't need an alias for these because they usually have a name in their package.json file.

See node-browserify -- external requires for more info.


If you are going to bundle your x.js like that (with -r switch) there are a couple of options

1) Take the script in your html page and bundle it separately.

      Create a main.js file and put your JS in it.

      Use browserify -x ./x.js > main.js

      By using the -x switch, Browserify will link your bundle.js in as a dependancy.

      Then reference both JS files in your page.

2) Use name generated by Browserify.

      var x = require('0+DPR/');

      See Update above to create an alias.

Good resource below since you are looking to go further with Gulp

  • Browserify - Bring Nodejs modules to browsers

For more Gulp + Browserify (uses Watchify as well for livereload) Check out blog post on Viget

  • Gulp + Browserify: The Everything Post
like image 119
mikekidder Avatar answered Oct 11 '22 02:10

mikekidder


Actually you got pretty close, except for two things:

  1. you need to expose your 'x.js' with an exposed name that you can use to require() later, for e.g.: 'x' is a good choice in your case

  2. instead of require('./x.js'); you should do require('x');

So to give you the full answer:

in lib/x.js

module.exports = function (n) { return n * 111 }

in gulpfile.js

var gulp = require('gulp');
var browserify = require('browserify');
var transform = require('vinyl-transform');

gulp.task('build-lib', function () {

  var browserified = transform(function(filename) {
    return browserify(filename)
      .require(filename, { expose: 'x'})
      .bundle();
  });
  return gulp.src('./lib/x.js')
    .pipe(browserified)
    .pipe(gulp.dest('./dist')); // currently this recipe will output to ./dist/x.js. you may use a rename plugin to output it with a different filename for eg. bundle.js
});

gulp.task('default', ['build-lib']);

in an HTML doc (index.html)

<html>
...
<script src='dist/x.js'></script>
<script>
   var x = require('x');
   console.log(x(3));
</script>

A little bit details about the gulp recipe:

I used vinyl-transform instead vinyl-source-stream.

You can choose to use vinyl-source-stream but you have to remember to pipe in vinyl-buffer right after that if you have more transformations using plugins that works on buffered vinyl file objects (instead of streaming vinyl file object that vinyl-source-stream gives out)

What vinyl-transform does is that it takes care of both buffered and streaming vinyl file objects for you.

like image 30
Hafiz Ismail Avatar answered Oct 11 '22 02:10

Hafiz Ismail