1
votes

I'm developing a modular framework in javascript and am looking for a way to automatically optimize/combine a set of javascripts as a precompile step.

I'm already using grunt so a grunt-task would probably make sense.

The framework consists of modules in their own files (as in the rectangular 'widgets' we're all used to) that in turn may require other javascripts.

All this is wired using Require.js which works great. However, I came across the following constraint when trying to use r.js which comes with require.js

The optimizer will only combine modules that are specified in arrays of string literals that are passed to top-level require and define calls, or the require('name') string literal calls in a simplified CommonJS wrapping. So, it will not find modules that are loaded via a variable name:

The thing is: modules may inherit from eachother, and even composition of other modules is possible through configuration (with the technical need to load the referenced modules sitting in their own js-files).

This doesn't work with the mentioned constraint above. I'm sure I could cook up something myself with enough time, but perhaps someone has already done something like this. (r.js but more flexible).

A doable solution imho would be to:

  • let the precompile-task run the page for which the js needs to be optimized once (but on the server in Node instead of on the client, the framework is able to do this)
  • and somehow track all the libraries loaded in by require.js
  • read out require.js somehow and voila there's your list of js-scripts to load.
  • hand this to r.js through the include it provides and r.js handles it from there.
  • there are more pagetypes btw. But in r.js it seems possible to define common libraries, so they don't get included in the per-page-optimized file.

Does this sound plausible? Anyone ever tried something like this?

1

1 Answers

1
votes

This seems overly complicated. In r.js build there is option onBuildRead, where you can modify source so that it would be acceptable to optimizer. Also you may look into Internal API: onResourceLoad. Where you can capture all loaded dependencies and then make a call to do custom build.

To load your page you would have to use PhantomJS, so that it acts as a browser and executes JS. Then signal node to produce custom build for that page. But then need to switch resources on that page to use custom build. I guess you can make it configurable and do that when in production.

It does sound that it is possible, not sure if it is feasible.