elasticsearch/kibana — pull request #484 by spenceralger (2013-09-12 02:01:08+00:00)
Title: Flexible dep management

Reorganized the repo, creating a src and dist directory as well as defining the build process using Grunt.

### Structure
```
dist/
src/
app/ # Kibana specific code
components/ # Generic utilities/classes written outside of Angular
controllers/
all.js # Index/single point of entry for the controller
dash.js
row.js
directives/
# same structure as controllers
filters/
# same structure as controllers
services/
# same structure as controllers
panels/
# Each panel must have a module.html, and module.js only if they have a
# controller. All files specific to a single panel should be in its dir
query/
bettermap/
etc..
partials/
# The shared templates for the application
dashboards/
vendor/
# Code from 3rd party vendors
jquery/
jquery-1.8.0.js
bootstrap/
require/
etc..
css/
font/
img/
index.html
```

### RequireJS
$LABjs has been replaced with RequireJS as it provides plug-ins for css, text, and maps file paths to simple names so we can declare deps as `require(['jquery', 'angular'])` and at the same times have deps which depend on others. The project now uses the r.js optimizer as well to concatenate files and remove the files that are no longer needed.

#### Notes
- In general, each "piece" of the application is defined in it's own file, unless it's so small that it wouldn't make the code any more readable (like filters).
- Each module RequireJS uses should be addressable with it's own URL.
- The general dependencies for the app are mapped to simple names like `"vendor/jquery/jquery-1.8.0.js" -> "jquery"`. This allows us to simply switch out the source for a module in the future, and makes things a lot more readable.
- Using the css and text plug-ins in the module definition inlines that file in the module
- I created a tmpl plug-in that used the text plug-in to cache a template string, and then pushed it into Angular's `$templateCache`. When in use, the app failed to boot even though the templates were loading properly. (seemed like the initial refresh event never got called). Couldn't figure out how to make it work so it's just sitting in `vendor/require/tmpl.js`.
- To require a file within a module use `$scope.require` which. See the bettermap module for an example.
- If an Angular module was created after the app was bootstrapped, it must be passed to app.useModule before anything is defined inside it (controllers, directives, etc).

### kibanaPanel directive
In order to ensure that a panel's module is loaded before its template, the kibanaPabel directive was modified to do the heavy lifting (I first created a loadKibanaPanel directive, but it seemed strange to have both). The directive will first use RequireJS to load the panel's module.html, if it finds a controller within the template, it will them load module.js. Once both are loaded, the module is inserted into the DOM and compiled.

### Build Process
Thanks to how awesome grunt and its plug-ins are, this was probably the simplest part of this whole process.

The steps carried out by the build process are as follows:

1. Copy & minify all of the .html files from src to a temp directory
- Note that the HTML minifier breaks Angular expessions within HTML attributes wrapped in single quotes but contain double-quotes. We should always use double-quotes for HTML attributes and " for double-quotes inside attributes.
- works: ``
- doesn't work: ``
* Compile the bootstrap .less from src to temp
* Copy & minify all of the .css files from src to temp
* Copy all of the remaining files that we want in the dist (.js, .json, images)
* Run the RequireJS optimizer on the temp directory, writing the now minified css, html, and js inline, and removing the js files that are no longer needed.
- This process will create a module for app (based on app.js) that includes all of the shared dependencies (a merged list, based on the deps declared in the file and the ones defined in the Gruntfile)
- Modules are also created for each panel by reading the folders in the panels directory. Those modules exclude any file already included in the app module, and include any other dependencies that require can find for them.
* Delete the temp directory

*__this is my first time setting-up up a build process, critisism appreciated__*

### Up to date
I have manually applied changes made since I forked the repo, since filenames don't map properly. I've stashed some patch files in the project root to keep track of what I've merged, but obviously those don't need to be merged.