Problems the redesign should solve
- It is difficult to understand the build process.
- We need to do
npm2rpm
for each npm dependency we use in core. - Plugins can’t build themselves, they need Foreman to get build.
- We need to rebuild plugins after each core build.
- The build process copies the
react_app
folder from core to each plugin bundle. - The build process creates an importing alias for plugins from
foremanReact
to the corereact_app
folder. While it works when running foreman itself, it doesn’t work in the plugins dev environment (test, lint, storybook).
Plugins find themselvs mocking each piece of code they are using from core, see: katello mocks - To set up a plugin environment there are some deps and configurations need to be set up (jest, babel, eslint, storybook). Those configs get copied from plugin to plugin with small changes so we end up with different env config for each plugin so it cannot be maintained.
Packages Architecture
The foreman has multiple packages, each package can build individually.
-
@theforeman/env
Provides the basic environment core and plugins needs.-
Dependencies
- babel
- eslint
- Jest
- Storybook
-
Source Exports
- babel configuration to extend
- eslint configuration to extend
- Jest configuration to extend
-
Bin Exports
- tfm-lint
- tfm-test
- tfm-storybook
-
Publish to
- npm
-
-
@theforeman/vendor
Foreman 3rd party supported libraries collection to use in core and plugins.
Already have a working solution: https://github.com/sharvit/foreman-js
In the end, it got split into 3 packagesvendor-core
,vendor-dev
andvendor
.
See the vendor discution here: RFC: Changing how we handle Webpack Building-
dependencies
- […node_modules]
-
devDependencies:
- webpack
- @theforeman/env
-
Scripts
- npm run build
-
Build
- Use webpack to build dist files. (manifest.json, bundle.jd, bundle.css)
-
Exports
- dist/vendor.bundle.js
- dist/vendor.bundle.css
- scss/mixins.scss
- scss/variables.scss
- scss/mixins.scss
- scss/vendor.scss
- webpack-plugin.js
-
Deploy
- npm with
./dist
(and source) - rpm with
./dist
(and source)
- npm with
-
-
@theforeman/builder
Build production and dev dist files for core and plugins.
Each plugin can use it to create it’s own build.-
dependencies
- Webpack
-
devDependencies:
- @theforeman/env
-
Configuration:
- Has webpack configurations and webpack-plugins inside
- Read the minimal configuration file:
tfm-builder.config.js
from consumer root.
This file will export a json with the following fields- entry (extctly like webpack.entry)
- output (extctly like webpack.output)
-
bin
- tfm-build
- tfm-dev-server
- tfm-builder-analyze
-
Publish
- npm
- rpm?
-
-
@theforeman/react-application
Will contain the core react_app folder so it can be shared with core and plugins.
Can live in the core repo.-
dependencies
- @theforeman/vendor
-
devDependencies:
- @theforeman/builder
- @theforeman/env
-
Scripts
- npm run build
- npm run storybook
- npm test
- npm run lint
-
Publish
- Deploy to npm-registry with
./dist
- Deploy to rpm with
./dist
- Deploy to npm-registry with
-
Build
- Use @theforeman/builder to produce
react-application.bundle.js
-
tfm-builder.config.js
- entry: react-application.js
-
output:
./dist/react-application.bundle.js
-
- Use @theforeman/builder to produce
-
-
Plugins
-
dependencies
- @theforeman/vendor
- @theforeman/react-application
-
devDependencies:
- @theforeman/builder
- @theforeman/env
-
Scripts
- npm run build
- npm run storybook
- npm test
- npm run lint
-
Build
- Use @theforeman/builder to produce
[plugin].bundle.js
-
tfm-builder.config.js
-
entry:
webpack/index.js
-
output:
./public/webpack/[plugin].bundle.js
-
entry:
- Use @theforeman/builder to produce
-
Publish
- Publish the gem together with
public/webpack/
- Publish the gem together with
-
-
Foreman
-
dependencies
- @theforeman/vendor
- @theforeman/react-application
-
devDependencies:
- @theforeman/builder
- @theforeman/env
-
Scripts
- npm start
- npm run build
- npm run storybook
- npm test
- npm run lint
-
Build
- Use @theforeman/builder to produce
application.bundle.js
-
tfm-builder.config.js
- entry: webpack/assets/application.js
-
output:
./public/webpack/application.bundle.js
- devServer: { port, bind }
- Use @theforeman/builder to produce
-
Publish
- Publish the gem together with
public/webpack/
- Publish the gem together with
-
Run dev
- Use @theforeman/builder to run
tfm-dev-server
- Use @theforeman/builder to run
-
Managin the sub-packages
I belive we should use lerna to create a monorepo with all the sub-packages.
I already created such a repo under my githhub account: https://github.com/sharvit/foreman-js
This repo contains some sub-packages (vendor, vendor-core, vendor-dev).
Installing plugins in development
Current behavior:
- For-each plugin
- cd <plugin-path> && npm install
- Webpack configuration that can resolve plugins
Wanted behavior:
- For-each plugin
- cd <plugin-path> && npm link
- cd <root> && npm link <plugin-name>
The result will be a symlink in node_modules to the actual plugin path
./node_modules/katello
->../katello
Assets to serve
- public/webpack/manifest.json
- vendor.bundle.(js,css)
- react-application.bundle.(js,css)
- application.bundle.(js,css)
- For each-plugin
- <plugin.path>/public/webpack/manifest.json
<plugin.name>.(js,css)
- <plugin.path>/public/webpack/manifest.json
Serving assets in development
@theforeman/builder supply a script tfm-dev-server
that can run webpack-dev-server
.
The tfm-dev-server
will know how to build and serve the core with plugins based on their configurations.
Other packages we can/want to put in the monorepo
Cheers!