Skip to content

Latest commit

 

History

History

webapp

ML Lab Web App

This folder container the ML Lab web app which is build with JavaScript and React. It communicates with the ML Lab backend (via the contaxy API) and provides the overall UI structure of ML Lab. The ML Lab components are integrated into this UI via iframes.

Develop

During development, it can be very helpful to run the web app locally without building the production bundle and putting it into the ML Lab backend docker image. To do this, execute yarn run start-debug and open http://localhost:3000 in your browser. Note that this debug server will automatically reload if the web application is changed. To test the integration with the ML Lab backend, this debug web app can be connected to any running ML Lab instance. By default, the ML Lab backend is expected to run at http://localhost:30010/ which is the default when starting ML Lab with docker compose. In case you want to connect to a different ML Lab instance, adjust the package.json file accordingly.

This project uses React as the main framework. Components should be written as React Hooks instead of the old class-style wherever possible. See Section Components Guide for some more guidelines. For component styling this project uses the styled-components library (see Section Component Styling). As the default design we use Material and, hence, the Material-UI Library.

For code styling, eslint is used for linting and prettier is used for formatting (see this page for learning about linting vs. formatting). The linting rules are listed in .eslintrc.json. The configuration for prettier can be found in .prettierrc. The configurations adhere to Airbnb's JavaScript style guide. For CSS styling, stylelint is used for which the configuration can be found in the .stylelintrc.json file.

Docs should be written in JSDoc format, though overall we advocate self-explanatory code over comments.

It was bootstrapped with Create React App (yarn create react-app react-webapp) and, thus, uses the pre-configured webpack and babel build tools.

The used package manager for installing packages is yarn.

Code Style

When contributing code, please try to make the code following the project's codestyle setup as described in the Development summary section. We recommend to use plugins in your IDE to already keep an eye on the style while developing. After executing yarn install as they are defined in the ./package.json, you can run style checking like following:

  • Formatting:
    • yarn run prettier <path-to-file>: this command formats the file and saves it.
  • Linting (shows the problems but does not fix them):
    • python build.py --check runs all checks as defined in the build.py or manually:
    • yarn run lint:js: checks the JavaScript files (files ending with .js/.jsx).
    • yarn run lint:css: checks the .css files.

Sometimes, you have to do something that is not allowed by the linting rules. For example, property spreading in React makes sense sometimes. In this example, you can disable the linter for the specific line by adding // eslint-disable-line react/jsx-props-no-spreading. Instead of disabling a rule globally, this forces you to think about your decision instead of allowing slopiness by default.

Production Build

Execute python build.py --make to build the app. Under the hood, it uses yarn build for production to the build folder.
It correctly bundles React in production mode and optimizes the build for the best performance.

The build is minified and the filenames include the hashes.
Your app is ready to be deployed!

See the section about deployment for more information.

Development Walkthrough

Add some information here about the structure of the app, what the entrypoint is, and what tools are used.

Project Structure

The project uses follwing structure:

  • src/: Contains the source code of the web app, for example the React components. Development usually happens in here. The /src/index.jsx is the entry point into the application.
  • public/: Contains the default public resources that must be available such as the index.html. It also contains the locales/ directory for translation files other than English; see the Internationalization Section for more information.
  • build/: The generated directory that contains the bundled web app. This folder is ignored by git and should not be pushed
  • node_modules/: The installed packages. This folder is ignored by git and should not be pushed.

Inside of the src/ folder, there should be following structure (inspired by this blog post):

  • components/: Capsulated components appear here. Artifacts that are specific to a component should be packaged together, for example components/dashboard/ should have all components and styles and images that are just relevant for the dashboard component (domain-based structure).
  • pages/: Reflects the routes of the application and is composed of different components. Each component in this folder should have its own route. If a page has specific components that are only used within that page (especially those which are composed of more general components), you can add them in a sub-directory here instead of the components/ directory.
  • utils/: Functionality that is generally relevant for your application and could be used in multiple places.
  • app/: Contains app essentials such as routes and the store in form of store.js when using Redux.
  • services/: Contains JavaScript functions and clients that manage API integrations.
  • assets/: Should contain style and images and other resources that are generally relevant for your application and not only for a specific component.
  • stories/: Contains general Storybook files such as introduction and assets that are not directly linked to a specific component. It should not contain the actual component stories.

If files belong together, for example a component has a related .stories.jsx and .test.jsx file, put them into an extra folder. Also, when needed add an index.js file to a component directory to make it easier to import as shown here.

Add Storybook files (see the Storybook Section) next to the components they describe. Story files must follow the <component-name>.stories.jsx name pattern. For example, if you have a component src/dashboard/Dashboard.jsx, put the stories file under src/dashboard/Dashboard.stories.jsx.

Add test files next to the code they are testing (see the Testing Section). Test files must follow the <component-name>.test.jsx name pattern.

Component Styling

You can find an example of how styled-components can be used here. With the stated motivation of the library, the style of a component should be bundled with the component and, usually, lies in the same file.

Components Guide

Arrow Functions

Inside of functional components, we prefer arrow functions const foo = () => {} over function declarations function foo(){}.

Memoized Functions

In class components, arrow functions should be defined outside of the render function to avoid any performance problems. For functional components, define non-component specific functions outside of the component function or use useMemo/useCallback functions to avoid re-creation of functions (see this example and the React documentation).

Memoized Components

When your component uses components that render often and always with the same props, consider using a memoized version of those components via React.memo to avoid unnecessary re-renders (check out this blogpost).

Internationalization

We use the react-i18next (GitHub) library for translations. The translation file for languages other than English is loaded dynamically upon need via the i18next-http-backend library. The translation files are placed under ./public/locales. Add a new folder there for extending the languages or edit the languages there to add new translations. The English translation file is pre-bundled with the app which is why it is placed under the src/ directory. You can find an example of how to use the i18next in ./src/pages/App/App.jsx.

Storybook

When we want to document our components further than using JSDoc, we use Storybook. In the Stories directory you can find some example stories (this project was initialized via npx sb init).
The Storybook server can be started via yarn run storybook.

Testing

This project uses Jest and react-testing-library for testing as it comes pre-bundled with Create React App. The official Jest documentation recommends to add at least smoke tests to make sure that components render (source), so we go along with this recommendation ;) Use test() instead of it's alias it() (source). See the App.test.jsx file for an example.

To run the tests, execute yarn test. To see test coverage, execute yarn test -- --coverage (source).