Anatomy
The structure of a Lore application
The structure of a Lore application
This file controls the behavior of the Lore CLI.
The Lore CLI is intended to be a complimentary tool for the application, and is designed in a way that allows it be extended from within a project. This means that you can add new commands to the CLI as well as overwrite existing commands, and all without leaving your project, or without needing to submit a PR to modify the CLI itself.
While the CLI originally started off as a simple convenience for generating basic project files, and was not expected to be useful much beyond the Quickstart, the inclusion of the extract
commands have dramatically changed that relationship and have made the CLI useful as a permanent tool.
Lore's development follows a process of identifying patterns for front-end development, which are then converted into blueprints that can be customized through a configuration object. Whenever possible, that configuration object is assigned sensible defaults, and conventions fill in the rest. This combination provides a sense of "magic" where certain parts of the framework "just work".
While this is useful, and can make for an enticing demonstration, it's not realistic to assume those conventions will work in all cases all the time. Sometimes, you just need to break out of them and take control of the reigns yourself.
The extract
commands are designed to make that process as painless as possible. When you invoke them, they will generate a version of the blueprint being used, and place it in your project, but stripped of any configuration or conventions the framework uses.
In fact, if you were to run the extractors for every action, reducer, form and dialog in your project, you'd basically have a vanilla Redux project. The only thing the framework would be doing is helping mount your project to the DOM, and manage the creation of your configuration object based on the environment.
By default, this file is the same for all projects, except for the language specified for the project (which controls what generated files will look like).
The file contains two keys; generators
and commands
.
The settings for generators
control what generated files will look like, such as when using the command lore generate component Header
.
The settings for commands
control what commands can be the command lore generate component Header
.
The default file included in new projects looks like this:
{
"generators": {
"language": "es5"
},
"commands": {}
}
{
"generators": {
"language": "es6"
},
"commands": {}
}
{
"generators": {
"language": "esnext"
},
"commands": {}
}
This file can also be used to override or extend the behavior of the CLI.
A .lorerc
file that completely replaces the current set of CLI commands looks like this:
{
"generators": {
"language": "es5"
},
"commands": {
"new": "lore-generate-new",
"extract": {
"description": "Create files that mirror the blueprint behavior",
"commands": {
"action": "lore-extract-action",
"reducer": "lore-extract-reducer"
}
},
"generate": {
"description": "Generate common project files",
"commands": {
"collection": "lore-generate-collection",
"component": "lore-generate-component",
"generator": "lore-generate-generator",
"model": "lore-generate-model",
"reducer": "lore-generate-reducer"
}
}
}
}
The commands
key is how you signal to the CLI that you have something you need to add to it.
If you want to add a command at the root, such as lore hello <arguments>
, you would add it by specifying a key called "hello" with a value pointing to the module location:
{
"generators": {
"language": "es5"
},
"commands": {
"hello": "./commands/folder-name"
}
}
The value can be a relative path like ./commands/folder-name
, an absolute path like /Users/jason/some-folder/command-folder
, or a node_module like module-name
. If you provide a node_module, the CLI will first look in the project's node_modules directory, and then look in the global node_modules directory before throwing an error if it can't find it in either location.
If you want to create a nested command, like lore hello world <arguments>
then you need to nest your command inside a category, like this:
{
"generators": {
"language": "es5"
},
"commands": {
"description": "Describe what commands in this category are for",
"hello": {
"world": "./commands/folder-name"
}
}
}
The category description is completely optional. It defaults to an empty string. If you specify a description for a category that exists by default, such as extract
or generate
it will override the default description.
The CLI has a command called lore generate generator <generator name>
that will create a folder pre-configured as a working plugin for the Lore CLI. You can use this as a starting point for creating your own commands.
If you need to debug the module loading sequence for commands, you can add a debugLoading
key in the options
object of the .lorerc
file.
{
"generators": {
"language": "es5"
},
"options": {
"debugLoading": true
}
}
When debugLoading
is true, it will print out the directory of the modules that are being loaded, which can be helpful to confirm the CLI has loaded your custom command:
Loading absolute module: /Users/jchansen/lore/packages/lore-cli/node_modules/lore-extract-action
Loading absolute module: /Users/jchansen/lore/packages/lore-cli/node_modules/lore-extract-reducer
Loading directory module: ../../packages/lore-extract-action
Loading project module: lore-generate-collection
Loading project module: lore-generate-component