The never ending journey.
I’ve searched long and hard, trying to find the best solution. I’ve come across Require.js, browserify, grunt and many more, but these were the best solutions in the bunch. Here are some of my findings on these three.
Require.JS is different in that it’s mainly meant to do AMD loading. It allows you to do some cool things, and actually works quite well. The problems I have with require.js are as follows:
- It forces you to wrap your code in a function call.
- It forces another (quite large) dependency on you.
- It’s difficult to add non-AMD dependencies.
- When a non-AMD dependency requires the use of another non-AMD file, good luck.
- When you want to add unit tests you’ll have to work around require.js.
It’s good, but not good enough for me.
Browserify looks very appealing when you look at it for the first time. Using
- It’s a bit fragile and doesn’t always do what you’d expect.
- It makes generating code coverage a tad difficult (it doesn’t recognize the require calls).
- It forces a dependency on you.
It’s better than require.js, but still not good enough.
Grunt (concat, usemin)
GruntJS, the task-running bamf. It’s amazing in that grunt itself doesn’t manage your dependencies for you, the plugins do. So this is actually a comparison between two of the best plugins I’ve found.
Usemin allows you to add good old script tags to your html, and html comments to figure out where to put the combined file. This is pretty cool, but it’s only cool when using static html files as it rewrites your html for you. I was able to still implement this, have it write my views to a different directory and tell my app to use those views. This worked okay, but still felt a bit weird and dirty.
In comes useuses
Tired of looking through all these alternatives I decided it was time to write something myself. I called it
useuses because it allows you to use uses. Aren’t I creative?
What it is.
Before I started writing this plugin, I assembled a list of requirements:
* It must be optional.
* It mustn’t force a dependency upon someone.
* It must be “standard”, so no weird tags.
* It must add value to the files, even when not used.
With those requirements set, I came up with a way to specify what dependencies a file has, to make it informative for the developers. So as soon as you were to open up a file, you’d immediately see what it depends on. This made me think of the way jquery ui does that. It’s nice, but not nice enough. It’s still unformatted information.
I finally came up with the following syntax:
* My file
* Some info about My file
* @author RWOverdijk
* @version 0.1.0
* @license MIT
* @uses ./my-dependency.js
This is informative and standardized in the docblock format. I immediately added support some other formats:
* Relative to your current dir:
* @uses ./my-dependency.js
* Without .js extension (will load ./my-dependency.js):
* @uses ./my-dependency
* Package with an index.js (will load ./package/index.js):
* @uses ./package
* Paths relative to your project directory:
* @uses assets/scripts/common/filter/age.js
I liked all alternatives and think that the developers did a great job creating solutions. I think that whatever you decide to use depends on your project’s requirements and development style.
If you wish to give
useuses a go, you can find the npm package for useuses by clicking here.