The functionality you are looking for is found in RequireJS and follows a spec called Asynchronous Module Definition (AMD). It is a mechanism that allows dependency management in JS, most notably in browsers.
As to why you think your own code is better, think again:
it provides better latency on 3G network
It's because you think the modules are deployed "as is", as file-per-module basis. You are thinking of the "additional HTTP request per module" am I right?
Sure, they work when broken down into modules. But you don't actually deploy them that way. You use the optimier which minifies your modules, and combines related modules into a file. This results in:
- Smaller files due to minification
- Lesser files due to dependency combination
- Lesser files to download since your dependencies are grouped into related modules.
Also, the modules are cached once loaded. Once another modules requires a module that is already loaded by another module earlier in the execution of your code, it uses the cached one rather than requesting it again.
I don't like unnecessary function wrappers... for every module, every require call.
A require/define call is designed to:
- define the dependencies
- define the module
- the filename is the module name
It isn't that hard to code:
//MyModule.js
define([
'what',
'you',
'need'
],function(what,you,need){
//what you do
return whatYouWantExposedFromThisModule;
});
I am now able to use my script like php's include
.
Handling the modules
include
is like appending one file to the other, which is synonymous to concatenating files. In JS, we don't want globals. What if one module of yours had a bam
variable, but has bam
in another and you required the two. How would you handle that? Also, JS execution does not halt. How would you expect to do a require in your implementation? Synchronous XHR? preloading? That takes time! You'd be halting the execution for each require call of your implementation just to load a script.
<script>
require('alert');
//halt here to load alert?
//you'd block the UI, freeze the browser, lose the user
bam(); // 9
</script>
In the module definition in require, the code of the module lives in it's own scope. Nothing is spilled to the global scope. What is exposed by the module is only exposed to the function that requires it, which is also a closed scope. Also, modules are cached. Once a module is already loaded, future requires to that module are taken from the cache, not from the network. They are asynchronous, and does not block the UI thread and the requiring code only executes when the dependencies are loaded - nothing is halted while we wait for the dependencies to load.
Loading the modules
Suppose you will do AJAX with your eval approach - it's not cross-domain friendly, and cross-browser friendly (IE).
The concept of loading a module is based on script-loaders which can do cross-domain. It's similar to how JSONP works, but instead of an arbitrary callback, they are fed through define
.
I suggest you read more about how script loaders and dependency loaders work. This is a broad topic and has it's own spec.