Closed davojan closed 9 years ago
cc @jdalton
A sanity check of our reasons would be good but we check for define
before exports
because build optimizers, like r.js
add an exports
object which isn't the exports
we are expecting. Since he
works with AMD and Node out of the box there's no need for the amdefine
use.
Can you elaborate on "doesn't correctly exports"? What is it doing in the presence of amdefine
?
It doesn't export anything, just empty object. When r.js is running with 'nodeRequire' configuration option it tries to load 'he' from node_modules as a regular npm module, but due to presence of 'amdefine' (it's necessary for AMD modules to work on node) 'he' thinks that it's used in AMD environment and doesn't write itself to 'module.exports'.
If you are in doubt that the opposite check order can break compatibility with some other environments, it's possible to check both conditions separately without 'else if'. I can modifly the pull-request if you'd like.
Btw lodash has the same problem and I'm going to submit the same pull-request there too :)
It doesn't export anything, just empty object. When r.js is running with 'nodeRequire' configuration option it tries to load 'he' from node_modules as a regular npm module, but due to presence of 'amdefine' (it's necessary for AMD modules to work on node) 'he' thinks that it's used in AMD environment and doesn't write itself to 'module.exports'.
Does amdefine
write to the global
? If so and it's supposed to make AMD code run in Node why wouldn't he
just work?
Btw lodash has the same problem and I'm going to submit the same pull-request there too :)
Hold off on that for now, I'm closer to wontfix
than fix
atm.
Does amdefine write to the global? If so and it's supposed to make AMD code run in Node why wouldn't he just work?
Yes it writes to the global. It doesn't work because in this mode r.js loads he from node_modules folder and treats it as a regular npm package, so it expects to see exports in this case and doesn't check 'defined' modules, I think.
May be @jrburke could clarify the issue?
we check for define before exports because build optimizers, like r.js add an exports object which isn't the exports we are expecting
My version works OK on browser-side in AMD mode (without amdefine) even with checking .exports before define.
Look, I realized that I can configure r.js to use 'he' as regular AMD module on server-side. But that is not very convenient. I'm working on as isomorphic app that has bunch of dependencies, and making them to work both on browser and server side is quite a challenge. Most of libraries doesn't have AMD compatibility in the same way as yours and I have to use separate version for browser and npm module for server.
And
If you are in doubt that the opposite check order can break compatibility with some other environments, it's possible to check both conditions separately without 'else if'. I can modifly the pull-request if you'd like.
May I try? :)
Yes it writes to the global.
The docs don't mention that do they? Is this when it's compiled that its global or when running the code in node? It looks like for node code you have to do var define = require('amdefine')(module)
in your file. How are you using amdefine
? Are you using amdefine/intercept
?
Ups. You've caught it! In one of those places there is a forgotten var
, that's why define is written to the global
. After adding the var
all works fine. And lodash too.
Thanks for your help and patience.
No prob. I'll still check in on r.js (it's been 2 yrs) and see how its compiling.
"he" doesn't correctly exports it's API when used with RequireJS in "node-compatibility mode" as described here: http://requirejs.org/docs/node.html#nodeModules
I changed the order of environment detection logic to prevent amdefine's fake 'define' making wrong decision about AMD environment.