Skip to content

Requiring modules CommonJS style in the browser #274

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
flimzy opened this issue Aug 22, 2015 · 6 comments
Closed

Requiring modules CommonJS style in the browser #274

flimzy opened this issue Aug 22, 2015 · 6 comments

Comments

@flimzy
Copy link
Member

flimzy commented Aug 22, 2015

Is there any way to require external JavaScript modules (CommonJS style) in the browser?

I tried the suggestion in #146:

foo := js.Global.Call("require", "foo")

And that worked fine in nodejs, but it does not work with Browserify (it says $global.require is not a function). As I understand Browserify, this makes sense, since 'require' isn't a true JS function, but is interpreted by Browserify during its 'compilation'.

So is there some other way to make this work, either with Browserify, or with some other third-party Javascript "wrapper"? I'd ideally like one that builds a single output file, so I don't have to worry about providing multiple JS modules via HTTP to the browser, and the complications that come with that.

Or maybe I should request a js.Require() feature be added to gopherjs/js? Is that even practical, given the different use cases anyway? (Presumably it would need to just wrap js.Global.Call("require") for node, but do something more Browserify-ish like slurping in the source JS code when the target is the browser... but AFAIK, GopherJS has no way of knowing, at the moment anyway, whether it's building for the browser or for node)

@dmitshur
Copy link
Member

Where is require defined?

@flimzy
Copy link
Member Author

flimzy commented Aug 22, 2015

That's the thing... I don't think it is. Browserify works as an IIFE, so Browserify's require() never exists as a true JavaScript function.

Up to now, I'm just having Browserify require() everything I need, and storing those modules in global variables for easy access by my GopherJS code. It works, but it's not ideal, as it necessitates a JavaScript "wrapper" around my GopherJS code.

@dmitshur
Copy link
Member

This may not be the solution you're looking for, but I just want to check you're aware it exists.

If you place JavaScript files in the same folder with .inc.js extension, when building the Go package, GopherJS will concatenate the output with those JS files.

See #111 for full details.

Did you already know about that?

@flimzy
Copy link
Member Author

flimzy commented Aug 22, 2015

I did not know about that! Is it in the documentation somewhere that I missed?

I'm not sure if that will be enough for me, as the order in which some of my JS modules are loaded is important, and my reading of the source code suggests the files are included in a non-deterministic manner (is that accurate?)

@neelance
Copy link
Member

The problem here is that the output is $global.require instead of just require. This makes it impossible for the static analysis of Browserify to "see" those calls to require. I want to avoid having to change / special case the output just for this use case. What about putting those require calls into a single .inc.js file and include that? This way Browserify can process the calls and your modules will be loaded in the correct order.

@flimzy
Copy link
Member Author

flimzy commented Oct 18, 2015

Yes, using .inc.js is clearly the most straight forward way to solve this issue.

@flimzy flimzy closed this as completed Oct 18, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants