0

I'm trying to use Browserify so that I can use an npm package in the browser. The package I'm trying to use is this

I have a fcs.js file:

// Use a Node.js core library var FCS = require('fcs'); // What our module will return when require'd module.exports = function(FCS) { return FCS; }; 

And an index.js file:

var FCS = require('./fcs.js'); console.log('FCS IS '); console.log(FCS); 

I then ran:

browserify index.js > bundle.js 

And created an index.html file:

<html> <script src="bundle.js"></script> <script> var fcs = new FCS(); </script> </html> 

But I end up with the error:

Uncaught ReferenceError: FCS is not defined 

Maybe I'm not grasping the concept correctly. How can i use this package in the browser? Thanks.

3 Answers 3

3

Don't do this: require('./fcs.js');

Do this: require('./fcs');

When you require something, the extension is implicitly .js. Also make sure that your module, FCS, has an entry point (the default is index.js, but you can change that in the main entry in the package.json).

Also, in your index.html document, you're expecting that FCS is a global object. I haven't seen the internal code of FCS, but it will only be globally available if it's attached to the window object.

When you require something, it only makes it available to the rest of your code where it's required. If you want to make it globally available, you have to attach it to the window object, just like anything else.

In other words, the internals of your FCS module might look something like:

// node_modules -> fcs -> index.js var FCS = function() {}; window.FCS = FCS; // this makes it globally available module.exports = FCS; // this lets you require it 
Sign up to request clarification or add additional context in comments.

6 Comments

Thanks, that helps. No FCS isn't attached to window object. I can do that in index.js but that doesnt seem to be right think to do as polluting global namespace....
@Mark, that's the way you do it. Either you attach it to window to use it globally, or you don't, and you don't have access to it globally. It's one or the other. Not polluting the global namespace is usually a good idea, but if you're expecting to be able to call new FCS(), then you're implicitly expecting FCS to be a part of the global namespace. If you don't want that, then don't try to call new FCS() in a global context. Instead, do it from the code where you require'ed the FCS module.
Thanks, @JoshBeam - this was really helpful. Attaching things to the window object is not discussed at all in the documentation. One question though... might it be possible to attach the require function to the window object so one could do FCS = window.require('./fcs'); outside of the context of the bundle.js? This seems a more general solution - only one thing attached to window, instead for one of each module you might use. I've been wrestling with this problem at home - I'll try it later.
@Kryten, I guess so, sure, but I haven't seen that before, and my gut gives me a skeptical feeling about it. Usually when using require, the assumption is that you're going to use the require'd code inside another node module or whatever (i.e., not inside an inline script tag, because that's where you'll need the object to be attached to the window)
@Kryten, another thing too is that this idea of attaching things to a global namespace (like window) isn't so farfetched. Angular does something similar when you use it with Browserify and require it (not saying that's an argument for or against the approach... just saying that it works.)
|
1

@JoshBeam's answer is correct - in order to expose assets inside the browserify bundle, you need to attach something to the window object. But instead of exposing specific assets, I wanted something more general.

Here's what I did:

in my app.js

require('this') require('that') require('./modules/mycode') ... window.req = require 

And in my <script> tag in my HTML:

something = req('./modules/mycode') 

Notice that, instead of assigning the require function directly to window.require, I gave it a different name. The reason for this is simple: if you call it window.require, you're overwriting the original require and you'll find yourself in an infinite loop of recursion (at least until the browser runs out of stack space).

1 Comment

very handy, well put
0

The problem is that your inline script (in index.html) is expecting a global variable called FCS to exist (when you do new FCS()). This is not the case because in index.js, your FCS variable is scoped to that file.

You should write all your scripts in separate files and bundle them all using browserify, avoiding the inline script or make FCS global, by attaching it to window.

2 Comments

So what would I do to index.js to get access to FCS()? If i do "window.FCS = FCS;" it works, but you suggest that is incorrect....
Josh Beam pretty much covered it in his comment.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.