Skip to content

Commit

Permalink
feat: provide documentation for the UI server (strimzi#30)
Browse files Browse the repository at this point in the history
- adds build details for the server
- adds sections in Architecture.md to describe the server's structure,
as well as the Mock admin server section
- adds first pass of configuration documentation (relating to the
server)
- updates version of webpack-dev-server to fix dependency vulnerability

Contributes to: strimzi#16
Contributes to: strimzi#13
Contributes to: strimzi#15

Signed-off-by: Matthew Chirgwin <[email protected]>

Co-authored-by: Matthew Chirgwin <[email protected]>
  • Loading branch information
matthew-chirgwin and Matthew Chirgwin authored Oct 7, 2020
1 parent 3baf656 commit 27ff433
Show file tree
Hide file tree
Showing 9 changed files with 243 additions and 53 deletions.
8 changes: 8 additions & 0 deletions config/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Config

This directory contains all configuration for both the client and server of the Strimzi-ui ([described here](../docs/Architecture.md#configuration-and-feature-flagging)).

- `runtime.js` - will contain all configuration options which require resolution at server runtime to return a value
- `static.js` - will contain all configuration options where values can be defined literally
- `featureflags.js` - will contain all feature flags. These could be defined literally, or require a callback to resolve (like `runtime.js` configuration values)
- `index.js` - acts as a barrel file for all types, merging them together
143 changes: 124 additions & 19 deletions docs/Architecture.md

Large diffs are not rendered by default.

61 changes: 38 additions & 23 deletions docs/Build.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# Build

This documentation will cover both the [building of the UI code](#ui-build), and also how it is [built and integrated with Strimzi](#ui-build-into-strimzi).
This documentation will cover both the [building of the UI client and server code](#ui-client-and-server-build), and also how the output of these builds is [built and integrated with Strimzi](#ui-build-into-strimzi).

## UI build
## UI client and server build

This UI is built using two tools, [Babel](https://babeljs.io/) and [Webpack](https://webpack.js.org/). Webpack acts as our main build and bundling tool, while Babel acts as a transpiler - meaning the UI codebase can make use of the latest and greatest ECMAscript syntax, and Babel will polyfill where appropriate to provide cross browser support. The below will detail choices we have made regarding how the build works, configuration and considerations to be aware of, and the end output. The aim of this stack is to have a fast and efficient build for day to day development, but also the smallest possible built bundles so users do not need to wait a long time for all required assets to be retrieved by their browser.
This UI codebase (client and server) is built using two tools, [Babel](https://babeljs.io/) and [Webpack](https://webpack.js.org/). Webpack acts as our main build and bundling tool, while Babel acts as a transpiler - meaning the UI codebase can make use of the latest and greatest ECMAscript syntax, and Babel will polyfill where appropriate to provide cross browser support. The below will detail choices we have made regarding how the build works, configuration and considerations to be aware of, and the end output. The aim of this stack is to have a fast and efficient build for day to day development, but also the smallest possible built bundles so users do not need to wait a long time for all required assets to be retrieved by their browser.

### Treeshaking

Expand Down Expand Up @@ -80,7 +80,8 @@ In addition to aliasing, the webpack configuration will be as follows:
| ------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
| entry | `client/Bootstrap/index.js` | Build entry point. _Note:_ the `scss/css` is expected to be imported by individual view layer code, which is imported (directly or indirectly) from this file. Details to follow in Code Style approach documentation regarding this styling approach and why. |
| mode | `production` or `development` (provided via config file used) | Build mode. If production, code will be minified and have developer helpers (warnings etc) removed from the built output |
| output.path | `dist` (via constant) | All output to be placed in the `dist` directory |
| target | `web` or `node` (provided via config file used) | The build target. The client side code will be built for `web`, and server `node`, reflecting where the code runs (and thus what Webpack will/will not include in it's output). |
| output.path | `dist/client` or `dist/server` (via constant) | All output to be placed in the `dist` directory, with client code going into the `client` directory, and all server code into `server` respectively. |
| output.publicPath | `` (empty string) | The public path of static/public content included by Webpack. Is relative to the URL. |
| output.filename | `[name].bundle.js` | Name of the built entry bundle. Will be `main.bundle.js` once built as we have one entry point |
| module.rules | Array of rules - [see here for details](#module-rules) | Rules/tests to run on modules being built. Depending on the file being parsed, different transformations should be run |
Expand Down Expand Up @@ -120,6 +121,7 @@ We also make use of the following plugins:
| compression-webpack-plugin | Compresses built output further using `gzip` algorithm, and emits these compressed files. Depending on headers provided by the browser, these gziped versions will be served to the browser, rather than the uncompressed versions |
| webpack-bundle-analyzer | At build time, produce a report regarding the JS bundle size (useful for understanding bloat and duplication). At dev build time this is an html file (which is then hosted by `webpack-dev-server`), and a json file at production build time. Each report is written to the `generated/bundle-analyser` directory |
| BannerPlugin | Used to add a copyright header to built css code. Other types handled by other plugins (eg TerserPlugin) |
| webpack-node-externals | Excludes any code from `node_modules`. Useful when building node.js bundles, due to OS/dynamic requirements of those modules. Expectation is these will be installed/provided at build time via an `npm install` alongside the built output. |

Where appropriate, plugins will be provided via helper functions from a common configuration file, but allow for modification to their configuration. [See this section for more details](#ui-build-implementation).

Expand All @@ -141,25 +143,30 @@ Given the above configuration, built output will be created in a `dist` director

```
dist/
index.html
favicon.ico
main.bundle.js
<hash1>.bundle.js
<hash2>.bundle.js
....
main.bundle.js.gz
<hash1>.bundle.js.gz
<hash2>.bundle.js.gz
....
main.css
<hash1>.bundle.css
<hash2>.bundle.css
...
images/
image1.svg
client/
index.html
favicon.ico
main.bundle.js
<hash1>.bundle.js
<hash2>.bundle.js
....
main.bundle.js.gz
<hash1>.bundle.js.gz
<hash2>.bundle.js.gz
....
main.css
<hash1>.bundle.css
<hash2>.bundle.css
...
fonts/
font1.ttf
images/
image1.svg
...
fonts/
font1.ttf
...
...
server/
main.bundle.js
...
```

Expand Down Expand Up @@ -188,4 +195,12 @@ The above UI build is implemented in the [`build directory`](../utils/build). It

## UI build into Strimzi

This will be completed once https://github.com/strimzi/proposals/pull/6 has been finalized.
The UI build is used in a `dockerfile` to produce an image that can then be deployed as a part of Strimzi. This `dockerfile` performs the following steps:

- Install all dependencies
- Run `npm run build`, which in turn runs a production build of the client and server
- Clear installed dependencies, and install just production (shipped) dependencies
- Move the built UI directory `dist` and `node_modules` to the required location
- Sets the entrypoint to a script/command which runs the UI Server: `node dist/server/main.bundle.js`

Further details to be added once https://github.com/strimzi/proposals/pull/6 has been finalized.
22 changes: 12 additions & 10 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 6 additions & 1 deletion server/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
# Server

Content to follow
This directory contains all server code for the Strimzi UI - ie code which is responsible for the serving of and back channel logic to support the client code. A summary of contents can be found below:

- [`core`](./core/README.md) - the core express server logic. This document also covers how the core module interacts with the other modules
- [`client`](./client/README.md) - handlers for returning built client code to a user's web browser
- [`mockapi`](./mockapi/README.md) - handlers for emulating a real instance of `Strimzi-admin` in dev and test scenarios
- `main.js` - the build entry point for the production UI server. It checks for one argument, being the path to the configuration for the server which it then watches for modification, and owns the creation and management of a node `http`/`https` server (and binding express to it).
5 changes: 5 additions & 0 deletions server/client/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# client

This module is responsible for serving the built client code, and does so on the `/` context root. All built client files are considered 'public', ie can be accessed without an authentication check, except a set defined subset representing the bundles which will only be retrieved once a user has authenticated and/or the backend server can support the page(s) those bundles represent. It also includes a behaviour if a request is not matched/served, it will redirect to `/index.html`.

_Note_: Implementation to follow in a future PR
40 changes: 40 additions & 0 deletions server/core/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# core

This module represents the core Express server. It also imports, configures and provides common items and capabilities to all modules, such as an authentication check middleware and logging utilities, as well as common middleware and security features.

## Public api

The core `app.js` file (in place of `router.js`) exports one function, `returnExpress`. This function takes one parameter, being a callback to get the current configuration. This is expected to be used in `main.js` to bind the returned express app to an http(s) server.

## Interaction with other modules

The core module will import and interact with all other modules to implement the server at run time. Thus, there are two

### Import time

The core module will import all modules' default export. This is expected to be a function, which takes two parameters:

```
const [mountPoint, routerToMount] = myModule(authMiddleware, router);
```

Where:

- `authMiddleware` is an express middleware function to be inserted/used when a module's routes require a user to be authenticated to access them
- `router` is an express [Router](https://expressjs.com/en/4x/api.html#router), which this module will append handlers to. This is provided so a common, pre module handler piece of express middleware can run [as described at runtime](#run-time) to provide context to the module

This function is to return an array containing two items. The first is the context route this module will be mounted on (eg `/dev`). The second is the modified router, with handlers appended to it.

This will then be mounted to the express server, ready to serve requests at runtime.

### Run time

At runtime, before any module handlers are called, a piece of express middleware defined by the core module will run. The result of this middleware is as follows:

- Create a context object in `res.locals` called `strimziuicontext`. This context will contain:
- The current configuration for the server
- A unique request ID
- A pre configured set of loggers to use
- Perform a check when receiving the request to see if the module is enabled, and thus should respond. If it is not enabled, a HTTP 404 RC will be returned, and the module's handlers will not be invoked

_Note_: Implementation to follow in a future PR
5 changes: 5 additions & 0 deletions server/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/*
* Copyright Strimzi authors.
* License: Apache License 2.0 (see the file LICENSE or http://apache.org/licenses/LICENSE-2.0.html).
*/
// placeholder - this will be used as the entry point for the UI production server
5 changes: 5 additions & 0 deletions server/mockapi/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# mockapi

This module is used at development and test time to emulate a real instance of `Strimzi-admin`. It will return mock data as if a real instance of `Strimzi-admin` had responded, and also offer additional mutations to trigger responses needed in particular scenarios (eg user not authorised to perform an action etc).

_Note_: Implementation to follow in a future PR

0 comments on commit 27ff433

Please sign in to comment.