- Webbase v4
The webbase-v4 framework is designed for developing web applications using express.js. It's versatile, allowing for the creation of both web apps and standard node.js applications.
- Modular Design: Tailor the framework to your needs. Disable unneeded features for a leaner application.
- Example: If you don't require Core_Db, disable it to avoid module-resolving-errors. Remember, disabling Core.Db necessitates disabling Core.Usermgmt as well.
- Efficiency: Thanks to webpack configuration, the application minimizes filesize by excluding unnecessary components.
As this application is ever-growing, it's probably time to start categorizing certain functionality by stricter rules. Currently, the code is split up into three (keep in mind that no custom extensions are shipped!) distinct categories:
- Runtime
- Core-Extension
- Custom-Extension
The runtime covers all functionality needed to build up and execute the several application types. To be exact, there are four categories that are to be included here:
- Extensions
- Configurations
- Threading
- other startup related systems
Code inside of this category must not be directly dependent on any Core-/ or Custom-Extensions at all. The strict main goal is always to be able to rip the whole extensions folder out, and the application should still be able to run, to the end, since no code is run after startup by default, without problems!
Everything that does not cover those three logical categories above but are still maintained and shipped on the main repository does count as a Core-Extension. Core-Extensions are allowed to be dependent on oneanother, but must never be dependent on any Custom-Extensions.
Custom-Extensions add functionalities to the web-app that are not covered by any of the other two categories. They only exist outside of the main repository.
The core modules form the foundation of the webbase-v4 framework, offering essential functionalities required for web application development. By default, all core modules are activated, providing a comprehensive suite of tools right from the start. These modules can be individually disabled to streamline the application, according to specific needs (for guidance, refer to ExtensionService).
| Module | Description |
|---|---|
| Core | The primary module, encompassing basic framework utilities and configurations. |
| Core.Web | Facilitates the creation and management of web services, including HTTP server configurations. |
| Core.Db | Provides database integration and management functionalities, supporting various DBMS. |
| Core.Usermgmt | Manages user accounts, authentication, and authorization processes. |
| Core.Usermgmt.Web | Extends Core.Usermgmt with web interfaces for user management. |
| Core.Mail | Enables email sending capabilities, supporting template-based email generation. |
| Core.Cache | Implements caching mechanisms to enhance application performance and reduce load times. |
| Core.Databridge | Facilitates data exchange between different parts of the application or with external services. |
| Core.Loki | Provides the capability to exchange logs with a Grafana Loki-Server |
| Core.Interfaces | Defines commonly used interfaces (and basic implementations) at a single point to prevent duplicate code across multiple extensions |
| Core.Dashboard | Offers a dashboard module for monitoring and managing application states. |
| Core.ReactComponents | Provides a set of React components for building user interfaces. |
Developing extensions allows you to expand the capabilities of the webbase-v4 framework. Extensions can add new features, integrate with external services, or modify existing functionality. The process involves the ExtensionService, which manages the loading and execution of extensions.
When you load an extension, the ExtensionService dynamically incorporates it into the application by providing an execution context. This context includes essential information and services the extension might need.
To start developing extensions you can use following command:
# node src/install.js --extinit='[extension name]'
# Example:
node src/install.js --extinit='Core.Db'This will create a new extension from the template extension project.
To get your application running, there are a few steps you need to follow. This process involves building your application from the source code and then starting it on your server or development environment.
We are using Webpack to build the app sources and esbuild to build the web sources.
Our goal is to eventually build everything using esbuild.
To build the application, you must:
- Clone the repository
- Install the dependencies
- Build the app-/ and the web-sources
- Execute the build-result
Using the terminal, this would look like this:
# Cloning the repository
git clone https://github.com/CreepSore/webbase-v4
cd webbase-v4
# Installing the dependencies
npm install
# Building both app and web sources
npm run build
# or
# npm run dbuild
# for a development build
node out/src/app.jsFor a quicker start you can also use one of these commands:
# Builds and starts the app in production mode
npm run start
# Builds and starts the app in development mode
npm run dstartTo make things easier we also provide a live-reload for all web-sources.
Watch out: The live-reload is only active when building and running in development mode!
# This starts the esbuild watcher for web-files
npm run watchWebAfter starting the application for the first time the template configuration files will be exported by default to ./cfg/template.
You can simply copy them into their parent directory and adapt the configuration to your needs.
Normally the Core-Extensions do NOT throw an error if no config exists. This ensures a clean first start.
If you already have config files somewhere on your system, you can use enviroment variables to specify the base path (see Enviornment Variables).
The LoggerService implements a small logging-framework that can be used to log to console, files and internal arrays. The Core Module loads following Loggers per default (doing so by replacing console.log):
| Name | Description |
|---|---|
| ConsoleLogger | Logs to the stdout |
| FileLogger | Logs to logs/*.txt files |
| CacheLogger | Logs to an internal array that can be accessed by modules |
The "new" usage of console.log is as follows:
console.log(LOGLEVEL, ...INFOS, MESSAGE)
Where LOGLEVEL, INFOS and MESSAGE are all strings. All "INFOS"-Entries are inserted into square brackets before printing.
Example:
console.log("INFO", "Core", "Loggers initialized successfully")
logs
[2022-10-21T15:05:55.785Z][ INFO][Core] Loggers initialized successfully
using all registered loggers.
There is also a High-Level Logging API available. Using it looks like this:
LogBuilder
.start()
.level(LogBuilder.LogLevel.INFO)
.info("Core")
.line("Loggers initialized successfully")
.done();Using this instead of console.log is preferrable, since it is able to do much more.
See LogBuilder.ts for more information.
| Name | Description | Example |
|---|---|---|
| CFG_PATH | Absolute path to the config files | /mnt/config |
| CFG_TEMPLATE_PATH | Absolute path where the template config files should be generated at | /mnt/config/template |
To override specific configuration values using the environment variables you have to enable overriding by setting the ENABLE_CONFIG_OVERRIDE variable to true.
Afterwards you can override configurations which use the ConfigLoader.environmentOverride function.
CoreDb is one of the extensions that uses this.
To override the db-uri you can use the env-var CoreDb_connection_uri.
Explanation of the parts:
- CoreDb
- The
baseKeyparameter that's passed toConfigLoader.environmentOverride
- The
- connection
- the path to the final object referencing the uri value
- uri
- the final target that will be overridden
Take this configuration that uses the baseKey ExAmPlE while calling ConfigLoader.environmentOverride:
{
"hello": {
"world": {
"my": {
"name": {
"is": "<PLACEHOLDER>"
}
}
}
}
}To override the placeholder with another value you can use the env-var ExAmPlE_hello_world_my_name_is.
Currently it is not possible to override configuration entries which do not use the environmentOverride function.
This may be subject to change in the future by making the baseKey the config-file-name.
You can also use .env files to specify your environment variables. They are ignored inside .gitignore by default.
There are three folders you can put your .env files in:
| Relative Path | Iterated recursively |
|---|---|
| . | No |
| .env | Yes |
| env | Yes |
Example:
# Classic
HELLO=World
# Double-Quotes also work
IAlsoSupport="DoubleQuotes"
# And Single quotes
Also='SingleQuotes'
# Backticks also
And=`Backticks`
# Quote nesting is also possible
NestingAlsoWorks=`"Hello'" World'` # This will result in ["Hello'" World']
# You can also specify newlines and carriage-returns when using backticks:
This=`HasA\nNewline\r\n`