I'm having trouble understanding the benefit of require.js. Can you help me out? I imagine other developers have a similar interest.
From Require.js - Why AMD:
The AMD format comes from wanting a module format that was better than today's "write a bunch of script tags with implicit dependencies that you have to manually order"
I don't quite understand why this methodology is so bad. The difficult part is that you have to manually order dependencies. But the benefit is that you don't have an additional layer of abstraction.
Here's my current JS development work flow.
When in development-mode, all scripts have their own tag in the DOM.
<script src="depA1/dep1-for-module-A.js"></script>
<script src="dep2-for-module-A.js"></script>
<script src="moduleA/moduleA.js"></script>
<script src="dep1-for-module-B.js"></script>
<script src="module-B.js"></script>
<script src="moduleC/module-C.js"></script>
<script src="script.js"></script>
There is no abstraction layer. This allows me to better debug individual files. The browser reads separate files, so I can debug with Developer Tools. I like how it's straight-forward.
Dependencies are basically managed right here. depA1
needs to be listed before moduleA
. It's explicit.
Modules are 'transported' by attaching to the global namespace.
( function( global ) {
var dep1 = global.depA1;
var dep2 = global.depA2;
function ModuleA() {
// ...
}
// export
global.ModuleA = ModuleA;
})( this );
All scripts are concatenated and minified. One HTTP request on load.
<script src="site-scripts.js"></script>
The Concat + minify task is maintained separately. It's part of a build process. Makefile
or what-have-you. For dependency management, the ordering of scripts matches how they were listed in the HTML.
This can be done easily with some sort of configuration and templating. For example, by setting prod_env
config variable to true
or false
, the site is either in production, serving the one file, or development mode, serving every single file.
{% if prod_env %}
<script src="site-scripts.js"></script>
{% else %}
<script src="dep1/dep1-for-module-A.js"></script>
<script src="dep2-for-module-A.js"></script>
<script src="moduleA/moduleA.js"></script>
...
{% endif %}
- What benefit does require.js provide over this workflow?
- How does require.js address minimizing HTTP requests? Is this any better than concat/minifing all the scripts?
Most medium-sized web apps (which is what most of us are building, right?!) do not need the syntactic vomit that RequireJS sprays all over the project. It is not hard to get even several dozen <script> tags in the right order. It. Is. Not. But it is at least as difficult to maintain RequireJS config files and the require() and define() statements. I have seen devs spending hours pairing to figure out their RequireJS config files.
Furthermore, many web apps will simply not benefit from lazy loading, because they will require loading almost everything at a certain choke point -- such as immediately after user login. If you can determine a clear choke point like this, it should be straight forward to configure the script bundling accordingly. Or maybe all of your custom scripts minify to 50K -- in which case you are insane to try to optimize performance by breaking that apart. Now, of course there will be apps where lazy loading will be beneficial. But I think they will be a small minority, based on the medium-sized business apps I have worked on.
Bottom line is that good devs will actually figure out whether or not it makes sense to use RequireJS on a project -- because it is not free. It complicates your ECMAScript5 code, despite what the sycophants say. People who spout that RequireJS should be used as a rule are either sheeple or self-congratulating hipster "experts."