There are some nuances, or tradeoffs with that approach:
1) multiple.js might actually be a built layer. So there may not be
any anonymous module in that file, making it difficult to decide what
to give for 'duplicate'. If there is a named 'duplicate' module in the
built file, the answer is easy (return that module), but this use case
seems to be about anonymous modules.
In any case, it seems realistic to want to map multiple built modules
to the same file, and that config would look similar to the above.
Taka Kojima suggested in a comment for this gist:
https://gist.github.com/1630091
that perhaps that sort of config would be a different type of config.
But I think that is just an optimization of the format for modules
that fit under a module ID, for specifying that 'a' and 'b' are in the
same JS file, I expect it would look like the config in this example.
2) To enable this behavior, it would mean a loader would have to hold
on to the factory functions for every anonymous module, just in case
this config case comes up. At first thought, I do not like that -- it
means more bookkeeping and keeping around more in memory for things
that usually are not needed.
3) How would this optimize? It seems like two versions of the
multiple.js would show up in the built file. That seems wasteful.
So while the behavior your advocate makes logical sense, this behavior
is a bit too tricky (it looks like a way to do object instantiation,
where modules should be more like singletons/statics), and the use
case for this being useful is so small that it is overshadowed by the
extra bookkeeping/memory cost and possible confusion and extra file
size cost when mapping to built files.
At least that is my first pass thinking through it. I'm open to
counterarguments. In particular, building up how this use case is
useful and would occur frequently enough to warrant the costs for it.
James
I am definitely in favor of one anonymous module definition per file.It gets super messy doing anything else, especially in older browsers that don't handle onLoad events as they should.
what should happen here?
// script tag in pagerequire({baseUrl: './',paths: {multiple: 'multiple',duplicate: 'multiple'}}, ['multiple', 'duplicate'], function (multiple, duplicate) {multiple.multi = true;console.log('multiple', multiple.multi);console.log('duplicate', duplicate.multi);});
// multiple.jsconsole.log('loaded');define(function (require, exports, module) {
console.log('defined', module.id);return {};});
i'd expect that a "good" loader would at least not try to fetch the same url twice - not sure that would be something needing to be mandated in a spec but might be worth discussing what each of us would expect in case someone thinks there's a good reason to try to fetch the code from the same url twice.
should the "multiple" and "duplicate" modules be the same module - ie the module's factory only gets run once and the exports are cached and shared - or should the module's factory be run for each module id that maps to it and have independent exports for each module?
my opinion is that these should be 2 different modules since module ids are a layer of abstraction that maps to urls. if 2 module ids happen to map to the same url, they are still 2 logically distinct modules. i'd expect to see the following in the console:
loadeddefined multipledefined duplicatemultiple trueduplicate undefined
what does everyone else think?
is there even agreement that we could have a valid case where 2 module ids could map to the same url?
> So there may not be
> any anonymous module in that file, making it difficult to decide what
> to give for 'duplicate'. If there is a named 'duplicate' module in the
> built file, the answer is easy (return that module), but this use case
> seems to be about anonymous modules.
Built layers can easily provide anonymous modules (the dojo
loader/builder can do this).
> In any case, it seems realistic to want to map multiple built modules
> to the same file, and that config would look similar to the above.
> Taka Kojima suggested in a comment for this gist:
> https://gist.github.com/1630091
>
> that perhaps that sort of config would be a different type of config.
> But I think that is just an optimization of the format for modules
> that fit under a module ID, for specifying that 'a' and 'b' are in the
> same JS file, I expect it would look like the config in this example.
>
> 2) To enable this behavior, it would mean a loader would have to hold
> on to the factory functions for every anonymous module, just in case
> this config case comes up. At first thought, I do not like that -- it
> means more bookkeeping and keeping around more in memory for things
> that usually are not needed.
iiuc "this behavior" means avoiding the second server transaction...I agree.
> 3) How would this optimize? It seems like two versions of the
> multiple.js would show up in the built file. That seems wasteful.
That should be left up to the dev who specified this kind of weird
config to specify a build profile to get the desired effect. It is
certainly possible to optimize.
--Rawld
In your case, if you really needed to do that what about something like:
// multiple.js
(function(){
var fac = {};
define("multiple", function (require, exports, module){return fac;});
define("duplicate", function (require, exports, module){return fac;});
});
I agree; please tell me that's what dojo does :).
I had a bug filed a while back on requirejs to fix this because I was
doing reloads for each ID even though they mapped to the same URL. It
is far more common to want to only fetch the script once, and map
multiple IDs that were built into one file to one script, and only
have it loaded once, than to try to get this other behavior.
Maybe using paths settings is not the right way to solve that build
issue, maybe there needs to be something else.
However, this kind of "create two different IDs that load the same
file that have an anonymous define() to get two different module
exports from the same factory function" is likely going to lead to
unexpected, undesirable consequences. Such as multiple inclusions of
the same factory function in a built file once that config is used in
a build.
So I'm still missing the use case that makes creating these other
hazards worthwhile. It would also imply creating some other config to
express "all these IDs are in this built file".
James