amd-config-builder
Builds AMD config for a project from configs of its components.
For a bigger project, where you load modules using AMD, you face the problem of building
a big require.config
call encompassing all dependencies and shims. Whenever you change something
about the structure of the project, this big structure inside the call needs to be changed.
As an example: you use CodeMirror, a non-AMD module, in your project. You naturally use jQuery,
the AMD project with hardcoded id (because CodeMirror needs it). Plus, you have some more modules
(like es5-shim) in your bower_components
, and you have some modules in your own app.
The premise of this project is to be able to specify pieces of AMD to-be-passed-into-require.config
object per component, that is, if the project has this structure:
. <root>
+-+ bower_components/
| +-+ jquery/
| | `-- jquery.js
| +-+ codemirror/
| | +-- codemirror.css
| | `-- codemirror.js
| `-+ require-css/
| `-- require-css.js
+-- lib/
| `-- ... some files
`-- distinct-part/
+-- vendor/
| +-- foo/
| | `-- ... files of foo vendor lib
| `-- ... some other vendor libs
`-- ... some more files
These files would be added:
{
"paths": {
"my-app": "lib"
}
}
{
"paths": {
"jquery": "jquery"
}
}
{
"paths": {
"css": "require-css"
}
}
{
"paths": {
"codemirror": "."
},
"shim": {
"codemirror/codemirror": [ "jquery", "css!codemirror/codemirror" ]
}
}
{
"paths": {
"my-distinct": "."
},
"shim": {
"my-distinct/vendor/foo": [ "codemirror/codemirror" ]
}
}
The local.amd.json
files describe the require.config
part for the module at the directory where they are present, in this example for the <root>
and <root>/distinct-part
. The idea is, each library can supply its own local.amd.json
, so the final config can be assembled. The paths
part of local.amd.json
is relative to the module it describes, that is, relative to its position.
The name.amd.json
files describe the missing pieces of config for other dependencies, which do not supply their own one (or they do, but something should be added/overridden). The name
is the name of the directory where the dependent library / module resides. Thus, jquery.amd.json
describes config part of <root>/bower_dependencies/jquery
, similarly for codemirror.amd.json
and require-css.amd.json
. Again, paths
part is relative to the module described, that is, for jquery.amd.json
, even if it is in <root>
, the pahts
part is resolved relative to <root>/bower_components/jquery
directory.
Q: "What if there are more directories with name name
?
A: "The one which is less deep in the hierarchy wins. If there are multiple at the same depth, the result is undefined (probably one of them is used; maybe some hinting as to which one should be preferred can be added in the future)."
The result should be to look for all .amd.json
files in the project and assemble all these files into one big require.config
call:
require.config({
paths: {
"my-app": "lib",
"my-distinct": "distinct-part",
"codemirror": "bower_components/codemirror",
"jquery": "bower_components/jquery/jquery",
"css": "bower_components/require-css/require-css"
},
shim: {
"my-distinct/vendor/foo": {"deps": ["codemirror/codemirror"]},
"codemirror/codemirror": {"deps": ["jquery", "css!codemirror/codemirror"]}
}
});
This, saved to a file, can be used as-is as a script to set up requirejs (or other loader),
and it can as well be used as mainConfigFile
for the requirejs optimizer.
API
require('amd-config-builder').produceConfigObject(rootDir, function(err, result))
This scans for the subtree of rootDir and calls the callback
with either the error or with (null, configObject). The configObject
is what you put into require.config
call.
All paths in configObject's paths section that were not absolute / uri,
are relative to rootDir