requirejs / r.js

Runs RequireJS in Node and Rhino, and used to run the RequireJS optimizer
Other
2.57k stars 671 forks source link

`require('requirejs')` resolved to different files results in failure #838

Open ghost opened 9 years ago

ghost commented 9 years ago

I have this folder structure:

As external/foo has its own package.json and is published in npm on its own, I wanted to npm install requirejs --save there. The problem is, I use

requirejs(ids_to_load, function callback(...) { ... }, function errback(...) { ...});

in external/foo/lib/bar.js. When I run grunt bar in root, which has tasks using grunt-contrib-requirejs, but also uses tasks from external/foo, the line above in external/foo/lib/bar.js behaves differently depending if external/foo has its own requirejs in external/foo/node_modules or not (the same version).

If external/foo does not have its own version, the line above works, but it loads root/node_modules version of bin/r.js. If external/foo does have its own version, and it is loaded first (Gruntfile has loadTasks('./external/foo/...') before loadNpmTasks('grunt-contrib-requirejs')), it passes undefined to all parameters of the callback (and does not call the errback). OTOH, if the load order in Gruntfile.js is switched and external/foo tasks are loaded later, it works again.

It is strange to have this erratic behaviour depending on the order of loading.

jrburke commented 9 years ago

I'm not sure I follow fully. If node's require('requirejs') gives back a requirejs, then if the issue is path resolution calling requirejs([], it might need a requirejs.config({baseUrl: __dirname}) or something like that so that the explicitly desired start path is used.

If it is a problem that the requirejs([]) call ends up loading modules that are node modules and not modules found by the requirejs config to find AMD modules, passing nodeRequire in a requirejs.config() call might help?

But I am not sure I am following the issue completely.

ghost commented 9 years ago

It's not baseUrl thing nor other triviality like modules cannot be found. The bug is, on some occassion, only dependent on load order of two identical copies of requirejs, requirejs works, loads the modules and passes them to callback's parameters; but with different load order, it calls the callback (not the errback) but passes undefined to each parameter (number of passed parameters in correct).

The bug is: :"requirejs behaves as if it loaded the modules, calls the callback, but passes undefined for each module; really passes, as console.dir(arguments) shows n undefineds".

Actual example is https://github.com/amber-smalltalk/amber/blob/master/Gruntfile.js: if you clone the project, make it into working condition by npm install, cd external/amber-dev && npm install && cd ../.. and grunt amdconfig, then running grunt works and .st files in src are compiled to corresponding .js files. If you switch lines 8 and 12 in Gruntfile (both are loading tasks that use requirejs, but different copy of it), grunt fails. It fails with passing undefineds to requirejs callback, as you can check by putting console.dir(arguments) before https://github.com/amber-smalltalk/amber/blob/master/external/amber-dev/lib/amberc.js#L215 (where requirejs is ultimately called and sometimes gets the real modules, sometimes gets load of undefineds, only depending on which copy of requirejs is loaded first).