Thanks for the heads up on the github issue. I think I *just* figured
out how administrators on the amdjs group can get notifications --
apparently "owners" do not get notifications by default, and I had to
create a separate "team" with those same members to apparently get
notifications.
At least I think it is supposed to work. We'll see if it works from
this point forward. Currently the owners/notification list are github
users rcgill, unscriptable, rbackhouse and me. Other implementers of
amd loaders can get access too, just ping me.
I responded in the ticket, but I think it is a bit early to specify
the top-level call, see the issue for more detail. We should continue
the discussion in the ticket since others have already responded in
that ticket vs this email thread.
James
Following James Burke's advice, I am moving the discussion back to the
mailing list. To summarize, we discussed the possibility to use
define() to bootstrap dynamic loading of top-level modules, but it
appears to be impractical due to optimizations which may delay the
execution of define(), sometimes indefinitely.
Instead of calling a method with a different name in each loader, can
we agree on a method to trigger the loading of the main module?
I propose to make the local require() method accessible at the top
level as define.require.
Currently, this method can only be accessed cross-loader by calling
define() and receiving the method as an argument. Since there is no
guarantee that the method provided to define() will run in the first
place, we are facing a chicken and egg problem, which would be solved
by giving access to the method through the global variable define.
The idea is to use:
define.require(["main"]);
instead of calling a different method in each loader:
requirejs(["main"]);
curl(["main"]);
...
Looking forward to your feedback,
Cheers,
Eric Bréchemier
I am open to figuring this out. As I work on volo, which can install
code dependencies, I can see value in a common top level call to at
least handle setting configuration information, like a 'map' config.
This would allow volo to work with any AMD loader, which would be
great.
I liked the idea of using require() and require.config(), but others
on this list believe it can be confused with the local require. Also,
in cases where there is an existing require() for some reason, it may
be nice to have a non-conflicting call.
If it is define.require(), would the config call be define.config()?
I would like it more if the top level call and the config call were
separate from define, since define is focused on module definition,
not loader configuration and bootstrapping. In other words, having a
separate API entry points for loader concerns vs. module definition
would be nice.
Given that, I'm still partial to a global require() and
require.config(), but open to other suggestions.
James
If another name is needed, I suggest "run".
For example:
define.run("main");
or
define.run("main",config); with an optional config object
Another approach would be to return something from define, e.g. a
promise, which may be used to bootstrap the loading:
var promise = define("main",function(){...});
promise.then(function(){
// loaded
});
promise.setup(config);
promise.run();
This is a more complex approach and I would personally favor a simple
function call.
Cheers,
Eric
My bigger concern was placing the function under the 'define'
function. It is nice, for example in node, if they just had to
implement a simple define() function without picking up these calls,
since they have a different way to trigger module loading, and do not
have the same configuration needs as a web based module loader.
So given that, I still prefer require() and require.config(). Or
something else that is not put under define().
James
I think that amd.define(), amd.config() and amd.require() would make sense.
Defining require() at the top level with a different semantic than
CommonJS would probably be confusing.
Cheers,
Eric
It seems that it can be confusing to talk about a global require vs. a
local require. I can see the point, but I like that the understanding
of the local require carries over into global require use.
There is also a concern about conflicting with a node-type
require(''), but that may not be an issue in practice. In Mozilla
Jetpacks, they have a sync-style require('') for their modules. But in
those cases, this sort of top level "start loading/tracing
dependencies" calls are not needed, and config is specified outside
the code, as I recall.
Eric's idea of 'amd' is interesting, but I still think that is mixing
up loader concerns with module format concerns -- the config() and top
level loading calls are loader concerns, where the AMD specs are
around module definition APIs. 'amdload' might be more accurate. But
then it acts a lot like require()...
It would be good to get input from John Hann, Rawld, Richard
Backhouse, other loader implementers.
James
What are the differences? It seems to me:
* how relative paths are resolved, which makes sense since the global
require() as a different relative relationship
* possibly the existence of a require.config() on the global object?
James
Oh, if you mean to ask how synchronous require caches in AMD it should
be by module ID. It is implied from the spec since relative module IDs
are resolved relative to the reference module ID and not its path.
Node chose to use path.
James
Cheers,
Eric
I can appreciate wanting to keep `require` out of the global scope. curl.js doesn't declare it globally by default to avoid confusion and common noob mistakes.
However, adding application bootstrap methods to the local require seems like the wrong direction to me. Here's why:
1. config() should be a one-time event, not something that devs feel they can do at any time. Allowing config at any time could easily make the app nondeterministic.
2. Adding more methods to the local require will not help us or our devs migrate to evolving module standards. The more we add to the local require, the harder it's going to be for all of us. curl.js only supports the standardized local require. There are no .config or .ready or other things on it.
Just declare a separate global for app bootstrap. That solves the problem. The few devs who need to create cross-loader code can do it by casting the loader-specific global (e.g. `curl`) to `require` quite easily.
-- John
Sent from my sonic screwdriver
On Mar 2, 2012, at 5:24 PM, Taka Kojima <ta...@gigafied.com> wrote:
> require.config
Many of you have heard me rant about how we can't concern ourselves too
much with confused people so long as our API is rational. If a
programmer doesn't understand the difference between a global variable
(e.g., global require) and a lexically scoped variable (e.g., local
require), then I don't hold much hope for us to be able to fix that
person's skills with a wonderful API.
And the behavior of the two versions of require is really
identical...they both resolve modules with respect to their "defining"
module. In the case of global require, the "defining" module happens to
be the global space or root space...so a relative module is nonsensical.
Also, I'm not seeing this as a big pain point.
> There is also a concern about conflicting with a node-type
> require(''), but that may not be an issue in practice. In Mozilla
> Jetpacks, they have a sync-style require('') for their modules. But in
> those cases, this sort of top level "start loading/tracing
> dependencies" calls are not needed, and config is specified outside
> the code, as I recall.
>
> Eric's idea of 'amd' is interesting, but I still think that is mixing
> up loader concerns with module format concerns -- the config() and top
> level loading calls are loader concerns, where the AMD specs are
> around module definition APIs. 'amdload' might be more accurate. But
> then it acts a lot like require()...
>
> It would be good to get input from John Hann, Rawld, Richard
> Backhouse, other loader implementers.
I favor global require. If John (curl) doesn't want to do that, I think
that is fine. As he points out, any user switching to curl would just
need to alias a variable. That said, I'm not against some of the other
alternatives like amd().
I am against overloading define(). define's semantics are clear and
simple. Tarnishing that under the cover of unconfusing the confused
would be a shame.
--Rawld
> 2. Adding more methods to the local require will not help us or our devs migrate to evolving module standards. The more we add to the local require, the harder it's going to be for all of us. curl.js only supports the standardized local require. There are no .config or .ready or other things on it.
>
> Just declare a separate global for app bootstrap. That solves the problem. The few devs who need to create cross-loader code can do it by casting the loader-specific global (e.g. `curl`) to `require` quite easily.
Generally agree. Though I think we need a standard way to pass config to
the loader.
--Rawld
Richard
Rawld, my biggest concern with the global require was how easy it was to
forget to include the ref in the define signature and use the global one
when the define version was expected. I haven't checked recently but
there were still places in the dojo codebase where this mistake had been
made. I would not consider the dojo contributors novice developers.Richard