5

I'm trying to understand the benefits of the popular r.js.

It seems to...

  • concatenate a list of manually selected JavaScript files
  • uglify/minimize that combined code
  • do some similar stuff for CSS files (combine them)

Also, (what it makes it different from generic combine/minify tools) it seems to...

  • convert Node-style require() modules to AMD style modules
  • name anonymous modules (eg. define(['dependency'], function(){...})
  • offer some support for loader plugins, e.g. inline CSS files

It does not seem to...

  • analyze and automatically resolve dependencies found in files (like, include file foo.js into the package just because r.js finds a define(["foo"], ...)

Is this correct, or did I miss something?

nhaa123
  • 9,570
  • 11
  • 42
  • 63
Udo G
  • 12,572
  • 13
  • 56
  • 89
  • Uh, was my edit incorrect and you really meant that it should "*include file `foo.js` into the package just because r.js finds a **`define(["foo"], ...)`***"? If the code is already there (`foo` is defined), I don't see why you would want it to load the `foo.js` file. – Bergi Oct 06 '14 at 20:15
  • [RequireJS/Optimization](http://requirejs.org/docs/optimization.html): "[r.js] Combines related scripts together into build layers and minifies them". The dependency graph itself is *still resolved at run-time*, all the modules have simply been shoved together and so do not require separate resource fetches. – user2864740 Oct 06 '14 at 20:16
  • @Bergi: Don't know about your edit, but yes, I want to make sure that it's correct that r.js does not automatically resolve any dependencies. I'm not saying it *should* do so. It just appears to me that r.js does some heavy JavaScript parsing/processing and want to make sure I understand all steps in that process. – Udo G Oct 06 '14 at 20:22
  • 1
    @user2864740: so, for modules that are already AMD-style, r.js does not do any special processing that can't be done by a classic combiner/minifier? (no criticism intended) – Udo G Oct 06 '14 at 20:24
  • 1
    @UdoG I mean: Normal module-per-file dependencies will be included, pretty much unless excluded, but the object graphs/load-order won't be. – user2864740 Oct 07 '14 at 04:18
  • @UdoG how would u handle any non amd dependencies though without r.js? – Dannyboy Nov 04 '15 at 13:34

1 Answers1

7

You are wrong, because r.js does automatically resolve dependencies. If you have a main.js file with this:

define(["foo"], function (foo) {
});

Then if you ask r.js to create produce an optimized module out of main.js, it will include the code for module foo into the build.

Some caveats:

  1. It is possible to tell r.js to exclude modules. So if a module you think should be in an optimized bundle is absent, it may be that it has been excluded. (You know how you are using r.js but if you use a bundle produced by someone else and you wonder, then this may be the answer: they specifically excluded a dependency from the build.)

  2. r.js does not find nested dependencies unless you tell it to. For instance:

    define(function () {
        require(["foo"], function (foo) {
        });
    });
    

    r.js won't find that foo is required unless you set findNestedDepencencies to true in your build config.

  3. r.js can find only dependencies that are specified in the form of a list of string placed as a literal in the location where the require and define calls expect dependencies. So if you do:

    define(function () {
        var deps = ["foo"];
        require(deps, function (foo) {
        });
    });
    

    Then r.js won't know that foo is a dependency, because in require(deps, ... your dependencies appear as a symbol reference, not as a list of strings. You would have to specify foo as a dependency manually in the build configuration. There's no flag to turn on to make r.js find these cases.

Louis
  • 146,715
  • 28
  • 274
  • 320