Search code examples
javascriptoptimizationrequirejsdependenciesr.js

If I optimize my RequireJS project using r.js, do I have to change the path and dependency configuration?


I'm new to RequireJS. I understand it for the most part. However, the r.js optimization process confuses me. Two questions:

  1. Doesn't concatenating all source into a single file defeat the purpose of RequireJS's lazy-loading abilities?

  2. If I do optimize using r.js and have everything in a single file, do I then have to manually update the path info in the config to point to that single file? And do the dependencies I've defined as individual modules have to now be changed throughout the entire application to point to this single file? Here's just a pretend source to illustrate how I'm currently setup:


requirejs.config({
    paths : {
        mod1 : 'app/common/module1',
        mod2 : 'app/common/module2',
        mod3 : 'app/common/module3',
    },
});

-- MOD 1
define(["mod2", "mod3"], function(mod2, mod3) {
// do something
}

Does that now have to be manually updated after optimization to look like this?

requirejs.config({
    paths : {
        optimizedMod : 'build-dir/optimizedModule',
    },
});

-- MOD 1
define(["optimizedMod"], function(optimizedMod) {
// do something
}

Solution

  • Re. 1. No, it doesn't. r.js analyzes your dependency tree and (by default) only includes modules you'd need to load on application startup anyway. The dependencies that are required dynamically won't be included, they'll be lazy-loaded at runtime (unless you set findNestedDependencies to true).

    However, lazy-loading is arguably not the main benefit of using RequireJS, a bigger thing is modularisation itself. Being forced to manage dependencies makes it harder to write code that's not testable or refactorable - bad architecture can be immediatelly spotted (lengthy dependencies lists, "god" modules, etc.)

    Re. 2. This is precisely the reason why you shouldn't be naming your own modules or mapping them in the paths configuration element. paths should be used for third party libraries and not your own code, centralising name->path mappings reduces flexibility. Once you refer to dependencies via their paths (relative to baseUrl) r.js can rewrite them at build time:

    define(["app/common/module2", "app/common/module3"], function(mod2, mod3) {
      // do something
    }