Multi-Tenant Anwendungen sind heutzutage ein weit verbreiteter Trend. Firmen entwickeln ein Produkt, welches von zahlreichen Kunden mit unterschiedlichsten Anforderungen genutzt werden kann. Die Entwicklung einer solchen flexiblen Software birgt viele neue Herausforderungen. Um komplexe Konfigurierbarkeit und Design-Customizing zu erreichen, bedarf es einer gründlichen Planung der Architektur. Es kann beispielsweise ein einziger Client so abstrakt gebaut werden, dass er alle speziellen Anforderungen sämtlicher Kunden abdecken kann. In diesem Beitrag wird demonstriert, wie Storybook bei der Entwicklung eines Multi-Tenant-fähigen Frontends helfen kann.
Wie UX/UI-Designer etablierte Tools zum Erstellen von Komponenten Bibliotheken nutzen, kann Storybook analog dazu, in der Frontendentwicklung verwenden werden. Ein online gehostetes Storybook unterstützt dabei auch den kollaborativen Workflow zwischen Entwicklern, Designern und Product Ownern. Technologien wie styled-components helfen dabei, diese Komponenten dynamisch von außen zu stylen und bringen weitere nützliche Features um unsere Anforderungen abzudecken.
In folgendem einfachen Beispiel wird gezeigt, wie mandantenfähige Komponenten mit React und styled-components zu erstellen und diese in Storybook zu verwenden sind.
Hier erstellen wir einen einfachen Button, wrappen ihn in eine Styled-Component und nutzen die Theme-Variable color und die Schriftfarbe zu setzen.
1// Button.tsx
2
3import React from 'react'
4import styled from "styled-components";
5
6const StyledButton = styled.button`
7 color: ${props => props.theme.color};
8`
9
10export const Button: React.FC = ({ children }) =>
11 <StyledButton>{children}</StyledButton>
Komponenten, die Zugriff auf das Theme benötigen, umschließt man mit einem <ThemeProvider />.
1// App.tsx
2
3import React from 'react'
4import { ThemeProvider } from 'styled-components'
5import { Button } from './components/Button'
6
7const theme = {
8 color: 'black',
9}
10
11export const App = () => (
12 <ThemeProvider theme={theme}>
13 <Button>Test</Button>
14 </ThemeProvider>
15)
Als Nächstes kümmern wir uns um das Setup von Storybook. Mit folgendem Befehl lässt sich Storybook jedem Javascript Projekt hinzufügen. Dabei wird automatisch erkannt, ob es sich beispielsweise um ein Typescript-Projekt handelt.
1npx sb-init
Nach der Installation kann Storybook wie folgt gestartet werden.
1npm run storybook
2oder
3yarn storybook
Im Ordner .storybook wurden zwei neue Dateien main.js und preview.js angelegt, welche die Konfiguration und Einstellungen für Stories beinhalten. Das Exportieren eines globalTypes Objekts in der preview.js, kann dafür genutzt werden, eigene Variablen innerhalb Storybook global zu verwalten. In diesem Code-Beispiel definieren wir die Variable tenant und fügen ein Dropdown mit zwei Auswahlmöglichkeiten in die Toolbar ein.
1// .storybook/preview.js
2
3export const globalTypes = {
4 tenant: {
5 defaultValue: 'tenant_A',
6 toolbar: {
7 icon: 'globe',
8 items: [
9 { value: 'tenant_A', title: 'Tenant A' },
10 { value: 'tenant_B', title: 'Tenant B' },
11 ],
12 },
13 },
14}
Ansicht in Storybook:
Mit der Hilfe von decorators können wir alle unsere Stories mit einem ThemeProvider ausliefern. Zudem können wir abhängig vom tenant Wert aus, den globals zwischen den Themes wechseln.
1// .storybook/preview.js
2
3const withThemeProvider = (Story, { globals: { tenant } }) => (
4 <ThemeProvider theme={tenant === 'tenant_A' ? tenantATheme : tenantBTheme}>
5 <Story />
6 </ThemeProvider>
7)
8
9export const decorators = [withThemeProvider]
Diese Methode lässt sich auch einfach auf andere Konfigurationen anwenden, wie Internationalisierung oder Lokalisierung.
Das Entwickeln von Multi-Tenant-fähigen Komponenten und Features in einem richtig konfigurierten Storybook bietet einen immensen Komfort. Anstatt den lokalen Client immer wieder mit unterschiedlichen Tenant Konfigurationen zu starten, kann man in Storybook einfach zwischen Tenants wechseln. Ebenso hilft dies bei der Kommunikation mit Product Ownern und Designern, um schnell spezielle Anpassungen vorzunehmen und zu demonstrieren. Die Dokumentation der Komponenten in allen möglichen Variationen ist dabei ein angenehmer Nebeneffekt.
Unter https://github.com/byteleaf/multi-tenant-storybook-react befindet sich ein lauffähiges Beispielprojekt.