Before this change, `app.booting` was set by Application plugin as part
of regular phase invocation, which executes individual plugins in
subsequent turns of the event loop. As a result, `app.booting` was
initially `undefined` despite the fact that the booting process was
already in progress.
This patch moves manipulation of `app.booting` flag directly to
`Bootstrapper#run` method, to ensure it's set early enough and always
properly cleared at the end.
- refactor logic of processing artifacts into their own classes
- introduce Container as the main class for bootstrapping and build a
registry of handlers during boot to organize them by a hierarchy
denoted by path
- adopt middleware like registration and invocation
- container.use(path, handler)
- container.run(context, done)
- allow more phases during boot
- boot is now asynchronous
Let environment variables override configuration set by config.json
and/or app.set()
Behavior changes
- datasources.json now support dynamic configuration through
env-vars and config.json
- component-config.json will first consider env-var
for resolving dynamic conf, then fallback to config.json
- middleware.json will first consider env-var for resolving
dynamic conf, then fallback to config.json
- for all the dynamic confg, unresolved conf will return as `undefined`
Example:
Consider the following server/datasources.json
```
{
"mysql" : {
"name" : "mysql_db",
"host" : "${MYSQL_DB_HOST}",
...
}
}
```
Now you can provide the parameter through
an environment variable:
```
$ MYSQL_DB_HOST=127.0.0.1 node .
```
or you can set the value in server/config.json
```
{
"MYSQL_DB_HOST": "127.0.0.1"
}
```
Fix executor to always emit the "booted" event and call the callback
in the next tick of the event loop, regardless of whether there are any
async boot scripts.
Before this change, adding a listener for "booted" event was cumbersome:
boot(app);
if (app.booting)
app.on('booted', handler);
else
handler();
With the fix in place, one can simply write the following:
boot(app);
app.on('booted', handler);
App variables can now be specified in component-config.json using
the ${var} format. The value of var is looked up using app.get().
This allows loopback explorer and other loopback components which
require app variables, to be loaded declaratively using
component-config.json.
App variables can now be specified in middleware.json using the ${var}
format. The value of var is looked up using app.get().
This allows loopback.rest and other loopback middleware which require
app variables, to be loaded declaratively using middleware.json.
When loading middleware configured in "middleware.json", loopback-boot
used to require() the full path to middleware's module main file,
for example "node_modules/strong-express-metrics/index.js".
This is breaking strong-agent probes, as it's difficult to detect
when the intercepted module (e.g. "strong-express-metrics") was loaded.
This commit modifies the compiler to omit the tail (the path to the
module main source file) when requiring middleware.
Because tryResolveAppPath returns undefined when it can’t resolve a
path the debug output for directories that cannot be resolved is fairly
useless.
You get output like this:
loopback👢compiler Skipping unknown module source dir undefined
+0ms
When you want output like this:
loopback👢compiler Skipping unknown module source dir "./models"
+0ms
Port can't be number checked to support iisnode. Using a parseInt()
or number isNumber function won't work if we want to support iisnode
which uses named pipes for ports (ex. \\.\pipe\mypipe)
Extend the options argument of boot/compile to allow the developer
to supply custom model definitions (to replace the result of
findModelDefinitions). Together with the existing options.models,
it allows to specify all model-related data and still use the benefits
which loopback-boot provides (most notably loading models in order
defined by inheritance, i.e. base models are loaded before models that
are extending them).