[[development-modules]]
=== Modules and Autoloading

[float]
==== Autoloading

Because of the disconnect between JS modules and angular directives, filters,
and services it is difficult to know what you need to import. It is even more
difficult to know if you broke something by removing an import that looked
unused.

To prevent this from being an issue the ui module provides "autoloading"
modules. The sole purpose of these modules is to extend the environment with
certain components. Here is a breakdown of those modules:

- *`import 'ui/autoload/styles'`*
    Imports all styles at the root of `src/ui/public/styles`

- *`import 'ui/autoload/directives'`*
    Imports all directives in `src/ui/public/directives`

- *`import 'ui/autoload/filters'`*
    Imports all filters in `src/ui/public/filters`

- *`import 'ui/autoload/modules'`*
    Imports angular and several ui services and "components" which Kibana
    depends on without importing. The full list of imports is hard coded in the
    module. Hopefully this list will shrink over time as we properly map out
    the required modules and import them were they are actually necessary.

- *`import 'ui/autoload/all'`*
    Imports all of the above modules

[float]
==== Resolving Require Paths

Kibana uses Webpack to bundle Kibana's dependencies.

Here is how import/require statements are resolved to a file:

. Check the beginning of the module path  
  * if the path starts with a '.'
    ** append it the directory of the current file
    ** proceed to *3*
  * if the path starts with a '/'
    ** search for this exact path
    ** proceed to *3*
  * proceed to *2*
. Search for a named module
  * `moduleName` = dirname(require path)`
  * match if `moduleName` is or starts with one of these aliases
    ** replace the alias with the match and continue to ***3***
  * match when any of these conditions are met:
    ** `./webpackShims/${moduleName}` is a directory
    ** `./node_modules/${moduleName}` is a directory
  * if no match was found
    ** move to the parent directory
    ** start again at *2.iii* until reaching the root directory or a match is found
  * if a match was found
    ** replace the `moduleName` prefix from the require statement with the full path of the match and proceed to *3*
. Search for a file
  * the first of the following paths that resolves to a **file** is our match
    ** path + '.js'
    ** path + '.json'
    ** path + '.jsx'
    ** path + '.less'
    ** path
    ** path/${basename(path)} + '.js'
    ** path/${basename(path)} + '.json'
    ** path/${basename(path)} + '.jsx'
    ** path/${basename(path)} + '.less'
    ** path/${basename(path)}
    ** path/index + '.js'
    ** path/index + '.json'
    ** path/index + '.jsx'
    ** path/index + '.less'
    ** path/index
  * if none of the above paths matches then an error is thrown
