Nw.js: Init problems with require.js

Created on 12 Apr 2013  路  21Comments  路  Source: nwjs/nw.js

I tried nw 0.5.0 on OSX with a SinglePageApp created using yeoman 1.0.0beta3. I'm making use of require.js, so my index.html loads my packaged JS at the end like:

Which in turn loads the main.js and runs it. When I prepare my distribution directory and open my index.html from a final yeoman build, the app runs smoothly. Then I created a package.json, packed all as a zip, renamed it to .nw and opened it.

What happens now is, that my JS does not seem to run. The error I see at the console is:

Uncaught TypeError: Object function (name) { if (name == 'nw.gui') return nwDispatcher.requireNwGui(); return global.require(name);} has no method 'config'

Is this an issue related to my use of require.js, or am I doing something totally wrong?

Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.

stale

Most helpful comment

Could work around this by overwriting the require function:

<script data-main="js/bootstrap.js" src="js/lib/require.js"></script>
<script>
var node_require = window.require;
window.require = function(data) {
    return (typeof data === 'string' ? node_require : window.requirejs).apply(window, arguments);
}
</script>

This way the require function itself finds out which "require" you meant.

All 21 comments

Thanks for reporting.

Is the same thing happening on 0.4.2?

Thanks for replying. Unfortunately yes.

It's a name conflict with require.js. Anybody find a work-around yet?

I've modified require.js to expose requireClient instead of require. Dirty hack but it solves the problem. You only need to change a few lines in require.js.

Ofcourse this sucks if you rely on thirdparty libraries which require()'s stuff inline. :)

I ended up getting everything working by just using "requirejs" in the file that is initially loaded via data-main. Then everywhere else I pass require into the define function and that seems to prevent the conflict.

define(function (require) {
    var Backbone = require('backbone'),
    // other goodies here
}

No code modifications needed. However I did have to modify one line in the require.js text.js plugin file to get that working. If anyone needs that let me know.

@rawberg, that's at least a solution comparable to the approach mentioned before. IMHO require.js is very popular. Recommending a change like your's seems not very clean, even if it solves the problem. It would be great to see this problem beeing solved in node-webkit instead.

It's not like it聽was node-webkit's idea to聽use require(); here it聽is based on the much聽broader tradition of聽Node.js.

And if it聽comes to聽NodeJS vs. RequireJS, the聽latter probably does聽not have a聽chance, or聽so it聽seems to聽me.

Of course these聽two are聽conflicting on what require() means. They聽are the聽two generally conflicting (though not totally opposite) models of how CommonJS happens.

@Mithgol understood and agree with you, when it comes to the question node.js vs. require.js. When you are writing a node.js based app, there's no need to make use of require.js. Unless you make use of some nifty ifty framework like sails, where there frontend JS comes into play. Wonder whether someone did ever have this problem? Since the yeoman team around Addy Osmani is working on a combination of yeoman, require.js and sails, I'm sure they will stumble upon the very same problem soon. We'll see. Meanwhile a manual workaround seems the only option.

@rawberg I could use that plugin tweak, if you don't mind. I'm attempting the same on require-cs (the cs! coffeescript loader), we'll see how far I get there. For the time being only way I've been successful running our app in node-webkit is by adding "nodejs": false to package.json to disable js access to node functions. Not exactly a winning solution, since it removes access to native UI control, as far as I can tell.


EDIT
Forgot to mention, for those of you not using the cs! plugin, you may be able to use the r.js optimizer's namespace option to shim loading the rest of your library, if you don't mind the build step in between. Once jrburke/requirejs#497 is fixed this should work for coffeescript, too, I believe.

If it'd be useful to anyone I don't mind sharing my requirejs config for the optimizer, though you'll need to strip my coffee-related configuration. Just let me know.

I changed line 237 of text.js.

From:

if (masterConfig.env === 'node' || (!masterConfig.env &&
            typeof process !== "undefined" &&
            process.versions &&
            !!process.versions.node)) {

To:

if (masterConfig.env === 'node') {

I haven't ran r.js on my project yet so I'm not sure if this tweak will interfere with it.

Thanks for that, I'm just coming back around to hacking on buildsystem stuff today. If it causes issues with r.js I'll try to find a workaround and post it.

@rawberg I had issues with the requirejs text plugin as well, and did this:

if (masterConfig.env === 'node' || (!masterConfig.env &&
        typeof process !== "undefined" &&
        process.versions &&
        !!process.versions.node &&
        !process.versions['node-webkit'])) {

So, when running in node-webkit, the text plugin will _not_ believe it is running under node, through r.js. Seems a little safer.

I ended up running into issues when I also wanted to include node modules using node's built-in require statement.

After unsuccessfully trying to use "requirejs" instead of "require" I decided to change all "require" references to "require_browser" in both require.js and text.js. Now I can use require_browser when I want to use require.js and "require" when I want to use node's commonjs based system.

So far everything seems to be working great! Although I haven't tried to use r.js yet, should be pretty soon though.

I've found that RequireJS exports multiple variables, one being require and requirejs. Both are the same variable so using requirejs would not cause conflicts with the Node require function.

I was wrong about the comment above. Other modules that are AMD compatible might still use the require method and so they would fail to load.

Are there any updates here?

I am starting a http server and open a new window with gui.Window.open("local web address"). However, I get the error
"Uncaught Error: Module name "nw.gui" has not been loaded yet for context: _. Use require([])"
in the new window. This is an exception fired in requirejs directly. RequireJS is used in the website by the http server, not in the main window/app.

Unfortunately the faq is not clear enough on how to solve this issue.

This issue is聽definitely going to聽be fixed in聽the聽next release (NW.js v0.13.0) and聽thus you聽just have to聽wait for聽it.

NW.js v0.13.0-alpha5 already has Node.js require() namespaced as nw.require(). You'd still want to聽wait for聽a聽release though. Because that聽alpha has聽usual alpha聽problems of聽incompleteness (such聽as #3945 or #3995 for聽example).

Could work around this by overwriting the require function:

<script data-main="js/bootstrap.js" src="js/lib/require.js"></script>
<script>
var node_require = window.require;
window.require = function(data) {
    return (typeof data === 'string' ? node_require : window.requirejs).apply(window, arguments);
}
</script>

This way the require function itself finds out which "require" you meant.

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

Posting as a heads up for anyone else who finds this issue via search:

The embedded Node.js runtime can be turned off using a manifest setting. This may help if you (like me) have static content or no need to use Node inside nw.js. Turning off node will eliminate the conflict between its instance of require and the one in your project.

https://github.com/nwjs/nw.js/wiki/faq-name-conflict
https://github.com/nwjs/nw.js/wiki/Manifest-format#nodejs

Have been struggling with this aswell, fixed it with setting the environment manually:

window.require.config({ config: { text: { //Valid values are 'node', 'xhr', or 'rhino' env: 'xhr' } } });

(Ofcourse after loading requirejs)

This will force the environment to be xhr, so it uses xhr instead of node require. Before loading requirejs I put node's require in window.nodeRequire and unset window.require.

Was this page helpful?
0 / 5 - 0 ratings