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'));
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
Actually you got pretty close, except for two things:
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
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.