3
votes

The case

I'm trying to get to the most convenient solution of setting up a big javascript project.

Requirements are:

  1. Modular javascript: just one object in the global namespace if necessary
  2. Compatible with bower components
  3. Compatible with grunt: building and deployment done by grunt (contrib-usemin or contrib-requirejs)

To my own suprise, this turns out to be a non trivial task. I'm running into the following issues when using AMD:

  1. Loading bower components cannot alwasy be done easily. Raphael for example cannot be loaded using AMD without modifying the source. Which is really not an option when using bower, since I only push the dependency list to git. Also: loading javascript libraries that do not support AMD, can be shimmed, but consist of more than one file (like jquery-ui) are problematic; I would need to hack that together.
  2. De requirejs optimizer builds everything into one file, not allowing the option to seperate libraries from site scripts. Something that seems a sane thing to do.

When I'm NOT using AMD I run into other issues:

  1. How do I control dependencies in a large project?

A possible solution

So I'm contemplating a solution that would:

  1. Keep it portable, don't force AMD on future users
  2. Prevent global namespace clutter
  3. Remain compatible with bower
  4. Allow usemin to build the whole lot in grunt

It would consist of a small script defining a require( <deps>, <factory> ) and a `define( , , ) function that implements basic module definition and injection. It would not implement any asynchronous loading or queuing of scripts with unmatched dependencies!

Furthermore I will define any module using the named module patter instead of using anonymous modules. Even though this will sacrifice a minimal amount of portability.

Now I can use either requirejs or that tiny dependency injector in combination with manual <script src=""></script> loading. When using the latter option I would still need to register the loaded non-amd libraries using something like this:

define( 'raphael', [], function() { return Raphael; })

What do you think? Am I doing something sane? Reinventing the wheel? Unnecessarily complex?

Update

I think I could use almond (https://github.com/jrburke/almond) to fullfill the abovementioned purpose.

1
How set are you on RequireJS? If you're not using asynchronous loading why not use Browserify? - CheapSteaks

1 Answers

0
votes

Loading bower components cannot alwasy be done easily. Raphael for example cannot be loaded using AMD without modifying the source

you could use the shim config from requirejs to make modules loaded that are usually not AMD loadable. (or is raphael a really special case?)

De requirejs optimizer builds everything into one file, not allowing the option to seperate libraries from site scripts. Something that seems a sane thing to do.

thats not true imho. read http://requirejs.org/docs/optimization.html#wholemultipage