So i've come across an interesting use case where i'm using Browserify to bundle all of my assets together in a project, but a large external (external to the project) module needs to be loaded in when a certain in-app window is accessed. (It's a video player module made up of three scripts that get pulled in asynchronously when required).
At the moment i'm getting all kinds of errors from uncalled object
errors if the requireJS module is loaded in before the Browserified app.js
file, to cannot find module
errors if loaded in after the Browserified code.
Is there anyway i can get Browserify and RequireJS to play nicely on the same page? I'm losing my mind!
So i've come across an interesting use case where i'm using Browserify to bundle all of my assets together in a project, but a large external (external to the project) module needs to be loaded in when a certain in-app window is accessed. (It's a video player module made up of three scripts that get pulled in asynchronously when required).
At the moment i'm getting all kinds of errors from uncalled object
errors if the requireJS module is loaded in before the Browserified app.js
file, to cannot find module
errors if loaded in after the Browserified code.
Is there anyway i can get Browserify and RequireJS to play nicely on the same page? I'm losing my mind!
Share Improve this question asked Jun 11, 2014 at 17:18 ScottyScotty 2,6656 gold badges30 silver badges39 bronze badges 5- Try wrapping your bundled javascript in a closure. – idbehold Commented Jun 11, 2014 at 18:01
- I think it's Browserify adding a require global at the beginning of the bundled file. How would i wrap the entire imported app.js file in a closure without modifying the browserified file? – Scotty Commented Jun 11, 2014 at 18:14
- Did you ever work around this? I'm coming from the opposite direction ... most of my app is requirejs, but I want to pull in a single library available on NPM that I plan to package with a browserify wrapper. So far no luck. – Mike Griffith Commented Aug 14, 2014 at 12:39
- This might be a death sentence for my use case: "Finally, RequireJS in Node can only load modules that are on the local disk -- fetching modules across http, for instance, is not supported at this time." <requirejs.org/docs/node.html> – Mike Griffith Commented Aug 14, 2014 at 12:43
- Are any of your modules loaded in the Browserify bundle UMD modules? This could cause an issue if RequireJS is loaded on the page because it might not export to CommonJS if it detects AMD. – cuth Commented Aug 16, 2014 at 5:17
3 Answers
Reset to default 11TL;DR - use window.require
in your browserified script.
Maybe it would still help someone. I happen to use an 'external' dojo-based library totally based on requireJS-style AMD, which is absolutely un-"browserifyeble" and un-convertable to CommonJS or anything sane. My own code is totally Browserified. It's working OK like this:
Load the AMD loader (which defines the global
require
function) before the browserified script:<script src="dojo/dojo.js"></script> <!-- RequireJS/AMD loader, defining a global 'require'--> <script src="app/main.js"></script> <!-- The Browserify bundle -->
In your own js, call the
require
function onwindow
object ('cause you'll have a local browserify-require
shadowing the global one)window.require(['dojo/dojo'], function (dojo) { ... });
The 'external' app or library, which calls
require
on its own to load submodules etc., works just fine 'cause that code is out of browserify context and the globalrequire
is not shadowed there.
Maybe if you have some pure nice standard RequireJS modules, you could somehow convert them to be Browserifiable, but in my case that wasn't an option.
There is a tool called browserify-derequire that resolves this issue by renaming browserify's require statmenets to avoid the naming collision.
It can be installed with npm using:
npm install -g browserify-derequire
Use it as a browserify plugin by changin your build command to:
browserify src/*.js -p browserify-derequire > module.js
There is more discussion on this issue at: https://github.com/substack/node-browserify/issues/790
For a gulp friendly solution (similar to what @Cride5 proposed) you can use gulp-derequire plugin.
Basic example from docs:
var derequire = require('gulp-derequire');
var browserify = require('browserify');
var source = require('vinyl-source-stream');
gulp.task('build', function() {
var bundleStream = browserify({entries: './index.js', standalone: 'yourModule'}).bundle();
return bundleStream
.pipe(source('yourModule.js'))
.pipe(derequire())
.pipe(gulp.dest('./build'));
});
Plugin is also based on derequire module so all options are supported.