RedHat Cloud Services frontend components - webpack config
Webpack 5
In order to use the new version of webpack and its federated medules you'll have to change your run script to use new webpack serve
.
> webpack-dev-server -> webpack serve
You'll also have to update your webpack-cli
dependency to >=4.2.0
, this package has peerDependency
on it so you should see warning in your console.
Removed features with webpack 5
The new version of webpack 5 changed polyfills and plugin configs, some packages are outdated, one example is lodash-webpack-plugin
this plugin is no longer maintain anyways. You should be just fine by installing lodash
directly, imports can stay the same as before import get from 'lodash/get'
.
useProxy
Drop-in replacement for insights-proxy. Just add useProxy: true
to your configuration.
const { config: webpackConfig, plugins } = config({
...
useProxy: true,
});
Attributes
Attribute | Type | Description |
---|
useProxy | boolean | Enables webpack proxy. |
proxyURL | string | URL to proxy Akamai environment requests to. |
localChrome | string | Path to your local chrome build folder. |
keycloakUri | string | Uri to inject into proxied chrome assets. |
registry | (({ app, server, compiler, standaloneConfig }) => void)[] | Express middleware to register. |
routes | object | An object with additional routes. |
routesPath | string | A path to an object with additional routes. |
customProxy | object[] | An array of custom provided proxy configurations. |
env | string | Environment to proxy against such as stage-stable. |
useCloud | boolean | Toggle to use old fallback to cloud.redhat.com paths instead of console.redhat.com. |
target | string | Override env and useCloud to use a custom URI. |
useAgent | boolean = true | Enforce using the agent to proxy requests via proxyUrl . |
bounceProd | boolean = false | Bounce all non-GET requests via server requests. |
localChrome
You can also easily run you application with a local build of Chrome by adding localChrome: <absolute_path_to_chrome_build_folder>
.
rootFolder: resolve(__dirname, '../'),
debug: true,
useFileHash: false,
useProxy: true,
localChrome: process.env.INSIGHTS_CHROME,
});
INSIGHTS_CHROME=/Users/rvsiansk/insights-project/insights-chrome/build/
The path must end with a slash character / !!
To check what the proxy is doing with your local chrome settings you can set proxyVerbose: true
.
keycloakUri
You can change which SSO URI insights-chrome uses. Useful when proxying to ephemeral environments. This will be overriden if using standalone
by standalone: { chrome: { keycloakUri } }
.
Registry
You can extend express middleware before Webpack or standalone does by passing an array of callbacks. This can be useful to override specific test files independent of standalone
config.
const express = require('express');
registry: [
({ app, server, compiler, standaloneConfig }) => app.get('/config/main.yml', (_req, res) => res.send('heyo'))
({ app, server, compiler, standaloneConfig }) => {
const staticConfig = express.static('pathToLocalCloudServicesConfig');
app.use('/config', staticConfig);
}
]
Custom routes
If you want to serve files or api from different URL you can either pass routes
to config or routesPath
for file which exports these routes.
routes
rootFolder: resolve(__dirname, '../'),
debug: true,
useFileHash: false,
useProxy: true,
routes: {
'/config/main.yml': { host: 'http://127.0.0.1:8889' }
},
routesPath
rootFolder: resolve(__dirname, '../'),
debug: true,
useFileHash: false,
useProxy: true,
routesPath: process.env.CONFIG_PATH
CONFIG_PATH=/home/khala/Documents/git/RedHatInsights/spandx.config.js
module.exports = {
routes: {
'/api': { host: 'PORTAL_BACKEND_MARKER' },
'/config': { host: 'http://127.0.0.1:8889' },
}
};
Custom proxy settings
You can add an array of additional custom proxy configuration..
Example:
const { config: webpackConfig, plugins } = config({
...
customProxy: [
{
context: ['/api'],
target: 'https://qa.cloud.redhat.com',
secure: false,
changeOrigin: true
},
],
});
This configuration will redirect all API requests to QA environment, so you can check CI UI with QA data.
Running multiple local (frontend) applications
With the proxy enabled it is possible to run multiple frontend applications together using one proxy and webpack dev servers for each other application via passing a LOCAL_APPS
variable.
$ LOCAL_APPS=APP_NAME:APP_PORT[~APP_PROTOCOL] npm run start:proxy
Steps to run multiple applications
- Choose a "main application", which will run the proxy and proxy all other applications, for example Inventory and open a terminal in it's directory
- Open another terminal in any other application that you want to run with the Inventory, for example Advisor and start it's webpack dev server with
npm run start
- Ensure the dev server is started and make not of it's addresses and port it is listening to. (This example assumes it runs on port
8002
)
3.1) You can repeat this process for any application you want to run the Inventory with. - With this information now, in the terminal for Inventory you can start the proxy and pass applications via the
LOCAL_APPS
variable, like LOCAL_APPS=advisor:2002 npm run start:proxy
4.1) You can pass multiple applications as a comma separated list, like LOCAL_APPS=advisor:8002,compliance:8003 npm run start:proxy
- With this you should be able to see any changes in both Inventroy and Advisor via the usual
https://stage.foo.redhat.com:1337
.
Env
A hyphenated string in the form of (stage|prod)-stable. Used to determine the proxy target (such as ci.console.redhat.com or console.stage.redhat.com) and branch to checkout of build repos. If "stage" is specific qa is used as the branch.
Use cloud
If you want to run in legacy mode pass useCloud: true
in your config, this way paths which does not match your proxy config (API for instance) will be passed to cloud.redhat.com
(respective to your env ci|qa|stage
). Without this all fallback routes will be redirected to console.redhat.com
.
Target
Override for the target env
and useCloud
build. Useful for cross-environment testing.
useAgent
boolean
= true
Enforces using the agent to proxy requests via proxyUrl
. Setting this to true
will enforce using agent for PROD environemnt too (use when you are using Red Hat VPN and you do not want to bounce PROD requests). STAGE is using the agent automatically and it cannot be turned off.
bounceProd
boolean
= false
Bounce all non-GET PROD requests via server. This option removes all headers except cookie
and body
so Akamai won't have issues with different origins/hosts. This behavior allows to access PROD environment without using Red Hat VPN.
Running PROD proxy without VPN
Set following attributes in your dev webpack proxy:
const config = {
...options,
env: 'prod-stable'
useAgent: false,
bounceProd: true
}
Now, you can access PROD env without being connected to Red Hat VPN.
standalone
A way to run cloud.redhat.com apps from localhost
offline.
Usage
Simple
Just pass true
to use the 4 default services:
- Insights-chrome cloned locally
- Keycloak on localhost:4001 for user auth
- Users admin/admin and user/user
- Entitlements-config cloned locally
- Landing page cloned locally
- Cloud services config cloned locally
const { config: webpackConfig, plugins } = config({
...
reposDir: 'repos',
standalone: true
});
Advanced
You can use provided services, write your own, or customize the default services.
Using provided services
Check config-utils/standalone/services to see what's supported.
const {
rbac,
backofficeProxy,
defaultServices,
} = require('@redhat-cloud-services/frontend-components-config-utilities/standalone');
const { config: webpackConfig, plugins } = config({
standalone: {
rbac,
backofficeProxy,
...defaultServices,
},
});
Writing services
Services have the following schema:
{
assets: {
[key]: 'https://github.com/redhatinsights/entitlements-config#qa'
},
services: {
keycloak: {
args: string[],
startMessage: string,
dependsOn: string[],
},
},
register({ app, server, compiler, config }) {},
context: ['/auth'],
target: 'http://localhost:4001'
}
In case you need access to some other config it can also be a function:
({ env, port }) => { ... }
and your services can access assets
as well:
services: ({ env, port, assets }) => { ... }
For example, to serve main.yml
from the prod-stable
branch in Github:
const express = require('express');
config(
standalone: {
servicesConfig: {
path: 'https://github.com/redhatinsights/cloud-services-config#prod-stable',
register({ app, config }) {
const staticConfig = express.static(config.servicesConfig.path);
app.use('/config', staticConfig);
}
}
}
)
Customizing default services
The chrome, config, entitlements, and landing services are exposed for you to mutate:
const { defaultServices } = require('@redhat-cloud-services/frontend-components-config-utilities/standalone');
defaultServices.chrome.path = '/path/to/my/insights-chrome';
const { config: webpackConfig, plugins } = config({
standalone: defaultServices
});
fec node scripts
Executable nodejs scripts available after installing RedHat Cloud Services frontend components - webpack config
Usage
Use binary in your package.json
scripts section:
{
"scripts": {
"script-name": "fec <script-name> [options]"
}
}
Patch etc hosts
This is a required step for first time setup. It will allow your localhost to map to [env].foo.redhat.com. This is required to run only once on your machine. Your OS may require running the script as sudo!
Static
A script that will run webpack build and serve webpack output through http-serve
server. This is not supposed to replace webpack dev server!
This script was added due to circular dependency issues when proxying remote containers to another application.
A remote containers can fail to initialize, which makes local development is impossible.
Inventory example
This example will describe a scenario, when we proxy the inventory remote container (for example the inventory table), to compliance UI for local development purposes.
In inventory UI repository changes
@@ -69,7 +69,7 @@
"@babel/preset-env": "^7.15.6",
"@babel/preset-react": "^7.14.5",
"@babel/runtime": "^7.15.4",
- "@redhat-cloud-services/frontend-components-config": "^4.3.9",
+ "@redhat-cloud-services/frontend-components-config": "^4.4.0",
"@testing-library/react": "^12.1.0",
"@wojtekmaj/enzyme-adapter-react-17": "^0.6.3",
"abortcontroller-polyfill": "^1.7.3",
@@ -103,6 +103,7 @@
"prod": "NODE_ENV=production webpack serve --config config/dev.webpack.config.js",
"server:ctr": "node src/server/generateServerKey.js",
"start": "NODE_ENV=development webpack serve --config config/dev.webpack.config.js",
+ "start:federated": "fec static",
"start:proxy": "PROXY=true NODE_ENV=development webpack serve --config config/dev.webpack.config.js",
"travis:build": "NODE_ENV=production webpack --config config/prod.webpack.config.js",
"travis:verify": "npm-run-all travis:build lint test",
@@ -10,7 +10,7 @@ const NoSystemsTable = () => (
<Bullseye>
<EmptyState variant={ EmptyStateVariant.full }>
<Title headingLevel="h5" size="lg">
- No matching systems found
+ Local change
</Title>
<EmptyStateBody>
This filter criteria matches no systems. <br /> Try changing your filter settings.
Compliance frontend setup
Note: The routesPath
was removed because it has higher priority than routes
config. The proxy config could have also changed in ../config/spandx.config.js
file.
@@ -32,10 +32,15 @@ const webpackProxy = {
proxyVerbose: true,
useCloud: (process.env?.USE_CLOUD
...useLocalChrome(),
- routesPath: process.env.ROUTES_PATH || resolve(__dirname, '../config/spandx.config.js'),
routes: {
// Additional routes to the spandx config
+ '/apps/inventory': {
+ host: "http://localhost:8003"
+ },
},
};
Run servers
npm run start:federated
npm run start:proxy
include PF css modules in your bundle
From version >= 4.5.0 the common config has been setup in a way, that PF styles will no longer be included in webpack build output.
This decision has been made to remove multiple versions of PF styling from the platform and performance improvement. Patternfly styles are now hoste by chrome.
If for some reason(bugs) you want to include PF CSS in your bundle, please use the following config:
const config = require('@redhat-cloud-services/frontend-components-config');
const { config: webpackConfig, plugins } = config({
rootFolder: resolve(__dirname, '../'),
bundlePfModules: true,
...
});