如何在具有多个租户的React应用程序中最佳地构造样式/组件自定义

时间:2018-09-27 10:45:59

标签: reactjs webpack sass multi-tenant

我正在构建一个供多个组织使用的应用程序。每个组织都在自己的子域E.G.中访问应用程序。 google.myapp.commicrosoft.myapp.com。它们都使用完全相同的捆绑软件,但是,每个子域上都没有运行单独的版本。

某些应用程序样式是根据组织的品牌定制的。当前,根据URL中的子域设置了全局类名称,这将样式应用于需要更改颜色等的某些元素。

我的设置是一个React应用程序,它运行在create-react-app Webpack配置的修改版本上。

我想要实现的是一种设置,其中每个组织都有一个“主题”,主要由不同的SCSS变量组成。这些变量将更改应用程序中的核心颜色。

我还需要根据正在查看应用程序的组织来显示某些元素(导航栏元素等)。 我只希望构建版本在捆绑包中具有每个组织的相关CSS。

我知道这是一个非常广泛的问题,但是我真的不知道构造此问题的最佳方法。任何建议,不胜感激!

1 个答案:

答案 0 :(得分:0)

我最终将应用程序迁移到styled-components并实现了theme

我将每个租户的主要变量存储在主题对象中:

export const themes = {
  tenantOne: {
    primaryOne: COLOURS.wallop,
    primaryTwo: COLOURS.wallop,
    logoBackground: COLOURS.wallop,
    secondaryOne: COLOURS.lostForest,
    secondaryTwo: COLOURS.darkPurp,
    [...]
  },
  tenantTwo: {
    primaryOne: COLOURS.red,
    primaryTwo: COLOURS.orange,
    logoBackground: COLOURS.darkerGrey,
    secondaryOne: COLOURS.darkerGrey,
    secondaryTwo: COLOURS.darkerGrey,
    [...]
  },
};

然后,我将应用程序包装在<ThemeProvider>提供的styled-components组件中。我将一个函数传递给theme道具,该道具确定哪个租户正在使用该应用程序(具有从后端获取的ID),然后返回要使用的主题对象。

<ThemeProvider theme={ platformBrandingHelper.getPlatformTheme(appId) }>
    <App />
</ThemeProvider>

辅助功能:

function getPlatformTheme(appId) {
  switch (appId) {
    case 'tenantOne':
      return THEMES.tenantOne;
    case 'tenantTwo':
      return THEMES.tenantTwo;
    default:
      return THEMES.default;
  }
}

从那以后,只不过是使用主题中的变量(而不是硬编码颜色)来对应用程序进行样式设置的一种情况。这就是为什么我迁移到styled-components

示例:

const Button = ({
  className,
  type,
  onClick,
  disabled,
  active,
  children,
}) => (
  <button
    disabled={ disabled }
    className={ `${ className } ${ active ? 'active' : '' }` }
    type={ type }
    onClick={ (e) => onClick(e) }
  >
    <span className="content">
      { children }
    </span>
  </button>
);

const StyledButton = styled(Button)`
  border-color: ${ (props) => props.theme.primaryOne };;
  background: ${ (props) => props.theme.primaryOne };;
  color: ${ (props) => props.theme.baseSix };
`;

现在,应用程序将为每个租户加载正确的主题对象,然后将使用适当的颜色等为每个组件设置样式,因为它们都依赖于从主题传递给他们的变量。