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?
A few years have passed since this was started, so there are far more options now. However I wanted to share how RequireJS is still an excellent tool for medium'ish (maybe large to some people) sized projects.
We use RequireJS on a daily basis in an e-comm project (similar to ATG) and I love it. Was the initial config a little tricky? Yes but after that it's been excellent. That tricky part is in reference to our need to create a modified version of the multi-page with shim support pattern to make it fit our needs - the original pattern didn't work due to our existing codebase/file structure. For an idea of the project complexity front and back: the project has north of 600 JS files (there are the usual inline scripts as well that aren't counted) and north of 3,000 class files (src).
Using RequireJS in the way we've implemented it has allowed us to progressively modularize the application, which was only realistic option. To say it's flexible would be an accurate statement as it's currently supporting 2 modes of operation in production - dist and src (which we can toggle for debugging). We run r.js using clojure compiler and node uglify2, since both were necessary to allow teams without node to compile the project (they just need to wait a minute or 2 😄 ). We're also in the early stages of a service based approach for our client-side assets that are tied to RequireJS i.e. imagine a 3rd party that specializes in writing the front-end code for your site and delivering it via Akamai/Verizon/some CDN. Network throttling tests over the HTTP and HTTPS schemes has gone smoothly (scaled back to dial up speeds) and we've added transpiling into the mix so we can stay current (maps provided via Babel 6).
In summary, RequireJS is the exit point for most of the platform JS in a hybrid (2-3 mincat'd scripts in dist) and modular (src) distribution, and it's doing what it was designed to do flawlessly.