[feature] Improved submodule support

Let's use this thread to host issues related to upgrading submodule support. We should start by listing the functionality we'd like to see. I'll start:

  • Dual purpose - Submodules run both as submodules and as first class applications. Mostly they run as apps for testing, but they must be able to run in either mode. When running in application mode, all configurations at the top level of their config object are used. When running in submodule mode, only the top level config branch matching the module name is used.

  • Submodule config as default - When loaded as a submodule, a full config object should be loaded from files in the /config directory of the submodule. Once loaded, the top level branch of that config object named by the module name is folded as defaults into the same top branch of the main app config.

  • Late loading - A healthy modular system doesn't require the main app to have direct knowledge of all modules in the dependency graph. The main app knows only of dependencies listed in package.json. It should not be forced to change as the dependency graph changes over time. In addition to this lack of knowledge, the main app doesn't control the timing of submodule loading. Submodule configs must be able to be loaded as the runtime discovers the need to load the module.

  • Backward compatibility - I'm listing this as a highly desired but optional feature. This feature may force us to hide the config object, requiring all access through get() in order to guarantee immutability.